Merge lp:~mzanetti/unity8/unified-stages into lp:unity8
- unified-stages
- Merge into trunk
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Lukáš Tinkl | ||||||||||||
Approved revision: | 2603 | ||||||||||||
Merged at revision: | 2662 | ||||||||||||
Proposed branch: | lp:~mzanetti/unity8/unified-stages | ||||||||||||
Merge into: | lp:unity8 | ||||||||||||
Diff against target: |
12285 lines (+3477/-6154) 62 files modified
debian/unity8.install (+1/-1) plugins/Ubuntu/Gestures/TouchGate.cpp (+4/-1) plugins/WindowManager/TopLevelSurfaceList.cpp (+0/-5) qml/CMakeLists.txt (+1/-1) qml/Components/EdgeBarrier.qml (+2/-0) qml/Components/FloatingFlickable.qml (+3/-0) qml/Components/InputMethod.qml (+1/-1) qml/Greeter/LoginAreaContainer.qml (+1/-1) qml/Notifications/Notification.qml (+1/-1) qml/Rotation/RotationStates.qml (+0/-6) qml/Shell.qml (+54/-167) qml/Stage/ApplicationWindow.qml (+13/-37) qml/Stage/DecoratedWindow.qml (+111/-31) qml/Stage/MoveHandler.qml (+2/-2) qml/Stage/PromptSurfaceAnimations.qml (+2/-3) qml/Stage/Spread/BezierCurve.qml (+45/-0) qml/Stage/Spread/KeySpline.js (+66/-0) qml/Stage/Spread/MathUtils.js (+95/-0) qml/Stage/Spread/OpacityMask.qml (+82/-0) qml/Stage/Spread/Spread.qml (+162/-0) qml/Stage/Spread/SpreadDelegateInputArea.qml (+183/-0) qml/Stage/Spread/SpreadMaths.qml (+78/-0) qml/Stage/Spread/StagedRightEdgeMaths.qml (+174/-0) qml/Stage/Spread/WindowedRightEdgeMaths.qml (+81/-0) qml/Stage/Spread/cubic-bezier.js (+39/-0) qml/Stage/Stage.qml (+1241/-185) qml/Stage/StageMaths.qml (+79/-0) qml/Stage/SurfaceContainer.qml (+5/-52) qml/Stage/TopLevelSurfaceRepeater.qml (+9/-0) qml/Stage/WindowDecoration.qml (+1/-1) qml/Stage/WindowInfoItem.qml (+53/-0) qml/Stage/WindowResizeArea.qml (+33/-32) qml/Stages/AbstractStage.qml (+0/-93) qml/Stages/DesktopSpread.qml (+0/-576) qml/Stages/DesktopSpreadDelegate.qml (+0/-126) qml/Stages/PhoneStage.qml (+0/-806) qml/Stages/SpreadDelegate.qml (+0/-424) qml/Stages/SpreadMaths.qml (+0/-164) qml/Stages/TabletStage.qml (+0/-1201) qml/Stages/TransformedSpreadDelegate.qml (+0/-391) qml/Stages/TransformedTabletSpreadDelegate.qml (+0/-437) qml/Tutorial/TutorialRight.qml (+1/-1) tests/mocks/Unity/Application/ApplicationInfo.cpp (+2/-2) tests/mocks/Unity/Application/ApplicationManager.cpp (+2/-0) tests/mocks/Unity/Application/MirSurface.cpp (+1/-0) tests/mocks/Unity/Application/MirSurfaceItem.cpp (+13/-0) tests/mocks/Unity/Application/MirSurfaceListModel.cpp (+0/-1) tests/mocks/Unity/Application/VirtualKeyboard.cpp (+9/-7) tests/mocks/Unity/Application/resources/MirSurfaceItem.qml (+2/-5) tests/qmltests/CMakeLists.txt (+8/-8) tests/qmltests/Stage/tst_ApplicationWindow.qml (+1/-1) tests/qmltests/Stage/tst_DecoratedWindow.qml (+232/-0) tests/qmltests/Stage/tst_DesktopStage.qml (+29/-71) tests/qmltests/Stage/tst_PhoneStage.qml (+157/-219) tests/qmltests/Stage/tst_Splash.qml (+1/-1) tests/qmltests/Stage/tst_SurfaceContainer.qml (+2/-2) tests/qmltests/Stage/tst_TabletStage.qml (+109/-243) tests/qmltests/Stage/tst_WindowResizeArea.qml (+40/-36) tests/qmltests/Stages/tst_SpreadDelegate.qml (+0/-423) tests/qmltests/tst_OrientedShell.qml (+38/-198) tests/qmltests/tst_Shell.qml (+199/-180) tests/qmltests/tst_ShellWithPin.qml (+9/-11) |
||||||||||||
To merge this branch: | bzr merge lp:~mzanetti/unity8/unified-stages | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Lukáš Tinkl (community) | Approve | ||
Unity8 CI Bot | continuous-integration | Needs Fixing | |
Daniel d'Andrada (community) | Needs Information | ||
Review via email: mp+307720@code.launchpad.net |
This proposal supersedes a proposal from 2016-09-13.
Commit message
Merge all Stages into one single codebase. Apply new spread visuals.
This deletes PhoneStage, TabletStage and DesktopStage, and merges all of the functionality into Stage. Also the spread visuals have been updated by design to work with all usage modes.
Description of the change
Also, you want this in order to fix a bug if an application is rotated while suspended (this can happen now as we can rotate while in the spread with the new visuals)
https:/
* tested on turbo, frieza and desktop
* tested/verfied by design. There will be some follow up work, especially when it comes to the tablet usage mode but design is ok with landing this as intermediate step.
* no packaging change
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2510
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2511
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2512
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2514
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2517
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2518
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2519
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2520
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2521
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2522
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2523
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2524
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2525
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2526
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2527
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2529
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2530
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2531
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2532
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2532
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2533
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2534
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2535
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2536
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2538
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2540
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2541
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2541
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2542
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2542
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2543
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2544
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2544
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2546
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2547
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2549
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2549
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2553
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2554
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2556
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2557
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2557
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2557
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2558
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2559
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2560
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2561
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2561
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2562
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
There's a debug leftover in qml/Launcher/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
Likewise in qml/Notificatio
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
"""
// TODO: Is this still needed? Didn't come across it. Needs checking before merging
beingResized: shell.beingResized
"""
If you solved the <FIXME-contentX> that PhoneStage and TabletStage had, there should be no use for this anymore.
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
In qml/Stage/
"""
// The DecoratedWindow takes requestedWidth/
"""
Typo: s/it's/its
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
As far as I remember, ApplicationWind
But that property sure is (or was) tainting the API.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2563
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
In
"""
property bool hasDecoration: true
"""
What about s/hasDecoration
Would sound more like a QML property
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
qml/Stage/Stage.qml
"""
// Congifuration
property string mode: "staged"
"""
Typo in comment.
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
In qml/Stage/Stage.qml
"""
// functions to be called from outside
[...]
function closeFocusedDel
"""
Don't see closeFocusedDel
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
In qml/Stage/
"""
readonly property real virtualKeyboard
"""
Please get it from outside. Let Shell wire it to inputMethod.
"""
""""
Likewise, all these SurfaceManager expressions could be supplied by inputMethod.visible from Shell.qml
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
"""
"""
If there's no surface I think you will want to fallback to application.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2563
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
> In
>
> """
> property bool hasDecoration: true
> """
>
> What about s/hasDecoration
> Would sound more like a QML property
in general, yes, I'd agree. Thing here is that there are 2, hasDecoration and showDecoration. toggling hasDecoration will resize the surface, while showDecoration will temporarily hide the decoration without actually resizing the surface. naming the property just "decorated" will blur the meaning between those too much IMO.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2567
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
> """
> readonly property bool fullscreen: surface && surface.state
> === Mir.FullscreenS
> """
>
> If there's no surface I think you will want to fallback to
> application.
I investigated now a while into this. I've tried:
readonly property bool fullscreen surface ? surface.state === Mir.FullscreenState : model.applicati
but this doesn't seem to reflect the correct thing in my tests... What I could do is something like:
property bool fullscreen: false
Connections { target: surface; onStateChanged: fullscreen = surface.state === Mir.FullscreenState }
This would work as expected, although being a tad ugly. The next thing though is that the panel doesn't use this logic, instead only acts on SurfaceManager.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2570
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
Ok, I addressed all of Daniel's comments. I am falling back to application.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2572
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
Switching between apps, where one supports only one orientation:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
qml/Stage/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2576
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
physical orientation is portrait while showing a landscape-only app. Go to spread and select that same app again, returning to the same state you were before:
https:/
That landscape-only app gets several resizes during that use case, going even to a portrait size in between:
MirSurface[
MirSurface[
MirSurface[
MirSurface[
Is all this really necessary to implement the new design?
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
Again on phone mode:
-Launch a landscape-only app
-rotate phone to portrait
-go to switcher and select a portrait-capable app like dash
The landscape-only app is left in a portrait size.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2577
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
qml/Stage/
If in the new world, all applications are always matching shell orientation, then this code won't be needed anymore and should be deleted (it's already dead code in this branch).
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
In Stage.qml:
+// property int animationDuration: 4000
This can be dropped probably?
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
In tests/mocks/
+// connect(surface, &MirSurface:
Ditto
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
In DecoratedWindow
// FIXME: priv.animationD
Behavior on opacity { UbuntuNumberAni
$ make tryDecoratedWindow
$ file://
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
In the same test (pressing match/animateTo
file://
file://
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
That's a common situation on the phone and currently it doesn't look good:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2580
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2582
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
FAILURE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
Resize got worse. Specially how the surface bleeds beyond window boundaries when enlarging it (2:33).
Resize after unified-stages start at 1:25
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2582
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
> Resize got worse. Specially how the surface bleeds beyond window boundaries
> when enlarging it (2:33).
>
> https:/
>
> Resize after unified-stages start at 1:25
fixed. good catch, it was a stupid little mistake in wiring up things after refactoring
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2583
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2586
https:/
Executed test runs:
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
Slowly push against right edge a bit then slowly move back.
It moves onto spread view smoothly but changes back abruptly and staggers in some intermediate state in-between. Same happens when you click on a window on the spread.
If it can't animate from spread state back to normal state, it should at least do a proper immediate transition without staggering in this intermediate state for a moment.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2588
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
Bunch of debug leftovers in Stage.qml:
"""
onTriggered: {print(
"""
"""
print("have delegate", appDelegate.appId)
"""
"""
print("minimizing it", appDelegate.appId)
"""
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2589
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
> Bunch of debug leftovers in Stage.qml:
>
> """
> onTriggered: {print(
> """
>
> """
> print("have delegate", appDelegate.appId)
> """
>
> """
> print("minimizing it", appDelegate.appId)
> """
fixed
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
> That's a common situation on the phone and currently it doesn't look good:
> https:/
OK. I have improved this according to design's guidance. We're not 100% happy with it yet, but at least it doesn't look broken any more.
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
> Slowly push against right edge a bit then slowly move back.
> It moves onto spread view smoothly but changes back abruptly and staggers in
> some intermediate state in-between. Same happens when you click on a window on
> the spread.
>
> https:/
>
> If it can't animate from spread state back to normal state, it should at least
> do a proper immediate transition without staggering in this intermediate state
> for a moment.
fixed...
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
Okay... I think I fixed all of the comments here, except the difference between trunk and this branch in regard to the orientation of the apps *in* the spread. That, however, is really what design wants and we are aware that there's room for improvement on how it looks/behaves and we will iterate on things. I'd prefer to keep logic around the not implemented rotation related functions for now, and then drop them when we reached the final conclusion on the spread & rotation with design.
So, unless you guys find some serious bugs, or something in the code that really needs fixing/cleaning up, I would vote for bringing this branch to an end now to unblock people working on top of this and iterate afterwards.
Daniel, Lukas, wdyt?
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
> So, unless you guys find some serious bugs, [...] I would vote for bringing this branch to an
> end now [...] and iterate afterwards.
>
> Daniel, Lukas, wdyt?
Ok.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2590
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2593
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
This test is still failing, even locally, needs fixing:
FAIL! : qmltestrunner:
Actual (): facebook-webapp
Expected ():
Loc: [/home/
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
On 28.09.2016 21:31, Lukáš Tinkl wrote:
> Review: Needs Fixing
>
> This test is still failing, even locally, needs fixing:
>
> FAIL! : qmltestrunner:
> Actual (): facebook-webapp
> Expected ():
> Loc: [/home/
>
>
Fixed
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
Waiting for CI for the top approval, but this should be good enough now. Thanks!
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2594
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
Found a small issue while testing this in the silo:
In desktop mode, newly launched apps are correctly focused but never raised (brought to the top), regardless of whether started from launcher, dash or indicators
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2595
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Lukáš Tinkl (lukas-kde) wrote : | # |
Good, focus and camera issues fixed
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2596
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2600
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : | # |
Found a loose end when dragging a corner-maximized window. :(
- 2601. By Michael Zanetti
-
fix ghost rect on corner maximize
- 2602. By Michael Zanetti
-
fix OSK rect not always going away when it should
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2601
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2602
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : | # |
> Found a loose end when dragging a corner-maximized window. :(
>
> https:/
That's fixed now, thanks.
Are those failures caused by this branch?
"""
qmltestrunner.
qmltestrunner.
qmltestrunner.
"""
Michael Zanetti (mzanetti) wrote : | # |
>
> Are those failures caused by this branch?
>
> """
> qmltestrunner.
> qmltestrunner.
> qmltestrunner.
> """
I can't reproduce them locally but have some changes running now which hopefully get away with them...
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2603
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2604
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2605
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2606
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2607
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 2603. By Michael Zanetti
-
fix test flakiness
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2607
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2603
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Lukáš Tinkl (lukas-kde) wrote : | # |
CI green now (modulo an unrelated test failure on yaketty)
- 2604. By Michael Zanetti
-
fix spread close input area
Lukáš Tinkl (lukas-kde) wrote : | # |
Verified and re-tested, still good
Preview Diff
1 | === modified file 'debian/unity8.install' |
2 | --- debian/unity8.install 2016-06-20 22:42:46 +0000 |
3 | +++ debian/unity8.install 2016-10-11 21:49:13 +0000 |
4 | @@ -16,7 +16,7 @@ |
5 | usr/share/unity8/OrientedShell.qml |
6 | usr/share/unity8/DisabledScreenNotice.qml |
7 | usr/share/unity8/Shell.qml |
8 | -usr/share/unity8/Stages |
9 | +usr/share/unity8/Stage |
10 | usr/share/unity8/Tutorial |
11 | usr/share/unity8/Wizard |
12 | usr/share/url-dispatcher/urls/unity8-dash.url-dispatcher |
13 | |
14 | === modified file 'plugins/Ubuntu/Gestures/TouchGate.cpp' |
15 | --- plugins/Ubuntu/Gestures/TouchGate.cpp 2016-07-13 07:29:00 +0000 |
16 | +++ plugins/Ubuntu/Gestures/TouchGate.cpp 2016-10-11 21:49:13 +0000 |
17 | @@ -61,7 +61,10 @@ |
18 | const QTouchEvent::TouchPoint &touchPoint = touchPoints[i]; |
19 | |
20 | if (touchPoint.state() == Qt::TouchPointPressed) { |
21 | - Q_ASSERT(!m_touchInfoMap.contains(touchPoint.id())); |
22 | +// FIXME: This assert triggers frequently in make trySomething. We have verified |
23 | +// that it's a bug in the mouse to touch conversion of the test environment |
24 | +// and not in the actual product. Still, it probably should be cleaned up eventually. |
25 | +// Q_ASSERT(!m_touchInfoMap.contains(touchPoint.id())); |
26 | m_touchInfoMap[touchPoint.id()].ownership = OwnershipRequested; |
27 | m_touchInfoMap[touchPoint.id()].ended = false; |
28 | TouchRegistry::instance()->requestTouchOwnership(touchPoint.id(), this); |
29 | |
30 | === modified file 'plugins/WindowManager/TopLevelSurfaceList.cpp' |
31 | --- plugins/WindowManager/TopLevelSurfaceList.cpp 2016-04-04 13:43:41 +0000 |
32 | +++ plugins/WindowManager/TopLevelSurfaceList.cpp 2016-10-11 21:49:13 +0000 |
33 | @@ -133,11 +133,6 @@ |
34 | |
35 | void TopLevelSurfaceList::connectSurface(MirSurfaceInterface *surface) |
36 | { |
37 | - connect(surface, &MirSurfaceInterface::focusedChanged, this, [this, surface](bool focused){ |
38 | - if (focused) { |
39 | - this->raise(surface); |
40 | - } |
41 | - }); |
42 | connect(surface, &MirSurfaceInterface::liveChanged, this, [this, surface](bool live){ |
43 | if (!live) { |
44 | onSurfaceDied(surface); |
45 | |
46 | === modified file 'qml/CMakeLists.txt' |
47 | --- qml/CMakeLists.txt 2015-03-06 04:44:11 +0000 |
48 | +++ qml/CMakeLists.txt 2016-10-11 21:49:13 +0000 |
49 | @@ -12,7 +12,7 @@ |
50 | Launcher |
51 | Notifications |
52 | Panel |
53 | - Stages |
54 | + Stage |
55 | Rotation |
56 | Tutorial |
57 | Wizard |
58 | |
59 | === modified file 'qml/Components/EdgeBarrier.qml' |
60 | --- qml/Components/EdgeBarrier.qml 2016-02-15 16:43:56 +0000 |
61 | +++ qml/Components/EdgeBarrier.qml 2016-10-11 21:49:13 +0000 |
62 | @@ -29,6 +29,8 @@ |
63 | // Supported values are: Qt.LeftEdge, Qt.RightEdge |
64 | property int edge: Qt.LeftEdge |
65 | |
66 | + readonly property alias progress: controller.progress |
67 | + |
68 | property Item target: parent |
69 | function push(amount) { controller.push(amount); } |
70 | signal passed() |
71 | |
72 | === modified file 'qml/Components/FloatingFlickable.qml' |
73 | --- qml/Components/FloatingFlickable.qml 2016-08-08 10:41:38 +0000 |
74 | +++ qml/Components/FloatingFlickable.qml 2016-10-11 21:49:13 +0000 |
75 | @@ -35,6 +35,9 @@ |
76 | property alias contentX: flickable.contentX |
77 | property alias contentY: flickable.contentY |
78 | property alias direction: swipeArea.direction |
79 | + property alias leftMargin: flickable.leftMargin |
80 | + property alias rightMargin: flickable.rightMargin |
81 | + property alias dragging: flickable.dragging |
82 | |
83 | MouseEventGenerator { |
84 | id: mouseEventGenerator |
85 | |
86 | === modified file 'qml/Components/InputMethod.qml' |
87 | --- qml/Components/InputMethod.qml 2016-06-30 13:51:32 +0000 |
88 | +++ qml/Components/InputMethod.qml 2016-10-11 21:49:13 +0000 |
89 | @@ -21,7 +21,7 @@ |
90 | Item { |
91 | id: root |
92 | |
93 | - readonly property rect visibleRect: surfaceItem.surface ? surfaceItem.surface.inputBounds : Qt.rect(0, 0, 0, 0) |
94 | + readonly property rect visibleRect: surfaceItem.surface && visible ? surfaceItem.surface.inputBounds : Qt.rect(0, 0, 0, 0) |
95 | |
96 | MirSurfaceItem { |
97 | id: surfaceItem |
98 | |
99 | === modified file 'qml/Greeter/LoginAreaContainer.qml' |
100 | --- qml/Greeter/LoginAreaContainer.qml 2016-06-14 17:34:35 +0000 |
101 | +++ qml/Greeter/LoginAreaContainer.qml 2016-10-11 21:49:13 +0000 |
102 | @@ -26,7 +26,7 @@ |
103 | rightMargin: -units.gu(1.5) |
104 | bottomMargin: -units.gu(1.5) |
105 | } |
106 | - source: "../Stages/graphics/dropshadow2gu.sci" |
107 | + source: "../graphics/dropshadow2gu.sci" |
108 | opacity: 0.35 |
109 | } |
110 | |
111 | |
112 | === modified file 'qml/Notifications/Notification.qml' |
113 | --- qml/Notifications/Notification.qml 2016-08-19 13:27:05 +0000 |
114 | +++ qml/Notifications/Notification.qml 2016-10-11 21:49:13 +0000 |
115 | @@ -143,7 +143,7 @@ |
116 | fill: contents |
117 | margins: shapedBack.visible ? -units.gu(1) : -units.gu(1.5) |
118 | } |
119 | - source: "../Stages/graphics/dropshadow2gu.sci" |
120 | + source: "../graphics/dropshadow2gu.sci" |
121 | opacity: notification.opacity * 0.5 |
122 | enabled: !fullscreen |
123 | } |
124 | |
125 | === modified file 'qml/Rotation/RotationStates.qml' |
126 | --- qml/Rotation/RotationStates.qml 2016-04-29 12:52:53 +0000 |
127 | +++ qml/Rotation/RotationStates.qml 2016-10-11 21:49:13 +0000 |
128 | @@ -121,12 +121,6 @@ |
129 | } |
130 | } |
131 | |
132 | - property var shellBeingResized: Binding { |
133 | - target: root.shell |
134 | - property: "beingResized" |
135 | - value: d.transitioning |
136 | - } |
137 | - |
138 | readonly property int fullAnimation: 0 |
139 | readonly property int indicatorsBarAnimation: 1 |
140 | readonly property int noAnimation: 2 |
141 | |
142 | === modified file 'qml/Shell.qml' |
143 | --- qml/Shell.qml 2016-09-22 07:42:01 +0000 |
144 | +++ qml/Shell.qml 2016-10-11 21:49:13 +0000 |
145 | @@ -35,7 +35,7 @@ |
146 | import "Panel" |
147 | import "Components" |
148 | import "Notifications" |
149 | -import "Stages" |
150 | +import "Stage" |
151 | import "Tutorial" |
152 | import "Wizard" |
153 | import Unity.Notifications 1.0 as NotificationBackend |
154 | @@ -58,24 +58,22 @@ |
155 | property real nativeWidth |
156 | property real nativeHeight |
157 | property alias indicatorAreaShowProgress: panel.indicatorAreaShowProgress |
158 | - property bool beingResized |
159 | property string usageScenario: "phone" // supported values: "phone", "tablet" or "desktop" |
160 | property string mode: "full-greeter" |
161 | property alias oskEnabled: inputMethod.enabled |
162 | function updateFocusedAppOrientation() { |
163 | - applicationsDisplayLoader.item.updateFocusedAppOrientation(); |
164 | + stage.updateFocusedAppOrientation(); |
165 | } |
166 | function updateFocusedAppOrientationAnimated() { |
167 | - applicationsDisplayLoader.item.updateFocusedAppOrientationAnimated(); |
168 | + stage.updateFocusedAppOrientationAnimated(); |
169 | } |
170 | property bool hasMouse: false |
171 | |
172 | // to be read from outside |
173 | - readonly property int mainAppWindowOrientationAngle: |
174 | - applicationsDisplayLoader.item ? applicationsDisplayLoader.item.mainAppWindowOrientationAngle : 0 |
175 | + readonly property int mainAppWindowOrientationAngle: stage.mainAppWindowOrientationAngle |
176 | |
177 | readonly property bool orientationChangesEnabled: panel.indicators.fullyClosed |
178 | - && (applicationsDisplayLoader.item && applicationsDisplayLoader.item.orientationChangesEnabled) |
179 | + && stage.orientationChangesEnabled |
180 | && (!greeter || !greeter.animating) |
181 | |
182 | readonly property bool showingGreeter: greeter && greeter.shown |
183 | @@ -89,19 +87,13 @@ |
184 | return Qt.PrimaryOrientation; |
185 | } else if (showingGreeter || notifications.topmostIsFullscreen) { |
186 | return Qt.PrimaryOrientation; |
187 | - } else if (applicationsDisplayLoader.item) { |
188 | - return shell.orientations.map(applicationsDisplayLoader.item.supportedOrientations); |
189 | } else { |
190 | - // we just don't care |
191 | - return Qt.PortraitOrientation |
192 | - | Qt.LandscapeOrientation |
193 | - | Qt.InvertedPortraitOrientation |
194 | - | Qt.InvertedLandscapeOrientation; |
195 | + return shell.orientations.map(stage.supportedOrientations); |
196 | } |
197 | } |
198 | |
199 | - readonly property var mainApp: |
200 | - applicationsDisplayLoader.item ? applicationsDisplayLoader.item.mainApp : null |
201 | + readonly property var mainApp: stage.mainApp |
202 | + |
203 | onMainAppChanged: { |
204 | if (mainApp) { |
205 | _onMainAppChanged(mainApp.appId); |
206 | @@ -278,154 +270,50 @@ |
207 | applicationsModel: ApplicationManager |
208 | } |
209 | |
210 | - Loader { |
211 | - id: applicationsDisplayLoader |
212 | - objectName: "applicationsDisplayLoader" |
213 | + Stage { |
214 | + id: stage |
215 | + objectName: "stage" |
216 | anchors.fill: parent |
217 | - |
218 | - // When we have a locked app, we only want to show that one app. |
219 | - // FIXME: do this in a less traumatic way. We currently only allow |
220 | - // locked apps in phone mode (see FIXME in Lockscreen component in |
221 | - // this same file). When that changes, we need to do something |
222 | - // nicer here. But this code is currently just to prevent a |
223 | - // theoretical attack where user enters lockedApp mode, then makes |
224 | - // the screen larger (maybe connects to monitor) and tries to enter |
225 | - // tablet mode. |
226 | + focus: true |
227 | + |
228 | + dragAreaWidth: shell.edgeSize |
229 | + background: wallpaperResolver.background |
230 | + leftEdgeDragProgress: !greeter || greeter.locked || !tutorial.launcherLongSwipeEnabled ? 0 : |
231 | + Math.max(0, (launcher.dragDistance * (stage.width - launcher.panelWidth) / stage.width) - launcher.panelWidth) |
232 | + |
233 | + applicationManager: ApplicationManager |
234 | + topLevelSurfaceList: topLevelSurfaceList |
235 | + inputMethodRect: inputMethod.visibleRect |
236 | |
237 | property string usageScenario: shell.usageScenario === "phone" || greeter.hasLockedApp |
238 | - ? "phone" |
239 | - : shell.usageScenario |
240 | - readonly property string qmlComponent: { |
241 | - if (applicationsDisplayLoader.usageScenario === "phone") { |
242 | - return "Stages/PhoneStage.qml"; |
243 | - } else if (applicationsDisplayLoader.usageScenario === "tablet") { |
244 | - return "Stages/TabletStage.qml"; |
245 | - } else { |
246 | - return "Stages/DesktopStage.qml"; |
247 | - } |
248 | - } |
249 | - // TODO: Ensure the current stage is destroyed before the new one gets loaded. |
250 | - // Currently the new one will get loaded while the old is still hanging |
251 | - // around for a bit, which might lead to conflicts where both stages |
252 | - // change the model simultaneously. |
253 | - onQmlComponentChanged: { |
254 | - if (item) item.stageAboutToBeUnloaded(); |
255 | - source = qmlComponent; |
256 | - } |
257 | - |
258 | - property bool interactive: (!greeter || !greeter.shown) |
259 | + ? "phone" |
260 | + : shell.usageScenario |
261 | + |
262 | + mode: usageScenario == "phone" ? "staged" |
263 | + : usageScenario == "tablet" ? "stagedWithSideStage" |
264 | + : "windowed" |
265 | + |
266 | + shellOrientation: shell.orientation |
267 | + shellOrientationAngle: shell.orientationAngle |
268 | + orientations: shell.orientations |
269 | + nativeWidth: shell.nativeWidth |
270 | + nativeHeight: shell.nativeHeight |
271 | + |
272 | + interactive: (!greeter || !greeter.shown) |
273 | && panel.indicators.fullyClosed |
274 | && launcher.progress == 0 |
275 | && !notifications.useModal |
276 | |
277 | onInteractiveChanged: { if (interactive) { focus = true; } } |
278 | |
279 | - Binding { |
280 | - target: applicationsDisplayLoader.item |
281 | - property: "focus" |
282 | - value: true |
283 | - } |
284 | - Binding { |
285 | - target: applicationsDisplayLoader.item |
286 | - property: "objectName" |
287 | - value: "stage" |
288 | - } |
289 | - Binding { |
290 | - target: applicationsDisplayLoader.item |
291 | - property: "dragAreaWidth" |
292 | - value: shell.edgeSize |
293 | - } |
294 | - Binding { |
295 | - target: applicationsDisplayLoader.item |
296 | - property: "maximizedAppTopMargin" |
297 | - // Not just using panel.panelHeight as that changes depending on the focused app. |
298 | - value: panel.indicators.minimizedPanelHeight |
299 | - } |
300 | - Binding { |
301 | - target: applicationsDisplayLoader.item |
302 | - property: "interactive" |
303 | - value: applicationsDisplayLoader.interactive |
304 | - } |
305 | - Binding { |
306 | - target: applicationsDisplayLoader.item |
307 | - property: "spreadEnabled" |
308 | - value: tutorial.spreadEnabled && (!greeter || (!greeter.hasLockedApp && !greeter.shown)) |
309 | - } |
310 | - Binding { |
311 | - target: applicationsDisplayLoader.item |
312 | - property: "inverseProgress" |
313 | - value: !greeter || greeter.locked || !tutorial.launcherLongSwipeEnabled ? 0 : launcher.progress |
314 | - } |
315 | - Binding { |
316 | - target: applicationsDisplayLoader.item |
317 | - property: "shellOrientationAngle" |
318 | - value: shell.orientationAngle |
319 | - } |
320 | - Binding { |
321 | - target: applicationsDisplayLoader.item |
322 | - property: "shellOrientation" |
323 | - value: shell.orientation |
324 | - } |
325 | - Binding { |
326 | - target: applicationsDisplayLoader.item |
327 | - property: "orientations" |
328 | - value: shell.orientations |
329 | - } |
330 | - Binding { |
331 | - target: applicationsDisplayLoader.item |
332 | - property: "background" |
333 | - value: wallpaperResolver.cachedBackground |
334 | - } |
335 | - Binding { |
336 | - target: applicationsDisplayLoader.item |
337 | - property: "nativeWidth" |
338 | - value: shell.nativeWidth |
339 | - } |
340 | - Binding { |
341 | - target: applicationsDisplayLoader.item |
342 | - property: "nativeHeight" |
343 | - value: shell.nativeHeight |
344 | - } |
345 | - Binding { |
346 | - target: applicationsDisplayLoader.item |
347 | - property: "beingResized" |
348 | - value: shell.beingResized |
349 | - } |
350 | - Binding { |
351 | - target: applicationsDisplayLoader.item |
352 | - property: "keepDashRunning" |
353 | - value: launcher.shown || launcher.dashSwipe |
354 | - } |
355 | - Binding { |
356 | - target: applicationsDisplayLoader.item |
357 | - property: "suspended" |
358 | - value: greeter.shown |
359 | - } |
360 | - Binding { |
361 | - target: applicationsDisplayLoader.item |
362 | - property: "altTabPressed" |
363 | - value: physicalKeysMapper.altTabPressed |
364 | - } |
365 | - Binding { |
366 | - target: applicationsDisplayLoader.item |
367 | - property: "leftMargin" |
368 | - value: shell.usageScenario == "desktop" && !settings.autohideLauncher ? launcher.panelWidth: 0 |
369 | - } |
370 | - Binding { |
371 | - target: applicationsDisplayLoader.item |
372 | - property: "applicationManager" |
373 | - value: ApplicationManager |
374 | - } |
375 | - Binding { |
376 | - target: applicationsDisplayLoader.item |
377 | - property: "topLevelSurfaceList" |
378 | - value: topLevelSurfaceList |
379 | - } |
380 | - Binding { |
381 | - target: applicationsDisplayLoader.item |
382 | - property: "oskEnabled" |
383 | - value: shell.oskEnabled |
384 | - } |
385 | + leftMargin: shell.usageScenario == "desktop" && !settings.autohideLauncher ? launcher.panelWidth: 0 |
386 | + suspended: greeter.shown |
387 | + keepDashRunning: launcher.shown || launcher.dashSwipe |
388 | + altTabPressed: physicalKeysMapper.altTabPressed |
389 | + oskEnabled: shell.oskEnabled |
390 | + |
391 | + // TODO: This is not implemented yet in the new stage... |
392 | + spreadEnabled: tutorial.spreadEnabled && (!greeter || (!greeter.hasLockedApp && !greeter.shown)) |
393 | } |
394 | } |
395 | |
396 | @@ -442,6 +330,7 @@ |
397 | |
398 | Loader { |
399 | id: greeterLoader |
400 | + objectName: "greeterLoader" |
401 | anchors.fill: parent |
402 | anchors.topMargin: panel.panelHeight |
403 | sourceComponent: shell.mode != "shell" ? integratedGreeter : |
404 | @@ -650,7 +539,7 @@ |
405 | } |
406 | onFocusChanged: { |
407 | if (!focus) { |
408 | - applicationsDisplayLoader.focus = true; |
409 | + stage.focus = true; |
410 | } |
411 | } |
412 | |
413 | @@ -706,12 +595,12 @@ |
414 | delayed: dialogs.hasActiveDialog || notifications.hasNotification || |
415 | inputMethod.visible || |
416 | (launcher.shown && !launcher.lockedVisible) || |
417 | - panel.indicators.shown || stage.dragProgress > 0 |
418 | + panel.indicators.shown || stage.rightEdgeDragProgress > 0 |
419 | usageScenario: shell.usageScenario |
420 | lastInputTimestamp: inputFilter.lastInputTimestamp |
421 | launcher: launcher |
422 | panel: panel |
423 | - stage: applicationsDisplayLoader.item |
424 | + stage: stage |
425 | } |
426 | |
427 | Wizard { |
428 | @@ -802,7 +691,7 @@ |
429 | z: dialogs.z + 10 |
430 | GlobalShortcut { shortcut: Qt.Key_Print; onTriggered: itemGrabber.capture(shell) } |
431 | Connections { |
432 | - target: applicationsDisplayLoader.item |
433 | + target: stage |
434 | ignoreUnknownSignals: true |
435 | onItemSnapshotRequested: itemGrabber.capture(item) |
436 | } |
437 | @@ -814,7 +703,7 @@ |
438 | z: itemGrabber.z + 1 |
439 | topBoundaryOffset: panel.panelHeight |
440 | |
441 | - confiningItem: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.itemConfiningMouseCursor : null |
442 | + confiningItem: stage.itemConfiningMouseCursor |
443 | |
444 | property bool mouseNeverMoved: true |
445 | Binding { |
446 | @@ -828,10 +717,9 @@ |
447 | |
448 | height: units.gu(3) |
449 | |
450 | - readonly property var previewRectangle: applicationsDisplayLoader.item && applicationsDisplayLoader.item.previewRectangle && |
451 | - applicationsDisplayLoader.item.previewRectangle.target && |
452 | - applicationsDisplayLoader.item.previewRectangle.target.dragging ? |
453 | - applicationsDisplayLoader.item.previewRectangle : null |
454 | + readonly property var previewRectangle: stage.previewRectangle.target && |
455 | + stage.previewRectangle.target.dragging ? |
456 | + stage.previewRectangle : null |
457 | |
458 | onPushedLeftBoundary: { |
459 | if (buttons === Qt.NoButton) { |
460 | @@ -842,9 +730,8 @@ |
461 | } |
462 | |
463 | onPushedRightBoundary: { |
464 | - if (buttons === Qt.NoButton && applicationsDisplayLoader.item |
465 | - && applicationsDisplayLoader.item.pushRightEdge) { |
466 | - applicationsDisplayLoader.item.pushRightEdge(amount); |
467 | + if (buttons === Qt.NoButton) { |
468 | + stage.pushRightEdge(amount); |
469 | } else if (buttons === Qt.LeftButton && previewRectangle && previewRectangle.target.canBeMaximizedLeftRight) { |
470 | previewRectangle.maximizeRight(amount); |
471 | } |
472 | |
473 | === renamed directory 'qml/Stages' => 'qml/Stage' |
474 | === modified file 'qml/Stage/ApplicationWindow.qml' |
475 | --- qml/Stages/ApplicationWindow.qml 2016-08-08 11:18:19 +0000 |
476 | +++ qml/Stage/ApplicationWindow.qml 2016-10-11 21:49:13 +0000 |
477 | @@ -20,8 +20,8 @@ |
478 | |
479 | FocusScope { |
480 | id: root |
481 | - implicitWidth: surfaceContainer.implicitWidth |
482 | - implicitHeight: surfaceContainer.implicitHeight |
483 | + implicitWidth: requestedWidth |
484 | + implicitHeight: requestedHeight |
485 | |
486 | // to be read from outside |
487 | property alias interactive: surfaceContainer.interactive |
488 | @@ -29,22 +29,10 @@ |
489 | readonly property string title: surface && surface.name !== "" ? surface.name : d.name |
490 | readonly property QtObject focusedSurface: d.focusedSurface.surface |
491 | |
492 | - // overridable from outside |
493 | - property bool fullscreen: { |
494 | - if (surface) { |
495 | - return surface.state === Mir.FullscreenState; |
496 | - } else if (application) { |
497 | - return application.fullscreen; |
498 | - } else { |
499 | - return false; |
500 | - } |
501 | - } |
502 | - |
503 | // to be set from outside |
504 | property QtObject surface |
505 | property QtObject application |
506 | property int surfaceOrientationAngle |
507 | - property alias resizeSurface: surfaceContainer.resizeSurface |
508 | property int requestedWidth: -1 |
509 | property int requestedHeight: -1 |
510 | property real splashRotation: 0 |
511 | @@ -156,6 +144,9 @@ |
512 | id: screenshotImage |
513 | objectName: "screenshotImage" |
514 | anchors.fill: parent |
515 | + fillMode: Image.PreserveAspectCrop |
516 | + horizontalAlignment: Image.AlignLeft |
517 | + verticalAlignment: Image.AlignTop |
518 | antialiasing: !root.interactive |
519 | z: 1 |
520 | |
521 | @@ -197,6 +188,7 @@ |
522 | |
523 | SurfaceContainer { |
524 | id: surfaceContainer |
525 | + anchors.fill: parent |
526 | z: splashLoader.z + 1 |
527 | requestedWidth: root.requestedWidth |
528 | requestedHeight: root.requestedHeight |
529 | @@ -220,6 +212,8 @@ |
530 | surface: model.surface |
531 | width: root.width |
532 | height: root.height |
533 | + requestedWidth: root.requestedWidth |
534 | + requestedHeight: root.requestedHeight |
535 | isPromptSurface: true |
536 | z: surfaceContainer.z + (promptSurfacesRepeater.count - index) |
537 | property int index: model.index |
538 | @@ -239,28 +233,6 @@ |
539 | property Item first: null |
540 | } |
541 | |
542 | - // SurfaceContainer size drives ApplicationWindow size |
543 | - Binding { |
544 | - target: root; property: "width" |
545 | - value: stateGroup.state === "surface" ? surfaceContainer.width : root.requestedWidth |
546 | - when: root.requestedWidth >= 0 |
547 | - } |
548 | - Binding { |
549 | - target: root; property: "height" |
550 | - value: stateGroup.state === "surface" ? surfaceContainer.height : root.requestedHeight |
551 | - when: root.requestedHeight >= 0 |
552 | - } |
553 | - |
554 | - // ApplicationWindow size drives SurfaceContainer size |
555 | - Binding { |
556 | - target: surfaceContainer; property: "width"; value: root.width |
557 | - when: root.requestedWidth < 0 |
558 | - } |
559 | - Binding { |
560 | - target: surfaceContainer; property: "height"; value: root.height |
561 | - when: root.requestedHeight < 0 |
562 | - } |
563 | - |
564 | StateGroup { |
565 | id: stateGroup |
566 | objectName: "applicationWindowStateGroup" |
567 | @@ -287,6 +259,11 @@ |
568 | (d.liveSurface || |
569 | (d.applicationState !== ApplicationInfoInterface.Running |
570 | && screenshotImage.status !== Image.Ready)) |
571 | + PropertyChanges { |
572 | + target: root |
573 | + implicitWidth: surfaceContainer.implicitWidth |
574 | + implicitHeight: surfaceContainer.implicitHeight |
575 | + } |
576 | }, |
577 | State { |
578 | name: "screenshot" |
579 | @@ -424,5 +401,4 @@ |
580 | } |
581 | ] |
582 | } |
583 | - |
584 | } |
585 | |
586 | === modified file 'qml/Stage/DecoratedWindow.qml' |
587 | --- qml/Stages/DecoratedWindow.qml 2016-09-08 14:13:27 +0000 |
588 | +++ qml/Stage/DecoratedWindow.qml 2016-10-11 21:49:13 +0000 |
589 | @@ -17,34 +17,46 @@ |
590 | import QtQuick 2.4 |
591 | import Ubuntu.Components 1.3 |
592 | import Unity.Application 0.1 |
593 | +import "Spread/MathUtils.js" as MathUtils |
594 | |
595 | FocusScope { |
596 | id: root |
597 | |
598 | - width: !counterRotate ? applicationWindow.width : applicationWindow.height |
599 | - height: visibleDecorationHeight + (!counterRotate ? applicationWindow.height : applicationWindow.width) |
600 | + // The DecoratedWindow takes requestedWidth/requestedHeight and asks its surface to be resized to that |
601 | + // (minus the window decoration size in case hasDecoration and showDecoration are true) |
602 | + // The surface might not be able to resize to the requested values. It will return its actual size |
603 | + // in implicitWidth/implicitHeight. |
604 | |
605 | property alias application: applicationWindow.application |
606 | property alias surface: applicationWindow.surface |
607 | readonly property alias focusedSurface: applicationWindow.focusedSurface |
608 | property alias active: decoration.active |
609 | readonly property alias title: applicationWindow.title |
610 | - property alias fullscreen: applicationWindow.fullscreen |
611 | property alias maximizeButtonShown: decoration.maximizeButtonShown |
612 | + property alias interactive: applicationWindow.interactive |
613 | + readonly property alias orientationChangesEnabled: applicationWindow.orientationChangesEnabled |
614 | |
615 | - readonly property bool decorationShown: !fullscreen |
616 | - property bool highlightShown: false |
617 | - property real shadowOpacity: 1 |
618 | + // Changing this will actually add/remove a decoration, meaning, requestedHeight will take the decoration into account. |
619 | + property bool hasDecoration: true |
620 | + // This will temporarily show/hide the decoration without actually changing the surface's dimensions |
621 | + property real showDecoration: 1 |
622 | + property bool animateDecoration: false |
623 | + property bool showHighlight: false |
624 | + property int highlightSize: units.gu(1) |
625 | + property real shadowOpacity: 0 |
626 | + property bool darkening: false |
627 | |
628 | property real requestedWidth |
629 | property real requestedHeight |
630 | + property real scaleToPreviewProgress: 0 |
631 | + property int scaleToPreviewSize: units.gu(30) |
632 | |
633 | property alias surfaceOrientationAngle: applicationWindow.surfaceOrientationAngle |
634 | - readonly property real visibleDecorationHeight: root.decorationShown ? decoration.height : 0 |
635 | + readonly property real decorationHeight: Math.min(d.visibleDecorationHeight, d.requestedDecorationHeight) |
636 | readonly property bool counterRotate: surfaceOrientationAngle != 0 && surfaceOrientationAngle != 180 |
637 | |
638 | readonly property int minimumWidth: !counterRotate ? applicationWindow.minimumWidth : applicationWindow.minimumHeight |
639 | - readonly property int minimumHeight: visibleDecorationHeight + (!counterRotate ? applicationWindow.minimumHeight : applicationWindow.minimumWidth) |
640 | + readonly property int minimumHeight: decorationHeight + (!counterRotate ? applicationWindow.minimumHeight : applicationWindow.minimumWidth) |
641 | readonly property int maximumWidth: !counterRotate ? applicationWindow.maximumWidth : applicationWindow.maximumHeight |
642 | readonly property int maximumHeight: (root.decorationShown && applicationWindow.maximumHeight > 0 ? decoration.height : 0) |
643 | + (!counterRotate ? applicationWindow.maximumHeight : applicationWindow.maximumWidth) |
644 | @@ -66,40 +78,86 @@ |
645 | signal decorationPressed() |
646 | signal decorationReleased() |
647 | |
648 | + QtObject { |
649 | + id: d |
650 | + property int requestedDecorationHeight: root.hasDecoration ? decoration.height : 0 |
651 | + Behavior on requestedDecorationHeight { enabled: root.animateDecoration; UbuntuNumberAnimation { } } |
652 | + |
653 | + property int visibleDecorationHeight: root.hasDecoration ? root.showDecoration * decoration.height : 0 |
654 | + Behavior on visibleDecorationHeight { enabled: root.animateDecoration; UbuntuNumberAnimation { } } |
655 | + } |
656 | + |
657 | + StateGroup { |
658 | + states: [ |
659 | + State { |
660 | + name: "normal"; when: root.scaleToPreviewProgress <= 0 && root.application.state === ApplicationInfoInterface.Running |
661 | + PropertyChanges { |
662 | + target: root |
663 | + implicitWidth: counterRotate ? applicationWindow.implicitHeight : applicationWindow.implicitWidth |
664 | + implicitHeight: root.decorationHeight + (counterRotate ? applicationWindow.implicitWidth: applicationWindow.implicitHeight) |
665 | + } |
666 | + }, |
667 | + State { |
668 | + name: "normalSuspended"; when: root.scaleToPreviewProgress <= 0 && root.application.state !== ApplicationInfoInterface.Running |
669 | + extend: "normal" |
670 | + PropertyChanges { |
671 | + target: root |
672 | + implicitWidth: counterRotate ? applicationWindow.requestedHeight : applicationWindow.requestedWidth |
673 | + implicitHeight: root.decorationHeight + (counterRotate ? applicationWindow.requestedWidth: applicationWindow.requestedHeight) |
674 | + } |
675 | + }, |
676 | + State { |
677 | + name: "preview"; when: root.scaleToPreviewProgress > 0 |
678 | + PropertyChanges { |
679 | + target: root |
680 | + implicitWidth: MathUtils.linearAnimation(0, 1, applicationWindow.oldRequestedWidth, root.scaleToPreviewSize, root.scaleToPreviewProgress) |
681 | + implicitHeight: MathUtils.linearAnimation(0, 1, applicationWindow.oldRequestedHeight, root.scaleToPreviewSize, root.scaleToPreviewProgress) |
682 | + } |
683 | + PropertyChanges { |
684 | + target: applicationWindow; |
685 | + requestedWidth: applicationWindow.oldRequestedWidth |
686 | + requestedHeight: applicationWindow.oldRequestedHeight |
687 | + width: MathUtils.linearAnimation(0, 1, applicationWindow.oldRequestedWidth, applicationWindow.minSize, root.scaleToPreviewProgress) |
688 | + height: MathUtils.linearAnimation(0, 1, applicationWindow.oldRequestedHeight, applicationWindow.minSize, root.scaleToPreviewProgress) |
689 | + itemScale: root.implicitWidth / width |
690 | + } |
691 | + } |
692 | + ] |
693 | + } |
694 | + |
695 | Rectangle { |
696 | id: selectionHighlight |
697 | + objectName: "selectionHighlight" |
698 | anchors.fill: parent |
699 | - anchors.margins: -units.gu(1) |
700 | + anchors.margins: -root.highlightSize |
701 | color: "white" |
702 | - opacity: highlightShown ? 0.15 : 0 |
703 | - } |
704 | - |
705 | - Rectangle { |
706 | - anchors { left: selectionHighlight.left; right: selectionHighlight.right; bottom: selectionHighlight.bottom; } |
707 | - height: units.dp(2) |
708 | - color: theme.palette.normal.focus |
709 | - visible: highlightShown |
710 | + opacity: showHighlight ? 0.55 : 0 |
711 | + visible: opacity > 0 |
712 | } |
713 | |
714 | BorderImage { |
715 | + id: dropShadow |
716 | anchors { |
717 | - fill: root |
718 | + left: parent.left; top: parent.top; right: parent.right |
719 | margins: active ? -units.gu(2) : -units.gu(1.5) |
720 | } |
721 | - source: "graphics/dropshadow2gu.sci" |
722 | - opacity: root.shadowOpacity * .3 |
723 | - visible: !fullscreen |
724 | + height: Math.min(applicationWindow.implicitHeight, applicationWindow.height) * applicationWindow.itemScale |
725 | + + root.decorationHeight * Math.min(1, root.showDecoration) + (active ? units.gu(4) : units.gu(3)) |
726 | + source: "../graphics/dropshadow2gu.sci" |
727 | + opacity: root.shadowOpacity |
728 | } |
729 | |
730 | WindowDecoration { |
731 | id: decoration |
732 | - target: root.parent |
733 | + target: root.parent || null |
734 | objectName: "appWindowDecoration" |
735 | anchors { left: parent.left; top: parent.top; right: parent.right } |
736 | height: units.gu(3) |
737 | width: root.width |
738 | title: applicationWindow.title |
739 | - visible: root.decorationShown |
740 | + opacity: root.hasDecoration ? Math.min(1, root.showDecoration) : 0 |
741 | + |
742 | + Behavior on opacity { UbuntuNumberAnimation { } } |
743 | |
744 | onCloseClicked: root.closeClicked(); |
745 | onMaximizeClicked: { root.decorationPressed(); root.maximizeClicked(); } |
746 | @@ -126,16 +184,25 @@ |
747 | ApplicationWindow { |
748 | id: applicationWindow |
749 | objectName: "appWindow" |
750 | + anchors.left: parent.left |
751 | anchors.top: parent.top |
752 | - anchors.topMargin: decoration.height |
753 | - anchors.left: parent.left |
754 | - readonly property real requestedHeightMinusDecoration: root.requestedHeight - root.visibleDecorationHeight |
755 | - requestedHeight: !counterRotate ? requestedHeightMinusDecoration : root.requestedWidth |
756 | - requestedWidth: !counterRotate ? root.requestedWidth : requestedHeightMinusDecoration |
757 | - interactive: true |
758 | + anchors.topMargin: root.decorationHeight * Math.min(1, root.showDecoration) |
759 | + width: implicitWidth |
760 | + height: implicitHeight |
761 | + requestedHeight: !counterRotate ? root.requestedHeight - d.requestedDecorationHeight : root.requestedWidth |
762 | + requestedWidth: !counterRotate ? root.requestedWidth : root.requestedHeight - d.requestedDecorationHeight |
763 | + property int oldRequestedWidth: requestedWidth |
764 | + property int oldRequestedHeight: requestedHeight |
765 | + onRequestedWidthChanged: oldRequestedWidth = requestedWidth |
766 | + onRequestedHeightChanged: oldRequestedHeight = requestedHeight |
767 | focus: true |
768 | |
769 | - transform: Rotation { |
770 | + property real itemScale: 1 |
771 | + property real minSize: Math.min(root.scaleToPreviewSize, Math.min(requestedHeight, Math.min(requestedWidth, Math.min(implicitHeight, implicitWidth)))) |
772 | + |
773 | + transform: [ |
774 | + Rotation { |
775 | + id: rotationTransform |
776 | readonly property int rotationAngle: applicationWindow.application && |
777 | applicationWindow.application.rotatesWindowContents |
778 | ? ((360 - applicationWindow.surfaceOrientationAngle) % 360) : 0 |
779 | @@ -152,6 +219,19 @@ |
780 | else return 0; |
781 | } |
782 | angle: rotationAngle |
783 | - } |
784 | + }, |
785 | + Scale { |
786 | + xScale: applicationWindow.itemScale |
787 | + yScale: applicationWindow.itemScale |
788 | + } |
789 | + ] |
790 | + |
791 | + } |
792 | + |
793 | + Rectangle { |
794 | + anchors.fill: parent |
795 | + color: "black" |
796 | + opacity: root.darkening && !root.showHighlight ? 0.05 : 0 |
797 | + Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } } |
798 | } |
799 | } |
800 | |
801 | === modified file 'qml/Stage/MoveHandler.qml' |
802 | --- qml/Stages/MoveHandler.qml 2016-09-08 14:13:27 +0000 |
803 | +++ qml/Stage/MoveHandler.qml 2016-10-11 21:49:13 +0000 |
804 | @@ -112,8 +112,8 @@ |
805 | // Use integer coordinate values to ensure that target is left in a pixel-aligned |
806 | // position. Mouse movement could have subpixel precision, yielding a fractional |
807 | // mouse position. |
808 | - target.requestedX = Math.round(pos.x - priv.distanceX); |
809 | - target.requestedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight)); |
810 | + target.windowedX = Math.round(pos.x - priv.distanceX); |
811 | + target.windowedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight)); |
812 | |
813 | if (sensingPoints) { // edge/corner detection when dragging via the touch overlay |
814 | if (sensingPoints.topLeft.x < priv.triggerArea && sensingPoints.topLeft.y < PanelState.panelHeight + priv.triggerArea |
815 | |
816 | === modified file 'qml/Stage/PromptSurfaceAnimations.qml' |
817 | --- qml/Stages/PromptSurfaceAnimations.qml 2016-04-04 13:38:56 +0000 |
818 | +++ qml/Stage/PromptSurfaceAnimations.qml 2016-10-11 21:49:13 +0000 |
819 | @@ -43,7 +43,7 @@ |
820 | SequentialAnimation { |
821 | // clip so we don't go out of parent's bounds during spread |
822 | PropertyAction { target: root.container.parent; property: "clip"; value: true } |
823 | - UbuntuNumberAnimation { target: root.surfaceItem; property: "y"; to: root.container.height |
824 | + UbuntuNumberAnimation { target: root.surfaceItem; property: "anchors.topMargin"; to: root.container.height |
825 | duration: UbuntuAnimation.BriskDuration } |
826 | PropertyAction { target: root.surfaceItem; property: "visible"; value: false } |
827 | PropertyAction { target: container.parent; property: "clip"; value: false } |
828 | @@ -61,11 +61,10 @@ |
829 | // clip so we don't go out of parent's bounds during spread |
830 | PropertyAction { target: root.container.parent; property: "clip"; value: true } |
831 | ScriptAction { script: { |
832 | - root.surfaceItem.y = root.container.height; |
833 | root.surfaceItem.visible = true; |
834 | } } |
835 | UbuntuNumberAnimation { |
836 | - target: root.surfaceItem; property: "y"; to: 0 |
837 | + target: root.surfaceItem; property: "anchors.topMargin"; from: root.container.height; to: 0 |
838 | duration: UbuntuAnimation.BriskDuration |
839 | } |
840 | PropertyAction { target: container.parent; property: "clip"; value: false } |
841 | |
842 | === added directory 'qml/Stage/Spread' |
843 | === added file 'qml/Stage/Spread/BezierCurve.qml' |
844 | --- qml/Stage/Spread/BezierCurve.qml 1970-01-01 00:00:00 +0000 |
845 | +++ qml/Stage/Spread/BezierCurve.qml 2016-10-11 21:49:13 +0000 |
846 | @@ -0,0 +1,45 @@ |
847 | +/* |
848 | + * Copyright (C) 2016 Canonical, Ltd. |
849 | + * |
850 | + * This program is free software; you can redistribute it and/or modify |
851 | + * it under the terms of the GNU General Public License as published by |
852 | + * the Free Software Foundation; version 3. |
853 | + * |
854 | + * This program is distributed in the hope that it will be useful, |
855 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
856 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
857 | + * GNU General Public License for more details. |
858 | + * |
859 | + * You should have received a copy of the GNU General Public License |
860 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
861 | + */ |
862 | + |
863 | +import QtQuick 2.4 |
864 | +import Ubuntu.Components 1.3 |
865 | +import QtQuick.Window 2.2 |
866 | +import 'cubic-bezier.js' as Bezier |
867 | +import 'KeySpline.js' as KeySpline |
868 | + |
869 | +Item { |
870 | + id: root |
871 | + |
872 | + property var controlPoint1: {'x':0, 'y':0} |
873 | + property var controlPoint2: {'x':0, 'y':0} |
874 | + property var controlPoint3: {'x':0.58, 'y':1} |
875 | + property var controlPoint4: {'x':1, 'y':1} |
876 | + |
877 | + function getValues(t) { |
878 | + if (t<0) t=0 |
879 | + else if (t>1)t=1 |
880 | + |
881 | + return Bezier.getBezier(t, controlPoint1, controlPoint2, controlPoint3, controlPoint4) |
882 | + } |
883 | + |
884 | + function getYFromX(x) { |
885 | + var spline = new KeySpline.keySpline(controlPoint2.x, controlPoint2.y, controlPoint3.x, controlPoint3.y) |
886 | + if (x<0) x=0 |
887 | + else if (x>1)x=1 |
888 | + |
889 | + return spline.get(x) |
890 | + } |
891 | +} |
892 | |
893 | === added file 'qml/Stage/Spread/KeySpline.js' |
894 | --- qml/Stage/Spread/KeySpline.js 1970-01-01 00:00:00 +0000 |
895 | +++ qml/Stage/Spread/KeySpline.js 2016-10-11 21:49:13 +0000 |
896 | @@ -0,0 +1,66 @@ |
897 | +/** MIT License |
898 | + * |
899 | + * KeySpline - use bezier curve for transition easing function |
900 | + * Copyright (c) 2012 Gaetan Renaudeau <renaudeau.gaetan@gmail.com> |
901 | + * |
902 | + * Permission is hereby granted, free of charge, to any person obtaining a |
903 | + * copy of this software and associated documentation files (the "Software"), |
904 | + * to deal in the Software without restriction, including without limitation |
905 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
906 | + * and/or sell copies of the Software, and to permit persons to whom the |
907 | + * Software is furnished to do so, subject to the following conditions: |
908 | + * |
909 | + * The above copyright notice and this permission notice shall be included in |
910 | + * all copies or substantial portions of the Software. |
911 | + * |
912 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
913 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
914 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
915 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
916 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
917 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
918 | + * DEALINGS IN THE SOFTWARE. |
919 | + */ |
920 | +/** |
921 | +* KeySpline - use bezier curve for transition easing function |
922 | +* is inspired from Firefox's nsSMILKeySpline.cpp |
923 | +* Usage: |
924 | +* var spline = new KeySpline(0.25, 0.1, 0.25, 1.0) |
925 | +* spline.get(x) => returns the easing value | x must be in [0, 1] range |
926 | +*/ |
927 | + |
928 | +.pragma library |
929 | + |
930 | +function keySpline (mX1, mY1, mX2, mY2) { |
931 | + |
932 | + this.get = function(aX) { |
933 | + if (mX1 == mY1 && mX2 == mY2) return aX; // linear |
934 | + return CalcBezier(GetTForX(aX), mY1, mY2); |
935 | + } |
936 | + |
937 | + function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } |
938 | + function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } |
939 | + function C(aA1) { return 3.0 * aA1; } |
940 | + |
941 | + // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. |
942 | + function CalcBezier(aT, aA1, aA2) { |
943 | + return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT; |
944 | + } |
945 | + |
946 | + // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. |
947 | + function GetSlope(aT, aA1, aA2) { |
948 | + return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1); |
949 | + } |
950 | + |
951 | + function GetTForX(aX) { |
952 | + // Newton raphson iteration |
953 | + var aGuessT = aX; |
954 | + for (var i = 0; i < 4; ++i) { |
955 | + var currentSlope = GetSlope(aGuessT, mX1, mX2); |
956 | + if (currentSlope == 0.0) return aGuessT; |
957 | + var currentX = CalcBezier(aGuessT, mX1, mX2) - aX; |
958 | + aGuessT -= currentX / currentSlope; |
959 | + } |
960 | + return aGuessT; |
961 | + } |
962 | +} |
963 | |
964 | === added file 'qml/Stage/Spread/MathUtils.js' |
965 | --- qml/Stage/Spread/MathUtils.js 1970-01-01 00:00:00 +0000 |
966 | +++ qml/Stage/Spread/MathUtils.js 2016-10-11 21:49:13 +0000 |
967 | @@ -0,0 +1,95 @@ |
968 | +/* |
969 | + * Copyright (C) 2016 Canonical, Ltd. |
970 | + * |
971 | + * This program is free software; you can redistribute it and/or modify |
972 | + * it under the terms of the GNU General Public License as published by |
973 | + * the Free Software Foundation; version 3. |
974 | + * |
975 | + * This program is distributed in the hope that it will be useful, |
976 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
977 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
978 | + * GNU General Public License for more details. |
979 | + * |
980 | + * You should have received a copy of the GNU General Public License |
981 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
982 | + */ |
983 | + |
984 | +.pragma library |
985 | + |
986 | +/** |
987 | + * From processing.js: https://raw.githubusercontent.com/processing-js/processing-js/v1.4.8/processing.js |
988 | + * |
989 | + * Re-map a number from one range to another. In the example above, the number |
990 | + * '25' is converted from a value in the range 0..100 into a value that |
991 | + * ranges from the left edge (0) to the right edge (width) of the screen. |
992 | + * Numbers outside the range are not clamped to 0 and 1, because out-of-range |
993 | + * values are often intentional and useful. |
994 | + * |
995 | + * @param {Number} value The incoming value to be converted |
996 | + * @param {Number} istart Lower bound of the value's current range |
997 | + * @param {Number} istop Upper bound of the value's current range |
998 | + * @param {Number} ostart Lower bound of the value's target range |
999 | + * @param {Number} ostop Upper bound of the value's target range |
1000 | + * |
1001 | + * @returns {Number} |
1002 | + */ |
1003 | +function map(value, istart, istop, ostart, ostop) { |
1004 | + return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)) |
1005 | +} |
1006 | + |
1007 | +/** |
1008 | + * Return a value which is always between `min` and `max` |
1009 | + * |
1010 | + * @param {Number} value The current value |
1011 | + * @param {Number} min The minimum value |
1012 | + * @param {Number} max The maximum value |
1013 | + * |
1014 | + * @returns {Number} |
1015 | + */ |
1016 | +function clamp(value, min, max) { |
1017 | + if (value < min) return min |
1018 | + if (value > max) return max |
1019 | + return value |
1020 | +} |
1021 | + |
1022 | +// calculates the distance from the middle of one rect to middle of other rect |
1023 | +function rectDistance(rect1, rect2) { |
1024 | + return pointDistance(Qt.point(rect1.x + rect1.width / 2, rect1.y + rect1.height / 2), |
1025 | + Qt.point(rect2.x + rect2.width / 2, rect2.y + rect2.height / 2)) |
1026 | +} |
1027 | + |
1028 | +// calculates the distance between two points |
1029 | +function pointDistance(point1, point2) { |
1030 | + return Math.sqrt(Math.pow(point1.x - point2.x, 2) + |
1031 | + Math.pow(point1.y - point2.y, 2) |
1032 | + ) |
1033 | +} |
1034 | + |
1035 | +// from http://stackoverflow.com/questions/14616829/java-method-to-find-the-rectangle-that-is-the-intersection-of-two-rectangles-usi |
1036 | +function intersectionRect(r1, r2) { |
1037 | + var xmin = Math.max(r1.x, r2.x); |
1038 | + var xmax1 = r1.x + r1.width; |
1039 | + var xmax2 = r2.x + r2.width; |
1040 | + var xmax = Math.min(xmax1, xmax2); |
1041 | + var out = {x:0, y:0, width:0, height:0} |
1042 | + if (xmax > xmin) { |
1043 | + var ymin = Math.max(r1.y, r2.y); |
1044 | + var ymax1 = r1.y + r1.height; |
1045 | + var ymax2 = r2.y + r2.height; |
1046 | + var ymax = Math.min(ymax1, ymax2); |
1047 | + if (ymax > ymin) { |
1048 | + out.x = xmin; |
1049 | + out.y = ymin; |
1050 | + out.width = xmax - xmin; |
1051 | + out.height = ymax - ymin; |
1052 | + } |
1053 | + } |
1054 | + return out; |
1055 | +} |
1056 | + |
1057 | +function easeOutCubic(t) { return (--t)*t*t+1 } |
1058 | + |
1059 | +function linearAnimation(startProgress, endProgress, startValue, endValue, progress) { |
1060 | + // progress : progressDiff = value : valueDiff => value = progress * valueDiff / progressDiff |
1061 | + return (progress - startProgress) * (endValue - startValue) / (endProgress - startProgress) + startValue; |
1062 | +} |
1063 | |
1064 | === added file 'qml/Stage/Spread/OpacityMask.qml' |
1065 | --- qml/Stage/Spread/OpacityMask.qml 1970-01-01 00:00:00 +0000 |
1066 | +++ qml/Stage/Spread/OpacityMask.qml 2016-10-11 21:49:13 +0000 |
1067 | @@ -0,0 +1,82 @@ |
1068 | +/* |
1069 | + * Copyright (C) 2016 Canonical, Ltd. |
1070 | + * |
1071 | + * This program is free software; you can redistribute it and/or modify |
1072 | + * it under the terms of the GNU General Public License as published by |
1073 | + * the Free Software Foundation; version 3. |
1074 | + * |
1075 | + * This program is distributed in the hope that it will be useful, |
1076 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1077 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1078 | + * GNU General Public License for more details. |
1079 | + * |
1080 | + * You should have received a copy of the GNU General Public License |
1081 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1082 | + */ |
1083 | + |
1084 | +import QtQuick 2.4 |
1085 | + |
1086 | +Item { |
1087 | + id: root |
1088 | + anchors.fill: sourceItem |
1089 | + anchors.margins: -units.gu(2) |
1090 | + visible: sourceItem !== null |
1091 | + |
1092 | + property var sourceItem: null |
1093 | + property int maskX: 0 |
1094 | + property int maskY: 0 |
1095 | + property int maskWidth: 0 |
1096 | + property int maskHeight: 0 |
1097 | + |
1098 | + property real opacityValue: 1 |
1099 | + |
1100 | + Item { |
1101 | + id: opacityMask |
1102 | + anchors.fill: parent |
1103 | + |
1104 | + Rectangle { |
1105 | + id: clipRect |
1106 | + color: "black" |
1107 | + x: root.maskX - root.anchors.margins |
1108 | + y: root.maskY - root.anchors.margins |
1109 | + width: root.maskWidth |
1110 | + height: root.maskHeight |
1111 | + opacity: 1 - root.opacityValue |
1112 | + } |
1113 | + } |
1114 | + |
1115 | + ShaderEffect { |
1116 | + id: opacityEffect |
1117 | + anchors.fill: parent |
1118 | + |
1119 | + property variant source: ShaderEffectSource { |
1120 | + id: shaderEffectSource |
1121 | + sourceItem: root.sourceItem |
1122 | + sourceRect: root.sourceItem ? Qt.rect(sourceItem.x + root.anchors.margins, |
1123 | + sourceItem.y + root.anchors.margins, |
1124 | + sourceItem.width - root.anchors.margins * 2, |
1125 | + sourceItem.height - root.anchors.margins * 2) |
1126 | + : Qt.rect(0,0,0,0) |
1127 | + hideSource: true |
1128 | + } |
1129 | + |
1130 | + property var mask: ShaderEffectSource { |
1131 | + sourceItem: opacityMask |
1132 | + hideSource: true |
1133 | + } |
1134 | + |
1135 | + fragmentShader: " |
1136 | + varying highp vec2 qt_TexCoord0; |
1137 | + uniform sampler2D source; |
1138 | + uniform sampler2D mask; |
1139 | + void main(void) |
1140 | + { |
1141 | + highp vec4 sourceColor = texture2D(source, qt_TexCoord0); |
1142 | + highp vec4 maskColor = texture2D(mask, qt_TexCoord0); |
1143 | + |
1144 | + sourceColor *= 1.0 - maskColor.a; |
1145 | + |
1146 | + gl_FragColor = sourceColor; |
1147 | + }" |
1148 | + } |
1149 | +} |
1150 | |
1151 | === added file 'qml/Stage/Spread/Spread.qml' |
1152 | --- qml/Stage/Spread/Spread.qml 1970-01-01 00:00:00 +0000 |
1153 | +++ qml/Stage/Spread/Spread.qml 2016-10-11 21:49:13 +0000 |
1154 | @@ -0,0 +1,162 @@ |
1155 | +/* |
1156 | + * Copyright (C) 2016 Canonical, Ltd. |
1157 | + * |
1158 | + * This program is free software; you can redistribute it and/or modify |
1159 | + * it under the terms of the GNU General Public License as published by |
1160 | + * the Free Software Foundation; version 3. |
1161 | + * |
1162 | + * This program is distributed in the hope that it will be useful, |
1163 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1164 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1165 | + * GNU General Public License for more details. |
1166 | + * |
1167 | + * You should have received a copy of the GNU General Public License |
1168 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1169 | + */ |
1170 | + |
1171 | +import QtQuick 2.4 |
1172 | +import Ubuntu.Components 1.3 |
1173 | +import "MathUtils.js" as MathUtils |
1174 | + |
1175 | +Item { |
1176 | + id: root |
1177 | + |
1178 | + // Information about the environment |
1179 | + property int highlightedIndex: -1 |
1180 | + property var model: null |
1181 | + property int leftMargin: 0 |
1182 | + property var spreadFlickable |
1183 | + |
1184 | + // some config options |
1185 | + property real contentMargin: 0.16 * root.height |
1186 | + property real contentTopMargin: contentMargin |
1187 | + property real contentBottomMargin: 0.35 * contentMargin |
1188 | + property real windowTitleTopMargin: 3/4 * (contentTopMargin - windowTitle.height) |
1189 | + property int stackItemCount: 3 |
1190 | + property real leftRotationAngle: 22 |
1191 | + property real rightRotationAngle: 32 |
1192 | + property real leftStackScale: .82 |
1193 | + property real rightStackScale: 1 |
1194 | + property real rightEdgeBreakPoint: Math.min(units.gu(40) / root.width, .35) |
1195 | + |
1196 | + signal leaveSpread() |
1197 | + |
1198 | + // Calculated stuff |
1199 | + readonly property int totalItemCount: model.count |
1200 | + readonly property real leftStackXPos: 0.03 * root.width + leftMargin |
1201 | + readonly property real rightStackXPos: root.width - 1.5 * leftStackXPos + leftMargin |
1202 | + |
1203 | + readonly property real stackHeight: spreadItemHeight - appInfoHeight |
1204 | + readonly property real stackWidth: Math.min(leftStackXPos/3, units.gu(1.5)) |
1205 | + |
1206 | + readonly property real spreadWidth: rightStackXPos - leftStackXPos |
1207 | + readonly property real spreadHeight: root.height |
1208 | + readonly property real spreadItemHeight: spreadHeight - contentTopMargin - contentBottomMargin |
1209 | + readonly property real spreadItemWidth: stackHeight |
1210 | + |
1211 | + readonly property real dynamicLeftRotationAngle: leftRotationAngle * rotationAngleFactor |
1212 | + readonly property real dynamicRightRotationAngle: rightRotationAngle * rotationAngleFactor |
1213 | + |
1214 | + readonly property real appInfoHeight: { |
1215 | + var screenHeightReferencePoint = 40 // ref screen height in gu |
1216 | + var valueAtReferencePoint = 0.17 // of screen height at the reference point |
1217 | + var appInfoHeightValueChange = -0.0014 // units / gu |
1218 | + var minAppInfoHeight = 0.08 |
1219 | + var maxAppInfoHeight = 0.2 |
1220 | + var screenHeightInGU = root.height / units.gu(1) // screenHeight in gu |
1221 | + |
1222 | + return MathUtils.clamp(valueAtReferencePoint + appInfoHeightValueChange * (screenHeightInGU - screenHeightReferencePoint), minAppInfoHeight, maxAppInfoHeight) * root.height |
1223 | + } |
1224 | + |
1225 | + property real rotationAngleFactor: { |
1226 | + var spreadHeightReferencePoint = 28 // reference spread height in gu |
1227 | + var valueAtReferencePoint = 1.3 |
1228 | + var rotationAngleValueChange = -0.008 // units / gu |
1229 | + var minRotationAngleFactor = 0.6 |
1230 | + var maxRotationAngleFactor = 1.5 |
1231 | + var spreadHeightInGU = spreadHeight / units.gu(1) |
1232 | + |
1233 | + return MathUtils.clamp(valueAtReferencePoint + rotationAngleValueChange * (spreadHeightInGU - spreadHeightReferencePoint), minRotationAngleFactor, maxRotationAngleFactor) |
1234 | + } |
1235 | + readonly property real itemOverlap: { |
1236 | + var spreadAspectRatioReferencePoint = 1.0 // ref screen height in gu |
1237 | + var valueAtReferencePoint = 0.74 // of screen height at the reference point |
1238 | + var itemOverlapValueChange = -0.068 |
1239 | + var minOverlap = 0.55 |
1240 | + var maxOverlap = 0.82 |
1241 | + var spreadAspectRatio = spreadWidth / stackHeight // spread stack aspect ratio (app info not included) |
1242 | + |
1243 | + return MathUtils.clamp(valueAtReferencePoint + itemOverlapValueChange * (spreadAspectRatio - spreadAspectRatioReferencePoint), minOverlap, maxOverlap) |
1244 | + } |
1245 | + |
1246 | + readonly property real visibleItemCount: (spreadWidth / spreadItemWidth) / (1 - itemOverlap) |
1247 | + |
1248 | + readonly property real spreadTotalWidth: totalItemCount * spreadWidth / visibleItemCount |
1249 | + |
1250 | + readonly property real centeringOffset: Math.max(spreadWidth - spreadTotalWidth ,0) / (2 * spreadWidth) |
1251 | + |
1252 | + |
1253 | + readonly property var curve: BezierCurve { |
1254 | + controlPoint2: {'x': 0.19, 'y': 0.00} |
1255 | + controlPoint3: {'x': 0.91, 'y': 1.00} |
1256 | + } |
1257 | + |
1258 | + Label { |
1259 | + id: windowTitle |
1260 | + |
1261 | + width: Math.min(implicitWidth, 0.5*root.width) |
1262 | + elide: Qt.ElideMiddle |
1263 | + anchors.horizontalCenter: parent.horizontalCenter |
1264 | + y: windowTitleTopMargin |
1265 | + readonly property var highlightedSurface: root.model ? root.model.surfaceAt(root.highlightedIndex) : null |
1266 | + readonly property var highlightedApp: root.model ? root.model.applicationAt(root.highlightedIndex) : null |
1267 | + text: root.highlightedIndex >= 0 && highlightedSurface && highlightedSurface.name != "" ? highlightedSurface.name : |
1268 | + highlightedApp ? highlightedApp.name : "" |
1269 | + fontSize: root.height < units.gu(85) ? 'medium' : 'large' |
1270 | + color: "white" |
1271 | + opacity: root.highlightedIndex >= 0 ? 1 : 0 |
1272 | + Behavior on opacity { UbuntuNumberAnimation { } } |
1273 | + } |
1274 | + |
1275 | + Keys.onPressed: { |
1276 | + switch (event.key) { |
1277 | + case Qt.Key_Left: |
1278 | + case Qt.Key_Backtab: |
1279 | + selectPrevious(event.isAutoRepeat) |
1280 | + event.accepted = true; |
1281 | + break; |
1282 | + case Qt.Key_Right: |
1283 | + case Qt.Key_Tab: |
1284 | + selectNext(event.isAutoRepeat) |
1285 | + event.accepted = true; |
1286 | + break; |
1287 | + case Qt.Key_Escape: |
1288 | + highlightedIndex = -1 |
1289 | + // Falling through intentionally |
1290 | + case Qt.Key_Enter: |
1291 | + case Qt.Key_Return: |
1292 | + case Qt.Key_Space: |
1293 | + root.leaveSpread(); |
1294 | + event.accepted = true; |
1295 | + } |
1296 | + } |
1297 | + |
1298 | + |
1299 | + function selectNext(isAutoRepeat) { |
1300 | + if (isAutoRepeat && highlightedIndex >= totalItemCount -1) { |
1301 | + return; // AutoRepeat is not allowed to wrap around |
1302 | + } |
1303 | + |
1304 | + highlightedIndex = (highlightedIndex + 1) % totalItemCount; |
1305 | + spreadFlickable.snap(highlightedIndex) |
1306 | + } |
1307 | + |
1308 | + function selectPrevious(isAutoRepeat) { |
1309 | + if (isAutoRepeat && highlightedIndex == 0) { |
1310 | + return; // AutoRepeat is not allowed to wrap around |
1311 | + } |
1312 | + |
1313 | + highlightedIndex = highlightedIndex - 1 >= 0 ? highlightedIndex - 1 : totalItemCount - 1; |
1314 | + spreadFlickable.snap(highlightedIndex) |
1315 | + } |
1316 | +} |
1317 | |
1318 | === added file 'qml/Stage/Spread/SpreadDelegateInputArea.qml' |
1319 | --- qml/Stage/Spread/SpreadDelegateInputArea.qml 1970-01-01 00:00:00 +0000 |
1320 | +++ qml/Stage/Spread/SpreadDelegateInputArea.qml 2016-10-11 21:49:13 +0000 |
1321 | @@ -0,0 +1,183 @@ |
1322 | +/* |
1323 | + * Copyright (C) 2016 Canonical, Ltd. |
1324 | + * |
1325 | + * This program is free software; you can redistribute it and/or modify |
1326 | + * it under the terms of the GNU General Public License as published by |
1327 | + * the Free Software Foundation; version 3. |
1328 | + * |
1329 | + * This program is distributed in the hope that it will be useful, |
1330 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1331 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1332 | + * GNU General Public License for more details. |
1333 | + * |
1334 | + * You should have received a copy of the GNU General Public License |
1335 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1336 | + */ |
1337 | + |
1338 | +import QtQuick 2.4 |
1339 | +import Ubuntu.Components 1.3 |
1340 | +import Ubuntu.Gestures 0.1 |
1341 | +import "../../Components" |
1342 | + |
1343 | +Item { |
1344 | + id: root |
1345 | + |
1346 | + property bool closeable: true |
1347 | + readonly property real minSpeedToClose: units.gu(40) |
1348 | + property bool zeroVelocityCounts: false |
1349 | + |
1350 | + readonly property alias distance: d.distance |
1351 | + |
1352 | + signal clicked() |
1353 | + signal close() |
1354 | + |
1355 | + QtObject { |
1356 | + id: d |
1357 | + property real distance: 0 |
1358 | + property bool moving: false |
1359 | + property var dragEvents: [] |
1360 | + property real dragVelocity: 0 |
1361 | + property int threshold: units.gu(2) |
1362 | + |
1363 | + // Can be replaced with a fake implementation during tests |
1364 | + // property var __getCurrentTimeMs: function () { return new Date().getTime() } |
1365 | + property var __dateTime: new function() { |
1366 | + this.getCurrentTimeMs = function() {return new Date().getTime()} |
1367 | + } |
1368 | + |
1369 | + function pushDragEvent(event) { |
1370 | + var currentTime = __dateTime.getCurrentTimeMs() |
1371 | + dragEvents.push([currentTime, event.x - event.startX, event.y - event.startY, getEventSpeed(currentTime, event)]) |
1372 | + cullOldDragEvents(currentTime) |
1373 | + updateSpeed() |
1374 | + } |
1375 | + |
1376 | + function cullOldDragEvents(currentTime) { |
1377 | + // cull events older than 50 ms but always keep the latest 2 events |
1378 | + for (var numberOfCulledEvents = 0; numberOfCulledEvents < dragEvents.length-2; numberOfCulledEvents++) { |
1379 | + // dragEvents[numberOfCulledEvents][0] is the dragTime |
1380 | + if (currentTime - dragEvents[numberOfCulledEvents][0] <= 50) break |
1381 | + } |
1382 | + |
1383 | + dragEvents.splice(0, numberOfCulledEvents) |
1384 | + } |
1385 | + |
1386 | + function updateSpeed() { |
1387 | + var totalSpeed = 0 |
1388 | + for (var i = 0; i < dragEvents.length; i++) { |
1389 | + totalSpeed += dragEvents[i][3] |
1390 | + } |
1391 | + |
1392 | + if (zeroVelocityCounts || Math.abs(totalSpeed) > 0.001) { |
1393 | + dragVelocity = totalSpeed / dragEvents.length * 1000 |
1394 | + } |
1395 | + } |
1396 | + |
1397 | + function getEventSpeed(currentTime, event) { |
1398 | + if (dragEvents.length != 0) { |
1399 | + var lastDrag = dragEvents[dragEvents.length-1] |
1400 | + var duration = Math.max(1, currentTime - lastDrag[0]) |
1401 | + return (event.y - event.startY - lastDrag[2]) / duration |
1402 | + } else { |
1403 | + return 0 |
1404 | + } |
1405 | + } |
1406 | + } |
1407 | + |
1408 | + // Event eater |
1409 | + MouseArea { |
1410 | + anchors.fill: parent |
1411 | + onClicked: root.clicked() |
1412 | + onWheel: wheel.accepted = true |
1413 | + } |
1414 | + |
1415 | + MultiPointTouchArea { |
1416 | + anchors.fill: parent |
1417 | + mouseEnabled: false |
1418 | + maximumTouchPoints: 1 |
1419 | + property int offset: 0 |
1420 | + |
1421 | + touchPoints: [ |
1422 | + TouchPoint { |
1423 | + id: tp |
1424 | + } |
1425 | + ] |
1426 | + |
1427 | + onCanceled: { |
1428 | + d.moving = false |
1429 | + animation.animate("center"); |
1430 | + } |
1431 | + |
1432 | + onTouchUpdated: { |
1433 | + if (!d.moving) { |
1434 | + if (Math.abs(tp.startY - tp.y) > d.threshold) { |
1435 | + d.moving = true; |
1436 | + d.dragEvents = [] |
1437 | + offset = tp.y - tp.startY; |
1438 | + } else { |
1439 | + return; |
1440 | + } |
1441 | + } |
1442 | + |
1443 | + d.distance = tp.y - tp.startY - offset |
1444 | + d.pushDragEvent(tp); |
1445 | + } |
1446 | + |
1447 | + onReleased: { |
1448 | + if (!d.moving) { |
1449 | + root.clicked() |
1450 | + } |
1451 | + |
1452 | + if (!root.closeable) { |
1453 | + animation.animate("center") |
1454 | + return; |
1455 | + } |
1456 | + |
1457 | + var touchPoint = touchPoints[0]; |
1458 | + |
1459 | + if ((d.dragVelocity < -root.minSpeedToClose && d.distance < -units.gu(8)) || d.distance < -root.height / 2) { |
1460 | + animation.animate("up") |
1461 | + } else if ((d.dragVelocity > root.minSpeedToClose && d.distance > units.gu(8)) || d.distance > root.height / 2) { |
1462 | + animation.animate("down") |
1463 | + } else { |
1464 | + animation.animate("center") |
1465 | + } |
1466 | + } |
1467 | + } |
1468 | + |
1469 | + UbuntuNumberAnimation { |
1470 | + id: animation |
1471 | + objectName: "closeAnimation" |
1472 | + target: d |
1473 | + property: "distance" |
1474 | + property bool requestClose: false |
1475 | + |
1476 | + function animate(direction) { |
1477 | + animation.from = dragArea.distance; |
1478 | + switch (direction) { |
1479 | + case "up": |
1480 | + animation.to = -root.height * 1.5; |
1481 | + requestClose = true; |
1482 | + break; |
1483 | + case "down": |
1484 | + animation.to = root.height * 1.5; |
1485 | + requestClose = true; |
1486 | + break; |
1487 | + default: |
1488 | + animation.to = 0 |
1489 | + } |
1490 | + animation.start(); |
1491 | + } |
1492 | + |
1493 | + onRunningChanged: { |
1494 | + if (!running) { |
1495 | + d.moving = false; |
1496 | + if (requestClose) { |
1497 | + root.close(); |
1498 | + } else { |
1499 | + d.distance = 0; |
1500 | + } |
1501 | + } |
1502 | + } |
1503 | + } |
1504 | +} |
1505 | |
1506 | === added file 'qml/Stage/Spread/SpreadMaths.qml' |
1507 | --- qml/Stage/Spread/SpreadMaths.qml 1970-01-01 00:00:00 +0000 |
1508 | +++ qml/Stage/Spread/SpreadMaths.qml 2016-10-11 21:49:13 +0000 |
1509 | @@ -0,0 +1,78 @@ |
1510 | +/* |
1511 | + * Copyright (C) 2016 Canonical, Ltd. |
1512 | + * |
1513 | + * This program is free software; you can redistribute it and/or modify |
1514 | + * it under the terms of the GNU General Public License as published by |
1515 | + * the Free Software Foundation; version 3. |
1516 | + * |
1517 | + * This program is distributed in the hope that it will be useful, |
1518 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1519 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1520 | + * GNU General Public License for more details. |
1521 | + * |
1522 | + * You should have received a copy of the GNU General Public License |
1523 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1524 | + */ |
1525 | + |
1526 | +import QtQuick 2.4 |
1527 | +import Ubuntu.Components 1.3 |
1528 | +import Utils 0.1 |
1529 | +import "MathUtils.js" as MathUtils |
1530 | + |
1531 | +Item { |
1532 | + id: root |
1533 | + anchors { left: parent.left; top: parent.top; margins: units.gu(1) } |
1534 | + |
1535 | + // Information about the environment |
1536 | + property Item flickable: null |
1537 | + property Spread spread: null |
1538 | + property int itemIndex: 0 |
1539 | + |
1540 | + // Internal |
1541 | + property real spreadPosition: itemIndex/spread.visibleItemCount - flickable.contentX/spread.spreadWidth // 0 -> left stack, 1 -> right stack |
1542 | + property real leftStackingProgress: MathUtils.clamp(MathUtils.map(spreadPosition, 0, -spread.stackItemCount/spread.visibleItemCount , 0, 1), 0, 1) |
1543 | + property real rightStackingProgress: MathUtils.clamp(MathUtils.map(spreadPosition, 1, 1 + spread.stackItemCount/spread.visibleItemCount , 0, 1), 0, 1) |
1544 | + property real stackingX: (MathUtils.easeOutCubic(rightStackingProgress) - MathUtils.easeOutCubic(leftStackingProgress)) * spread.stackWidth |
1545 | + |
1546 | + |
1547 | + QtObject { |
1548 | + id: d |
1549 | + property real spreadScale: MathUtils.clamp( |
1550 | + MathUtils.map(spreadPosition, 0, 1, spread.leftStackScale, spread.rightStackScale), |
1551 | + spread.leftStackScale, spread.rightStackScale) |
1552 | + |
1553 | + property real selectedScale: (spread.highlightedIndex == itemIndex ? 1.01 : 1) |
1554 | + Behavior on selectedScale { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } } |
1555 | + |
1556 | + } |
1557 | + |
1558 | + // Output |
1559 | + readonly property int targetX: spread.leftStackXPos + |
1560 | + spread.spreadWidth * spread.curve.getYFromX(spreadPosition + spread.centeringOffset) + |
1561 | + stackingX |
1562 | + |
1563 | + readonly property int targetY: spread.contentTopMargin |
1564 | + |
1565 | + readonly property real targetAngle: MathUtils.clamp( |
1566 | + MathUtils.map(targetX, spread.leftStackXPos, spread.rightStackXPos, spread.dynamicLeftRotationAngle, spread.dynamicRightRotationAngle), |
1567 | + Math.min(spread.dynamicLeftRotationAngle, spread.dynamicRightRotationAngle), Math.max(spread.dynamicLeftRotationAngle, spread.dynamicRightRotationAngle)) |
1568 | + |
1569 | + |
1570 | + readonly property real targetScale: d.spreadScale * d.selectedScale |
1571 | + |
1572 | + readonly property real shadowOpacity: 0.2 * (1 - rightStackingProgress) * (1 - leftStackingProgress) |
1573 | + |
1574 | + |
1575 | + readonly property real closeIconOffset: (targetScale - 1) * (-spread.stackHeight / 2) |
1576 | + |
1577 | + readonly property real tileInfoOpacity: Math.min(MathUtils.clamp(MathUtils.map(leftStackingProgress, 0 , 1/(spread.stackItemCount*3), 1, 0), 0 , 1), |
1578 | + MathUtils.clamp(MathUtils.map(spreadPosition, 0.9 , 1, 1, 0), 0 , 1)) /** MathUtils.map(curvedSwitcherProgress, 0.7, 0.9, 0, 1)*/ |
1579 | + |
1580 | + readonly property bool itemVisible: { |
1581 | + var leftStackHidden = spreadPosition < -(spread.stackItemCount + 1)/spread.visibleItemCount |
1582 | + // don't hide the rightmost |
1583 | + var rightStackHidden = (spreadPosition > 1 + (spread.stackItemCount)/spread.visibleItemCount) && itemIndex !== spread.totalItemCount - 1 |
1584 | + return !leftStackHidden && !rightStackHidden |
1585 | + } |
1586 | + |
1587 | +} |
1588 | |
1589 | === added file 'qml/Stage/Spread/StagedRightEdgeMaths.qml' |
1590 | --- qml/Stage/Spread/StagedRightEdgeMaths.qml 1970-01-01 00:00:00 +0000 |
1591 | +++ qml/Stage/Spread/StagedRightEdgeMaths.qml 2016-10-11 21:49:13 +0000 |
1592 | @@ -0,0 +1,174 @@ |
1593 | +/* |
1594 | + * Copyright (C) 2016 Canonical, Ltd. |
1595 | + * |
1596 | + * This program is free software; you can redistribute it and/or modify |
1597 | + * it under the terms of the GNU General Public License as published by |
1598 | + * the Free Software Foundation; version 3. |
1599 | + * |
1600 | + * This program is distributed in the hope that it will be useful, |
1601 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1602 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1603 | + * GNU General Public License for more details. |
1604 | + * |
1605 | + * You should have received a copy of the GNU General Public License |
1606 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1607 | + */ |
1608 | + |
1609 | +import QtQuick 2.4 |
1610 | +import Ubuntu.Components 1.3 |
1611 | +import Unity.Application 0.1 |
1612 | +import "MathUtils.js" as MathUtils |
1613 | + |
1614 | +QtObject { |
1615 | + id: root |
1616 | + |
1617 | + // Input |
1618 | + property int itemIndex: 0 |
1619 | + property real progress: 0 |
1620 | + property int sceneWidth: 0 |
1621 | + property int sideStageWidth: 0 |
1622 | + property int sceneHeight: 0 |
1623 | + property int targetX: 0 |
1624 | + property int startY: 0 |
1625 | + property int targetY: 0 |
1626 | + property real startAngle: 30 |
1627 | + property real targetAngle: 0 |
1628 | + property int targetHeight: 0 |
1629 | + property real startScale: 1.3 |
1630 | + property real targetScale: 0 |
1631 | + property real breakPoint: units.gu(15) / sceneWidth |
1632 | + |
1633 | + property bool isMainStageApp: false |
1634 | + property bool isSideStageApp: false |
1635 | + property bool sideStageOpen: false |
1636 | + property int nextInStack: 0 |
1637 | + property int shuffledZ: 0 |
1638 | + |
1639 | + |
1640 | + // Config |
1641 | + property int tileDistance: units.gu(10) |
1642 | + |
1643 | + // Output |
1644 | + |
1645 | + readonly property real scaleToPreviewProgress: { |
1646 | + return progress < breakPoint ? 0 : MathUtils.clamp(MathUtils.linearAnimation(breakPoint, 1, 0, 1, progress), 0, 1) |
1647 | + } |
1648 | + readonly property int animatedWidth: { |
1649 | + return progress < breakPoint ? root.sceneHeight : MathUtils.linearAnimation(breakPoint, 1, root.sceneWidth, targetHeight, progress) |
1650 | + } |
1651 | + |
1652 | + readonly property int animatedHeight: { |
1653 | + return progress < breakPoint ? root.sceneHeight : MathUtils.linearAnimation(breakPoint, 1, root.sceneHeight, targetHeight, progress) |
1654 | + } |
1655 | + |
1656 | + |
1657 | + readonly property int animatedX: { |
1658 | + var nextStage = appRepeater.itemAt(nextInStack) ? appRepeater.itemAt(nextInStack).stage : ApplicationInfoInterface.MainStage; |
1659 | + |
1660 | + var startX = 0; |
1661 | + if (isMainStageApp) { |
1662 | + if (progress < breakPoint) { |
1663 | + if (nextStage == ApplicationInfoInterface.MainStage) { |
1664 | + return MathUtils.linearAnimation(0, breakPoint, 0, -units.gu(4), progress); |
1665 | + } else { |
1666 | + return 0; |
1667 | + } |
1668 | + } else { |
1669 | + if (nextStage == ApplicationInfoInterface.MainStage) { |
1670 | + return MathUtils.linearAnimation(breakPoint, 1, -units.gu(4), targetX, progress); |
1671 | + } else { |
1672 | + return MathUtils.linearAnimation(breakPoint, 1, 0, targetX, progress); |
1673 | + } |
1674 | + } |
1675 | + } else if (isSideStageApp) { |
1676 | + startX = sceneWidth - sideStageWidth; |
1677 | + } else if (itemIndex == nextInStack && itemIndex <= 2 && priv.sideStageDelegate && nextStage == ApplicationInfoInterface.MainStage) { |
1678 | + startX = sceneWidth - sideStageWidth; |
1679 | + } else { |
1680 | + var stageCount = (priv.mainStageDelegate ? 1 : 0) + (priv.sideStageDelegate ? 1 : 0) |
1681 | + startX = sceneWidth + Math.max(0, itemIndex - stageCount - 1) * tileDistance; |
1682 | + } |
1683 | + |
1684 | + if (itemIndex == nextInStack) { |
1685 | + if (progress < breakPoint) { |
1686 | + return MathUtils.linearAnimation(0, breakPoint, startX, startX * (1 - breakPoint), progress) |
1687 | + } |
1688 | + return MathUtils.linearAnimation(breakPoint, 1, startX * (1 - breakPoint), targetX, progress) |
1689 | + } |
1690 | + |
1691 | + if (progress < breakPoint) { |
1692 | + return startX; |
1693 | + } |
1694 | + |
1695 | + return MathUtils.linearAnimation(breakPoint, 1, startX, targetX, progress) |
1696 | + |
1697 | + } |
1698 | + |
1699 | + readonly property int animatedY: progress < breakPoint ? startY : MathUtils.linearAnimation(breakPoint, 1, startY, targetY, progress) |
1700 | + |
1701 | + readonly property int animatedZ: { |
1702 | + if (progress < breakPoint + (1 - breakPoint) / 2) { |
1703 | + return shuffledZ |
1704 | + } |
1705 | + return itemIndex; |
1706 | + } |
1707 | + |
1708 | + readonly property real animatedAngle: { |
1709 | + var nextStage = appRepeater.itemAt(nextInStack) ? appRepeater.itemAt(nextInStack).stage : ApplicationInfoInterface.MainStage; |
1710 | + |
1711 | + var startAngle = 0; |
1712 | + if (isMainStageApp) { |
1713 | + startAngle = 0; |
1714 | + } else if (isSideStageApp) { |
1715 | + startAngle = 0; |
1716 | + } else { |
1717 | + if (stage == ApplicationInfoInterface.SideStage && itemIndex == nextInStack && !sideStageOpen) { |
1718 | + startAngle = 0; |
1719 | + } else { |
1720 | + startAngle = root.startAngle; |
1721 | + } |
1722 | + } |
1723 | + |
1724 | + if ((itemIndex == nextInStack) |
1725 | + || (isMainStageApp && nextStage === ApplicationInfoInterface.MainStage) |
1726 | + || (isSideStageApp && nextStage === ApplicationInfoInterface.SideStage)) { |
1727 | + return MathUtils.linearAnimation(0, 1, startAngle, targetAngle, progress); |
1728 | + } |
1729 | + |
1730 | + if (progress < breakPoint) { |
1731 | + return 0; |
1732 | + } |
1733 | + return MathUtils.linearAnimation(breakPoint, 1, startAngle, targetAngle, progress); |
1734 | + } |
1735 | + |
1736 | + readonly property real animatedScale: { |
1737 | + var pullingInSideStage = itemIndex == nextInStack && stage == ApplicationInfoInterface.SideStage && !sideStageOpen; |
1738 | + |
1739 | + var startScale = 1; |
1740 | + if (isMainStageApp) { |
1741 | + startScale = 1; |
1742 | + } else if (isSideStageApp) { |
1743 | + startScale = 1; |
1744 | + } else { |
1745 | + if (pullingInSideStage) { |
1746 | + startScale = 1 |
1747 | + } else { |
1748 | + startScale = root.startScale; |
1749 | + } |
1750 | + } |
1751 | + |
1752 | + if (progress < breakPoint) { |
1753 | + if (itemIndex == nextInStack && (sideStageOpen || stage == ApplicationInfoInterface.MainStage)) { |
1754 | + return MathUtils.linearAnimation(0, 1, startScale, targetScale, progress); |
1755 | + } |
1756 | + return startScale; |
1757 | + } |
1758 | + if (itemIndex == nextInStack) { |
1759 | + return MathUtils.linearAnimation(0, 1, startScale, targetScale, progress) |
1760 | + } |
1761 | + |
1762 | + return MathUtils.linearAnimation(breakPoint, 1, startScale, targetScale, progress) |
1763 | + } |
1764 | + |
1765 | + readonly property bool itemVisible: true //animatedX < sceneWidth |
1766 | +} |
1767 | |
1768 | === added file 'qml/Stage/Spread/WindowedRightEdgeMaths.qml' |
1769 | --- qml/Stage/Spread/WindowedRightEdgeMaths.qml 1970-01-01 00:00:00 +0000 |
1770 | +++ qml/Stage/Spread/WindowedRightEdgeMaths.qml 2016-10-11 21:49:13 +0000 |
1771 | @@ -0,0 +1,81 @@ |
1772 | +/* |
1773 | + * Copyright (C) 2016 Canonical, Ltd. |
1774 | + * |
1775 | + * This program is free software; you can redistribute it and/or modify |
1776 | + * it under the terms of the GNU General Public License as published by |
1777 | + * the Free Software Foundation; version 3. |
1778 | + * |
1779 | + * This program is distributed in the hope that it will be useful, |
1780 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1781 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1782 | + * GNU General Public License for more details. |
1783 | + * |
1784 | + * You should have received a copy of the GNU General Public License |
1785 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1786 | + */ |
1787 | + |
1788 | +import QtQuick 2.4 |
1789 | +import Ubuntu.Components 1.3 |
1790 | +import Unity.Application 0.1 |
1791 | +import "MathUtils.js" as MathUtils |
1792 | + |
1793 | +QtObject { |
1794 | + id: root |
1795 | + |
1796 | + // Input |
1797 | + property int itemIndex: 0 |
1798 | + property int normalZ: 0 |
1799 | + property real progress: 0 |
1800 | + property int startWidth: 0 |
1801 | + property int startHeight: 0 |
1802 | + property int startX: 0 |
1803 | + property int targetX: 0 |
1804 | + property int startY: 0 |
1805 | + property int targetY: 0 |
1806 | +// property real startAngle: 40 |
1807 | + property real targetAngle: 0 |
1808 | + property int targetHeight: 0 |
1809 | + property real targetScale: 0 |
1810 | + |
1811 | + // Config |
1812 | + property real breakPoint: 0.4 |
1813 | + |
1814 | + // Output |
1815 | + |
1816 | + readonly property real scaleToPreviewProgress: { |
1817 | + return progress < breakPoint ? 0 : MathUtils.clamp(MathUtils.linearAnimation(breakPoint, 1, 0, 1, progress), 0, 1) |
1818 | + } |
1819 | + readonly property int animatedWidth: { |
1820 | + return progress < breakPoint ? root.startWidth : MathUtils.linearAnimation(breakPoint, 1, root.startWidth, targetHeight, progress) |
1821 | + } |
1822 | + |
1823 | + readonly property int animatedHeight: { |
1824 | + return progress < breakPoint ? root.startHeight : MathUtils.linearAnimation(breakPoint, 1, root.startHeight, targetHeight, progress) |
1825 | + } |
1826 | + |
1827 | + readonly property int animatedX: { |
1828 | + if (progress < breakPoint) { |
1829 | + return startX; |
1830 | + } |
1831 | + return MathUtils.linearAnimation(breakPoint, 1, startX, targetX, progress) |
1832 | + } |
1833 | + |
1834 | + readonly property int animatedY: progress < breakPoint ? startY : MathUtils.linearAnimation(breakPoint, 1, startY, targetY, progress) |
1835 | + |
1836 | + readonly property real animatedAngle: progress < breakPoint ? 0 : MathUtils.linearAnimation(breakPoint, 1, 0, targetAngle, progress); |
1837 | + |
1838 | + readonly property real decorationHeight: progress < breakPoint ? 1 : MathUtils.linearAnimation(breakPoint, 1, 1, 0, progress); |
1839 | + |
1840 | + readonly property int animatedZ: { |
1841 | + if (progress < breakPoint + (1 - breakPoint) / 2) { |
1842 | + return itemIndex == 1 ? normalZ + 2 : normalZ |
1843 | + } |
1844 | + return itemIndex |
1845 | + } |
1846 | + |
1847 | + readonly property real opacityMask: itemIndex == 1 ? MathUtils.linearAnimation(0, breakPoint, 0, 1, progress) : 1 |
1848 | + |
1849 | + readonly property real animatedScale: progress < breakPoint ? 1 : MathUtils.linearAnimation(breakPoint, 1, 1, targetScale, progress) |
1850 | + |
1851 | +// readonly property bool itemVisible: true //animatedX < sceneWidth |
1852 | +} |
1853 | |
1854 | === added file 'qml/Stage/Spread/cubic-bezier.js' |
1855 | --- qml/Stage/Spread/cubic-bezier.js 1970-01-01 00:00:00 +0000 |
1856 | +++ qml/Stage/Spread/cubic-bezier.js 2016-10-11 21:49:13 +0000 |
1857 | @@ -0,0 +1,39 @@ |
1858 | +/* |
1859 | + * Copyright (C) 2016 Canonical, Ltd. |
1860 | + * |
1861 | + * This program is free software; you can redistribute it and/or modify |
1862 | + * it under the terms of the GNU General Public License as published by |
1863 | + * the Free Software Foundation; version 3. |
1864 | + * |
1865 | + * This program is distributed in the hope that it will be useful, |
1866 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1867 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1868 | + * GNU General Public License for more details. |
1869 | + * |
1870 | + * You should have received a copy of the GNU General Public License |
1871 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1872 | + */ |
1873 | + |
1874 | +//====================================\\ |
1875 | +// 13thParallel.org Beziér Curve Code \\ |
1876 | +// by Dan Pupius (www.pupius.net) \\ |
1877 | +//====================================\\ |
1878 | + |
1879 | + |
1880 | +var coord = function (x,y) { |
1881 | + if(!x) var x=0; |
1882 | + if(!y) var y=0; |
1883 | + return {x: x, y: y}; |
1884 | +} |
1885 | + |
1886 | +function B4(t) { return t*t*t } |
1887 | +function B3(t) { return 3*t*t*(1-t) } |
1888 | +function B2(t) { return 3*t*(1-t)*(1-t) } |
1889 | +function B1(t) { return (1-t)*(1-t)*(1-t) } |
1890 | + |
1891 | +var getBezier = function(percent,C1,C2,C3,C4) { |
1892 | + var pos = new coord(); |
1893 | + pos.x = C1.x*B1(percent) + C2.x*B2(percent) + C3.x*B3(percent) + C4.x*B4(percent); |
1894 | + pos.y = C1.y*B1(percent) + C2.y*B2(percent) + C3.y*B3(percent) + C4.y*B4(percent); |
1895 | + return pos; |
1896 | +} |
1897 | |
1898 | === renamed file 'qml/Stages/DesktopStage.qml' => 'qml/Stage/Stage.qml' |
1899 | --- qml/Stages/DesktopStage.qml 2016-09-07 08:36:59 +0000 |
1900 | +++ qml/Stage/Stage.qml 2016-10-11 21:49:13 +0000 |
1901 | @@ -22,75 +22,152 @@ |
1902 | import Utils 0.1 |
1903 | import Ubuntu.Gestures 0.1 |
1904 | import GlobalShortcut 1.0 |
1905 | +import GSettings 1.0 |
1906 | +import "Spread" |
1907 | +import "Spread/MathUtils.js" as MathUtils |
1908 | |
1909 | -AbstractStage { |
1910 | +FocusScope { |
1911 | id: root |
1912 | anchors.fill: parent |
1913 | - paintBackground: false |
1914 | - |
1915 | - // functions to be called from outside |
1916 | - function updateFocusedAppOrientation() { /* TODO */ } |
1917 | - function updateFocusedAppOrientationAnimated() { /* TODO */} |
1918 | - function pushRightEdge(amount) { |
1919 | - if (spread.state === "") { |
1920 | - edgeBarrier.push(amount); |
1921 | - } |
1922 | - } |
1923 | - function closeFocusedDelegate() { |
1924 | - if (priv.focusedAppDelegate && !priv.focusedAppDelegate.isDash) { |
1925 | - priv.focusedAppDelegate.close(); |
1926 | - } |
1927 | - } |
1928 | - |
1929 | - // Used by TutorialRight |
1930 | - property bool spreadShown: spread.state == "altTab" |
1931 | + |
1932 | + property QtObject applicationManager |
1933 | + property QtObject topLevelSurfaceList |
1934 | + property bool altTabPressed |
1935 | + property url background |
1936 | + property int dragAreaWidth |
1937 | + property bool interactive |
1938 | + property bool keepDashRunning: true |
1939 | + property real nativeHeight |
1940 | + property real nativeWidth |
1941 | + property QtObject orientations |
1942 | + property int shellOrientation |
1943 | + property int shellOrientationAngle |
1944 | + property bool spreadEnabled: true // If false, animations and right edge will be disabled |
1945 | + property bool suspended |
1946 | + property int leftMargin: 0 |
1947 | + property bool oskEnabled: false |
1948 | + property rect inputMethodRect |
1949 | + |
1950 | + // Configuration |
1951 | + property string mode: "staged" |
1952 | + property real leftEdgeDragProgress: 0 |
1953 | + |
1954 | + // Used by the tutorial code |
1955 | + readonly property bool spreadShown: state == "spread" |
1956 | + readonly property real rightEdgeDragProgress: rightEdgeDragArea.progress // How far left the stage has been dragged |
1957 | |
1958 | // used by the snap windows (edge maximize) feature |
1959 | readonly property alias previewRectangle: fakeRectangle |
1960 | |
1961 | - mainApp: priv.focusedAppDelegate ? priv.focusedAppDelegate.application : null |
1962 | + readonly property var mainApp: priv.focusedAppDelegate ? priv.focusedAppDelegate.application : null |
1963 | |
1964 | // application windows never rotate independently |
1965 | - mainAppWindowOrientationAngle: shellOrientationAngle |
1966 | - |
1967 | - orientationChangesEnabled: true |
1968 | - |
1969 | - |
1970 | - itemConfiningMouseCursor: !spreadShown && priv.focusedAppDelegate && priv.focusedAppDelegate.surface && |
1971 | + property int mainAppWindowOrientationAngle: shellOrientationAngle |
1972 | + |
1973 | + property bool orientationChangesEnabled: priv.focusedAppDelegate && priv.focusedAppDelegate.orientationChangesEnabled |
1974 | + |
1975 | + property int supportedOrientations: { |
1976 | + if (mainApp) { |
1977 | + switch (mode) { |
1978 | + case "staged": |
1979 | + return mainApp.supportedOrientations; |
1980 | + case "stagedWithSideStage": |
1981 | + var orientations = mainApp.supportedOrientations; |
1982 | + orientations |= Qt.LandscapeOrientation | Qt.InvertedLandscapeOrientation; |
1983 | + if (priv.sideStageItemId) { |
1984 | + // If we have a sidestage app, support Portrait orientation |
1985 | + // so that it will switch the sidestage app to mainstage on rotate to portrait |
1986 | + orientations |= Qt.PortraitOrientation|Qt.InvertedPortraitOrientation; |
1987 | + } |
1988 | + return orientations; |
1989 | + } |
1990 | + } |
1991 | + |
1992 | + return Qt.PortraitOrientation | |
1993 | + Qt.LandscapeOrientation | |
1994 | + Qt.InvertedPortraitOrientation | |
1995 | + Qt.InvertedLandscapeOrientation; |
1996 | + } |
1997 | + |
1998 | + |
1999 | + onAltTabPressedChanged: priv.goneToSpread = altTabPressed |
2000 | + |
2001 | + property Item itemConfiningMouseCursor: !spreadShown && priv.focusedAppDelegate && priv.focusedAppDelegate.surface && |
2002 | priv.focusedAppDelegate.surface.confinesMousePointer ? |
2003 | priv.focusedAppDelegate.clientAreaItem : null; |
2004 | |
2005 | + signal itemSnapshotRequested(Item item) |
2006 | + |
2007 | + // functions to be called from outside |
2008 | + function updateFocusedAppOrientation() { /* TODO */ } |
2009 | + function updateFocusedAppOrientationAnimated() { /* TODO */} |
2010 | + function pushRightEdge(amount) { |
2011 | + edgeBarrier.push(amount); |
2012 | + } |
2013 | + |
2014 | + onSpreadEnabledChanged: { |
2015 | + if (!spreadEnabled && root.state == "spread") { |
2016 | + priv.goneToSpread = false; |
2017 | + } |
2018 | + } |
2019 | + |
2020 | + GSettings { |
2021 | + id: lifecycleExceptions |
2022 | + schema.id: "com.canonical.qtmir" |
2023 | + } |
2024 | + |
2025 | + function isExemptFromLifecycle(appId) { |
2026 | + var shortAppId = appId.split('_')[0]; |
2027 | + for (var i = 0; i < lifecycleExceptions.lifecycleExemptAppids.length; i++) { |
2028 | + if (shortAppId === lifecycleExceptions.lifecycleExemptAppids[i]) { |
2029 | + return true; |
2030 | + } |
2031 | + } |
2032 | + return false; |
2033 | + } |
2034 | + |
2035 | + GlobalShortcut { |
2036 | + id: closeFocusedShortcut |
2037 | + shortcut: Qt.AltModifier|Qt.Key_F4 |
2038 | + onTriggered: { |
2039 | + if (priv.focusedAppDelegate && !priv.focusedAppDelegate.isDash) { |
2040 | + priv.focusedAppDelegate.close(); |
2041 | + } |
2042 | + } |
2043 | + } |
2044 | + |
2045 | GlobalShortcut { |
2046 | id: showSpreadShortcut |
2047 | shortcut: Qt.MetaModifier|Qt.Key_W |
2048 | - onTriggered: spread.state = "altTab" |
2049 | + onTriggered: priv.goneToSpread = true |
2050 | } |
2051 | |
2052 | GlobalShortcut { |
2053 | id: minimizeAllShortcut |
2054 | shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_D |
2055 | onTriggered: priv.minimizeAllWindows() |
2056 | + active: root.state == "windowed" |
2057 | } |
2058 | |
2059 | GlobalShortcut { |
2060 | id: maximizeWindowShortcut |
2061 | shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Up |
2062 | onTriggered: priv.focusedAppDelegate.maximize() |
2063 | - active: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.canBeMaximized |
2064 | + active: root.state == "windowed" && priv.focusedAppDelegate && priv.focusedAppDelegate.canBeMaximized |
2065 | } |
2066 | |
2067 | GlobalShortcut { |
2068 | id: maximizeWindowLeftShortcut |
2069 | shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Left |
2070 | onTriggered: priv.focusedAppDelegate.maximizeLeft() |
2071 | - active: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.canBeMaximizedLeftRight |
2072 | + active: root.state == "windowed" && priv.focusedAppDelegate && priv.focusedAppDelegate.canBeMaximizedLeftRight |
2073 | } |
2074 | |
2075 | GlobalShortcut { |
2076 | id: maximizeWindowRightShortcut |
2077 | shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Right |
2078 | onTriggered: priv.focusedAppDelegate.maximizeRight() |
2079 | - active: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.canBeMaximizedLeftRight |
2080 | + active: root.state == "windowed" && priv.focusedAppDelegate && priv.focusedAppDelegate.canBeMaximizedLeftRight |
2081 | } |
2082 | |
2083 | GlobalShortcut { |
2084 | @@ -98,7 +175,7 @@ |
2085 | shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Down |
2086 | onTriggered: priv.focusedAppDelegate.anyMaximized |
2087 | ? priv.focusedAppDelegate.restoreFromMaximized() : priv.focusedAppDelegate.minimize() |
2088 | - active: priv.focusedAppDelegate !== null |
2089 | + active: root.state == "windowed" && priv.focusedAppDelegate |
2090 | } |
2091 | |
2092 | GlobalShortcut { |
2093 | @@ -107,28 +184,17 @@ |
2094 | active: priv.focusedAppDelegate !== null |
2095 | } |
2096 | |
2097 | - Connections { |
2098 | - target: root.topLevelSurfaceList |
2099 | - onCountChanged: { |
2100 | - if (spread.state == "altTab") { |
2101 | - spread.cancel(); |
2102 | - } |
2103 | - } |
2104 | - } |
2105 | - |
2106 | QtObject { |
2107 | id: priv |
2108 | objectName: "DesktopStagePrivate" |
2109 | |
2110 | property var focusedAppDelegate: null |
2111 | - onFocusedAppDelegateChanged: { |
2112 | - if (spread.state == "altTab") { |
2113 | - spread.state = ""; |
2114 | - } |
2115 | - } |
2116 | - |
2117 | property var foregroundMaximizedAppDelegate: null // for stuff like drop shadow and focusing maximized app by clicking panel |
2118 | |
2119 | + property bool goneToSpread: false |
2120 | + property int closingIndex: -1 |
2121 | + property int animationDuration: UbuntuAnimation.FastDuration |
2122 | + |
2123 | function updateForegroundMaximizedApp() { |
2124 | var found = false; |
2125 | for (var i = 0; i < appRepeater.count && !found; i++) { |
2126 | @@ -162,11 +228,93 @@ |
2127 | } |
2128 | } |
2129 | |
2130 | - readonly property real virtualKeyboardHeight: SurfaceManager.inputMethodSurface |
2131 | - ? SurfaceManager.inputMethodSurface.inputBounds.height |
2132 | - : 0 |
2133 | + readonly property bool sideStageEnabled: root.mode === "stagedWithSideStage" && |
2134 | + (root.shellOrientation == Qt.LandscapeOrientation || |
2135 | + root.shellOrientation == Qt.InvertedLandscapeOrientation) |
2136 | + |
2137 | + property var mainStageDelegate: null |
2138 | + property var sideStageDelegate: null |
2139 | + property int mainStageItemId: 0 |
2140 | + property int sideStageItemId: 0 |
2141 | + property string mainStageAppId: "" |
2142 | + property string sideStageAppId: "" |
2143 | + |
2144 | + onSideStageDelegateChanged: { |
2145 | + if (!sideStageDelegate) { |
2146 | + sideStage.hide(); |
2147 | + } |
2148 | + } |
2149 | + |
2150 | + function updateMainAndSideStageIndexes() { |
2151 | + if (root.mode != "stagedWithSideStage") { |
2152 | + priv.sideStageDelegate = null; |
2153 | + priv.sideStageItemId = 0; |
2154 | + priv.sideStageAppId = ""; |
2155 | + priv.mainStageDelegate = appRepeater.itemAt(0); |
2156 | + priv.mainStageAppId = topLevelSurfaceList.idAt(0); |
2157 | + priv.mainStageAppId = topLevelSurfaceList.applicationAt(0) ? topLevelSurfaceList.applicationAt(0).appId : "" |
2158 | + return; |
2159 | + } |
2160 | + |
2161 | + var choseMainStage = false; |
2162 | + var choseSideStage = false; |
2163 | + |
2164 | + if (!root.topLevelSurfaceList) |
2165 | + return; |
2166 | + |
2167 | + for (var i = 0; i < appRepeater.count && (!choseMainStage || !choseSideStage); ++i) { |
2168 | + var appDelegate = appRepeater.itemAt(i); |
2169 | + if (!appDelegate) { |
2170 | + // This might happen during startup phase... If the delegate appears and claims focus |
2171 | + // things are updated and appRepeater.itemAt(x) still returns null while appRepeater.count >= x |
2172 | + // Lets just skip it, on startup it will be generated at a later point too... |
2173 | + continue; |
2174 | + } |
2175 | + if (sideStage.shown && appDelegate.stage == ApplicationInfoInterface.SideStage |
2176 | + && !choseSideStage) { |
2177 | + priv.sideStageDelegate = appDelegate |
2178 | + priv.sideStageItemId = root.topLevelSurfaceList.idAt(i); |
2179 | + priv.sideStageAppId = root.topLevelSurfaceList.applicationAt(i).appId; |
2180 | + choseSideStage = true; |
2181 | + } else if (!choseMainStage && appDelegate.stage == ApplicationInfoInterface.MainStage) { |
2182 | + priv.mainStageDelegate = appDelegate; |
2183 | + priv.mainStageItemId = root.topLevelSurfaceList.idAt(i); |
2184 | + priv.mainStageAppId = root.topLevelSurfaceList.applicationAt(i).appId; |
2185 | + choseMainStage = true; |
2186 | + } |
2187 | + } |
2188 | + if (!choseMainStage && priv.mainStageDelegate) { |
2189 | + priv.mainStageDelegate = null; |
2190 | + priv.mainStageItemId = 0; |
2191 | + priv.mainStageAppId = ""; |
2192 | + } |
2193 | + if (!choseSideStage && priv.sideStageDelegate) { |
2194 | + priv.sideStageDelegate = null; |
2195 | + priv.sideStageItemId = 0; |
2196 | + priv.sideStageAppId = ""; |
2197 | + } |
2198 | + } |
2199 | + |
2200 | + property int nextInStack: { |
2201 | + var mainStageIndex = priv.mainStageDelegate ? priv.mainStageDelegate.itemIndex : -1; |
2202 | + var sideStageIndex = priv.sideStageDelegate ? priv.sideStageDelegate.itemIndex : -1; |
2203 | + if (sideStageIndex == -1) { |
2204 | + return topLevelSurfaceList.count > 1 ? 1 : -1; |
2205 | + } |
2206 | + if (mainStageIndex == 0 || sideStageIndex == 0) { |
2207 | + if (mainStageIndex == 1 || sideStageIndex == 1) { |
2208 | + return topLevelSurfaceList.count > 2 ? 2 : -1; |
2209 | + } |
2210 | + return 1; |
2211 | + } |
2212 | + return -1; |
2213 | + } |
2214 | + |
2215 | + readonly property real virtualKeyboardHeight: root.inputMethodRect.height |
2216 | } |
2217 | |
2218 | + Component.onCompleted: priv.updateMainAndSideStageIndexes(); |
2219 | + |
2220 | Connections { |
2221 | target: PanelState |
2222 | onCloseClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } } |
2223 | @@ -178,14 +326,13 @@ |
2224 | target: PanelState |
2225 | property: "buttonsVisible" |
2226 | value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized // FIXME for Locally integrated menus |
2227 | - && spread.state == "" |
2228 | } |
2229 | |
2230 | Binding { |
2231 | target: PanelState |
2232 | property: "title" |
2233 | value: { |
2234 | - if (priv.focusedAppDelegate !== null && spread.state == "") { |
2235 | + if (priv.focusedAppDelegate !== null) { |
2236 | if (priv.focusedAppDelegate.maximized) |
2237 | return priv.focusedAppDelegate.title |
2238 | else |
2239 | @@ -199,7 +346,7 @@ |
2240 | Binding { |
2241 | target: PanelState |
2242 | property: "dropShadow" |
2243 | - value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppDelegate !== null |
2244 | + value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppDelegate !== null && mode == "windowed" |
2245 | } |
2246 | |
2247 | Binding { |
2248 | @@ -216,16 +363,34 @@ |
2249 | |
2250 | Instantiator { |
2251 | model: root.applicationManager |
2252 | - delegate: Binding { |
2253 | - target: model.application |
2254 | - property: "requestedState" |
2255 | - |
2256 | - // TODO: figure out some lifecycle policy, like suspending minimized apps |
2257 | - // if running on a tablet or something. |
2258 | - // TODO: If the device has a dozen suspended apps because it was running |
2259 | - // in staged mode, when it switches to Windowed mode it will suddenly |
2260 | - // resume all those apps at once. We might want to avoid that. |
2261 | - value: ApplicationInfoInterface.RequestedRunning // Always running for now |
2262 | + delegate: QtObject { |
2263 | + property var stateBinding: Binding { |
2264 | + readonly property bool isDash: model.application ? model.application.appId == "unity8-dash" : false |
2265 | + target: model.application |
2266 | + property: "requestedState" |
2267 | + |
2268 | + // TODO: figure out some lifecycle policy, like suspending minimized apps |
2269 | + // or something if running windowed. |
2270 | + // TODO: If the device has a dozen suspended apps because it was running |
2271 | + // in staged mode, when it switches to Windowed mode it will suddenly |
2272 | + // resume all those apps at once. We might want to avoid that. |
2273 | + value: root.mode === "windowed" |
2274 | + || (isDash && root.keepDashRunning) |
2275 | + || (!root.suspended && model.application && priv.focusedAppDelegate && |
2276 | + (priv.focusedAppDelegate.appId === model.application.appId || |
2277 | + priv.mainStageAppId === model.application.appId || |
2278 | + priv.sideStageAppId === model.application.appId)) |
2279 | + ? ApplicationInfoInterface.RequestedRunning |
2280 | + : ApplicationInfoInterface.RequestedSuspended |
2281 | + } |
2282 | + |
2283 | + property var lifecycleBinding: Binding { |
2284 | + target: model.application |
2285 | + property: "exemptFromLifecycle" |
2286 | + value: model.application |
2287 | + ? (!model.application.isTouchApp || isExemptFromLifecycle(model.application.appId)) |
2288 | + : false |
2289 | + } |
2290 | } |
2291 | } |
2292 | |
2293 | @@ -236,16 +401,203 @@ |
2294 | when: !appRepeater.startingUp && root.parent |
2295 | } |
2296 | |
2297 | + states: [ |
2298 | + State { |
2299 | + name: "spread"; when: priv.goneToSpread |
2300 | + PropertyChanges { target: floatingFlickable; enabled: true } |
2301 | + PropertyChanges { target: spreadItem; focus: true } |
2302 | + PropertyChanges { target: hoverMouseArea; enabled: true } |
2303 | + PropertyChanges { target: rightEdgeDragArea; enabled: false } |
2304 | + PropertyChanges { target: cancelSpreadMouseArea; enabled: true } |
2305 | + }, |
2306 | + State { |
2307 | + name: "stagedRightEdge"; when: (rightEdgeDragArea.dragging || edgeBarrier.progress > 0) && root.mode == "staged" |
2308 | + }, |
2309 | + State { |
2310 | + name: "sideStagedRightEdge"; when: (rightEdgeDragArea.dragging || edgeBarrier.progress > 0) && root.mode == "stagedWithSideStage" |
2311 | + PropertyChanges { |
2312 | + target: sideStage |
2313 | + opacity: priv.sideStageDelegate.x === sideStage.x ? 1 : 0 |
2314 | + visible: true |
2315 | + } |
2316 | + }, |
2317 | + State { |
2318 | + name: "windowedRightEdge"; when: (rightEdgeDragArea.dragging || edgeBarrier.progress > 0) && root.mode == "windowed" |
2319 | + }, |
2320 | + State { |
2321 | + name: "staged"; when: root.mode === "staged" |
2322 | + }, |
2323 | + State { |
2324 | + name: "stagedWithSideStage"; when: root.mode === "stagedWithSideStage" |
2325 | + PropertyChanges { target: triGestureArea; enabled: true } |
2326 | + PropertyChanges { target: sideStage; visible: true } |
2327 | + }, |
2328 | + State { |
2329 | + name: "windowed"; when: root.mode === "windowed" |
2330 | + } |
2331 | + ] |
2332 | + transitions: [ |
2333 | + Transition { |
2334 | + from: "stagedRightEdge,sideStagedRightEdge,windowedRightEdge"; to: "spread" |
2335 | + PropertyAction { target: spreadItem; property: "highlightedIndex"; value: -1 } |
2336 | + }, |
2337 | + Transition { |
2338 | + to: "spread" |
2339 | + PropertyAction { target: spreadItem; property: "highlightedIndex"; value: appRepeater.count > 1 ? 1 : 0 } |
2340 | + PropertyAction { target: floatingFlickable; property: "contentX"; value: 0 } |
2341 | + }, |
2342 | + Transition { |
2343 | + from: "spread" |
2344 | + SequentialAnimation { |
2345 | + ScriptAction { |
2346 | + script: { |
2347 | + var item = appRepeater.itemAt(Math.max(0, spreadItem.highlightedIndex)); |
2348 | + if (item.stage == ApplicationInfoInterface.SideStage && !sideStage.shown) { |
2349 | + sideStage.show(); |
2350 | + } |
2351 | + item.playFocusAnimation(); |
2352 | + } |
2353 | + } |
2354 | + PropertyAction { target: spreadItem; property: "highlightedIndex"; value: -1 } |
2355 | + } |
2356 | + }, |
2357 | + Transition { |
2358 | + to: "stagedRightEdge" |
2359 | + PropertyAction { target: floatingFlickable; property: "contentX"; value: 0 } |
2360 | + }, |
2361 | + Transition { |
2362 | + to: "stagedWithSideStage" |
2363 | + ScriptAction { script: priv.updateMainAndSideStageIndexes(); } |
2364 | + } |
2365 | + |
2366 | + ] |
2367 | + |
2368 | + MouseArea { |
2369 | + id: cancelSpreadMouseArea |
2370 | + anchors.fill: parent |
2371 | + enabled: false |
2372 | + onClicked: priv.goneToSpread = false |
2373 | + } |
2374 | + |
2375 | FocusScope { |
2376 | id: appContainer |
2377 | objectName: "appContainer" |
2378 | anchors.fill: parent |
2379 | - focus: spread.state !== "altTab" |
2380 | + focus: true |
2381 | |
2382 | Wallpaper { |
2383 | id: wallpaper |
2384 | anchors.fill: parent |
2385 | source: root.background |
2386 | + // Make sure it's the lowest item. Due to the left edge drag we sometimes need |
2387 | + // to put the dash at -1 and we don't want it behind the Wallpaper |
2388 | + z: -2 |
2389 | + } |
2390 | + |
2391 | + Spread { |
2392 | + id: spreadItem |
2393 | + objectName: "spreadItem" |
2394 | + anchors.fill: appContainer |
2395 | + leftMargin: root.leftMargin |
2396 | + model: root.topLevelSurfaceList |
2397 | + spreadFlickable: floatingFlickable |
2398 | + z: 10 |
2399 | + |
2400 | + onLeaveSpread: { |
2401 | + priv.goneToSpread = false; |
2402 | + } |
2403 | + } |
2404 | + |
2405 | + Connections { |
2406 | + target: root.topLevelSurfaceList |
2407 | + onListChanged: priv.updateMainAndSideStageIndexes() |
2408 | + } |
2409 | + |
2410 | + |
2411 | + DropArea { |
2412 | + objectName: "MainStageDropArea" |
2413 | + anchors { |
2414 | + left: parent.left |
2415 | + top: parent.top |
2416 | + bottom: parent.bottom |
2417 | + } |
2418 | + width: appContainer.width - sideStage.width |
2419 | + enabled: sideStage.enabled |
2420 | + |
2421 | + onDropped: { |
2422 | + drop.source.appDelegate.saveStage(ApplicationInfoInterface.MainStage); |
2423 | + drop.source.appDelegate.focus = true; |
2424 | + } |
2425 | + keys: "SideStage" |
2426 | + } |
2427 | + |
2428 | + SideStage { |
2429 | + id: sideStage |
2430 | + objectName: "sideStage" |
2431 | + shown: false |
2432 | + height: appContainer.height |
2433 | + x: appContainer.width - width |
2434 | + visible: false |
2435 | + Behavior on opacity { UbuntuNumberAnimation {} } |
2436 | + z: { |
2437 | + if (!priv.mainStageItemId) return 0; |
2438 | + |
2439 | + if (priv.sideStageItemId && priv.nextInStack > 0) { |
2440 | + |
2441 | + // Due the order in which bindings are evaluated, this might be triggered while shuffling |
2442 | + // the list and index doesn't yet match with itemIndex (even though itemIndex: index) |
2443 | + // Let's walk the list and compare itemIndex to make sure we have the correct one. |
2444 | + var nextDelegateInStack = -1; |
2445 | + for (var i = 0; i < appRepeater.count; i++) { |
2446 | + if (appRepeater.itemAt(i).itemIndex == priv.nextInStack) { |
2447 | + nextDelegateInStack = appRepeater.itemAt(i); |
2448 | + break; |
2449 | + } |
2450 | + } |
2451 | + |
2452 | + if (nextDelegateInStack.stage === ApplicationInfoInterface.MainStage) { |
2453 | + // if the next app in stack is a main stage app, put the sidestage on top of it. |
2454 | + return 2; |
2455 | + } |
2456 | + return 1; |
2457 | + } |
2458 | + |
2459 | + return 1; |
2460 | + } |
2461 | + |
2462 | + onShownChanged: { |
2463 | + if (!shown && priv.mainStageDelegate) { |
2464 | + priv.mainStageDelegate.claimFocus(); |
2465 | + } |
2466 | + } |
2467 | + |
2468 | + DropArea { |
2469 | + id: sideStageDropArea |
2470 | + objectName: "SideStageDropArea" |
2471 | + anchors.fill: parent |
2472 | + |
2473 | + property bool dropAllowed: true |
2474 | + |
2475 | + onEntered: { |
2476 | + dropAllowed = drag.keys != "Disabled"; |
2477 | + } |
2478 | + onExited: { |
2479 | + dropAllowed = true; |
2480 | + } |
2481 | + onDropped: { |
2482 | + if (drop.keys == "MainStage") { |
2483 | + drop.source.appDelegate.saveStage(ApplicationInfoInterface.SideStage); |
2484 | + drop.source.appDelegate.focus = true; |
2485 | + } |
2486 | + } |
2487 | + drag { |
2488 | + onSourceChanged: { |
2489 | + if (!sideStageDropArea.drag.source) { |
2490 | + dropAllowed = true; |
2491 | + } |
2492 | + } |
2493 | + } |
2494 | + } |
2495 | } |
2496 | |
2497 | TopLevelSurfaceRepeater { |
2498 | @@ -256,6 +608,7 @@ |
2499 | delegate: FocusScope { |
2500 | id: appDelegate |
2501 | objectName: "appDelegate_" + model.id |
2502 | + property int itemIndex: index // We need this from outside the repeater |
2503 | // z might be overriden in some cases by effects, but we need z ordering |
2504 | // to calculate occlusion detection |
2505 | property int normalZ: topLevelSurfaceList.count - index |
2506 | @@ -265,10 +618,33 @@ |
2507 | } |
2508 | } |
2509 | z: normalZ |
2510 | - x: requestedX // may be overridden in some states. Do not directly write to this. |
2511 | - y: requestedY // may be overridden in some states. Do not directly write to this. |
2512 | - property real requestedX: priv.focusedAppDelegate ? priv.focusedAppDelegate.x + units.gu(3) : (normalZ - 1) * units.gu(3) |
2513 | - property real requestedY: priv.focusedAppDelegate ? priv.focusedAppDelegate.y + units.gu(3) : normalZ * units.gu(3) |
2514 | + |
2515 | + // Normally we want x/y where we request it to be. Width/height of our delegate will |
2516 | + // match what the actual surface size is. |
2517 | + // Don't write to those, they will be set by states |
2518 | + x: requestedX |
2519 | + y: requestedY |
2520 | + width: decoratedWindow.implicitWidth |
2521 | + height: decoratedWindow.implicitHeight |
2522 | + |
2523 | + // requestedX/Y/width/height is what we ask the actual surface to be. |
2524 | + // Do not write to those, they will be set by states |
2525 | + property real requestedX: windowedX |
2526 | + property real requestedY: windowedY |
2527 | + property real requestedWidth: windowedWidth |
2528 | + property real requestedHeight: windowedHeight |
2529 | + |
2530 | + // In those are for windowed mode. Those values basically store the window's properties |
2531 | + // when having a floating window. If you want to move/resize a window in normal mode, this is what you want to write to. |
2532 | + property real windowedX |
2533 | + property real windowedY |
2534 | + property real windowedWidth |
2535 | + property real windowedHeight |
2536 | + |
2537 | + // unlike windowedX/Y, this is the last known grab position before being pushed against edges/corners |
2538 | + // when restoring, the window should return to these, not to the place where it was dropped near the edge |
2539 | + property real restoredX |
2540 | + property real restoredY |
2541 | |
2542 | Binding { |
2543 | target: appDelegate |
2544 | @@ -277,27 +653,24 @@ |
2545 | Math.min(appDelegate.requestedY - PanelState.panelHeight, |
2546 | Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height)))) |
2547 | when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored") |
2548 | - && SurfaceManager.inputMethodSurface |
2549 | - && SurfaceManager.inputMethodSurface.state != Mir.HiddenState |
2550 | - && SurfaceManager.inputMethodSurface.state != Mir.MinimizedState |
2551 | + && root.inputMethodRect.height > 0 |
2552 | |
2553 | } |
2554 | |
2555 | - width: decoratedWindow.width |
2556 | - height: decoratedWindow.height |
2557 | + Behavior on x { id: xBehavior; enabled: priv.closingIndex >= 0; UbuntuNumberAnimation { onRunningChanged: if (!running) priv.closingIndex = -1} } |
2558 | |
2559 | Connections { |
2560 | target: root |
2561 | onShellOrientationAngleChanged: { |
2562 | // at this point decoratedWindow.surfaceOrientationAngle is the old shellOrientationAngle |
2563 | if (application && application.rotatesWindowContents) { |
2564 | - if (state == "normal" || state == "restored") { |
2565 | + if (root.state == "windowed") { |
2566 | var angleDiff = decoratedWindow.surfaceOrientationAngle - shellOrientationAngle; |
2567 | angleDiff = (360 + angleDiff) % 360; |
2568 | if (angleDiff === 90 || angleDiff === 270) { |
2569 | var aux = decoratedWindow.requestedHeight; |
2570 | - decoratedWindow.requestedHeight = decoratedWindow.requestedWidth + decoratedWindow.visibleDecorationHeight; |
2571 | - decoratedWindow.requestedWidth = aux - decoratedWindow.visibleDecorationHeight; |
2572 | + decoratedWindow.requestedHeight = decoratedWindow.requestedWidth + decoratedWindow.decorationHeight; |
2573 | + decoratedWindow.requestedWidth = aux - decoratedWindow.decorationHeight; |
2574 | } |
2575 | } |
2576 | decoratedWindow.surfaceOrientationAngle = shellOrientationAngle; |
2577 | @@ -306,6 +679,10 @@ |
2578 | } |
2579 | } |
2580 | } |
2581 | + Connections { |
2582 | + target: priv |
2583 | + onSideStageEnabledChanged: refreshStage() |
2584 | + } |
2585 | |
2586 | readonly property alias application: decoratedWindow.application |
2587 | readonly property alias minimumWidth: decoratedWindow.minimumWidth |
2588 | @@ -314,8 +691,6 @@ |
2589 | readonly property alias maximumHeight: decoratedWindow.maximumHeight |
2590 | readonly property alias widthIncrement: decoratedWindow.widthIncrement |
2591 | readonly property alias heightIncrement: decoratedWindow.heightIncrement |
2592 | - property int requestedWidth: -1 |
2593 | - property int requestedHeight: -1 |
2594 | |
2595 | readonly property bool maximized: windowState === WindowStateStorage.WindowStateMaximized |
2596 | readonly property bool maximizedLeft: windowState === WindowStateStorage.WindowStateMaximizedLeft |
2597 | @@ -330,7 +705,7 @@ |
2598 | maximizedTopLeft || maximizedTopRight || maximizedBottomLeft || maximizedBottomRight |
2599 | |
2600 | readonly property bool minimized: windowState & WindowStateStorage.WindowStateMinimized |
2601 | - readonly property alias fullscreen: decoratedWindow.fullscreen |
2602 | + readonly property bool fullscreen: surface ? surface.state === Mir.FullscreenState : application.fullscreen |
2603 | |
2604 | readonly property bool canBeMaximized: canBeMaximizedHorizontally && canBeMaximizedVertically |
2605 | readonly property bool canBeMaximizedLeftRight: (maximumWidth == 0 || maximumWidth >= appContainer.width/2) && |
2606 | @@ -339,6 +714,7 @@ |
2607 | (maximumHeight == 0 || maximumHeight >= appContainer.height/2) |
2608 | readonly property bool canBeMaximizedHorizontally: maximumWidth == 0 || maximumWidth >= appContainer.width |
2609 | readonly property bool canBeMaximizedVertically: maximumHeight == 0 || maximumHeight >= appContainer.height |
2610 | + readonly property alias orientationChangesEnabled: decoratedWindow.orientationChangesEnabled |
2611 | |
2612 | property int windowState: WindowStateStorage.WindowStateNormal |
2613 | property bool animationsEnabled: true |
2614 | @@ -347,23 +723,45 @@ |
2615 | property bool visuallyMaximized: false |
2616 | property bool visuallyMinimized: false |
2617 | |
2618 | + property int stage: ApplicationInfoInterface.MainStage |
2619 | + function saveStage(newStage) { |
2620 | + appDelegate.stage = newStage; |
2621 | + WindowStateStorage.saveStage(appId, newStage); |
2622 | + priv.updateMainAndSideStageIndexes() |
2623 | + } |
2624 | + |
2625 | readonly property var surface: model.surface |
2626 | readonly property alias resizeArea: resizeArea |
2627 | readonly property alias focusedSurface: decoratedWindow.focusedSurface |
2628 | readonly property bool dragging: touchControls.overlayShown ? touchControls.dragging : decoratedWindow.dragging |
2629 | |
2630 | - readonly property bool isDash: model.application.appId == "unity8-dash" |
2631 | + readonly property string appId: model.application.appId |
2632 | + readonly property bool isDash: appId == "unity8-dash" |
2633 | readonly property alias clientAreaItem: decoratedWindow.clientAreaItem |
2634 | |
2635 | function claimFocus() { |
2636 | - if (spread.state == "altTab") { |
2637 | - spread.cancel(); |
2638 | - } |
2639 | - appDelegate.restore(true /* animated */, appDelegate.windowState); |
2640 | + if (root.state == "spread") { |
2641 | + spreadItem.highlightedIndex = index |
2642 | + priv.goneToSpread = false; |
2643 | + } |
2644 | + if (root.mode == "stagedWithSideStage") { |
2645 | + if (appDelegate.stage == ApplicationInfoInterface.SideStage && !sideStage.shown) { |
2646 | + sideStage.show(); |
2647 | + } |
2648 | + priv.updateMainAndSideStageIndexes(); |
2649 | + } |
2650 | + |
2651 | + if (root.mode == "windowed") { |
2652 | + appDelegate.restore(true /* animated */, appDelegate.windowState); |
2653 | + } else { |
2654 | + appDelegate.focus = true; |
2655 | + } |
2656 | } |
2657 | Connections { |
2658 | target: model.surface |
2659 | - onFocusRequested: claimFocus(); |
2660 | + onFocusRequested: { |
2661 | + claimFocus(); |
2662 | + } |
2663 | } |
2664 | Connections { |
2665 | target: model.application |
2666 | @@ -383,14 +781,9 @@ |
2667 | return; |
2668 | |
2669 | if (focus) { |
2670 | - // If we're orphan (!parent) it means this stage is no longer the current one |
2671 | - // and will be deleted shortly. So we should no longer have a say over the model |
2672 | - if (root.parent) { |
2673 | - topLevelSurfaceList.raiseId(model.id); |
2674 | - } |
2675 | - |
2676 | + topLevelSurfaceList.raiseId(model.id); |
2677 | priv.focusedAppDelegate = appDelegate; |
2678 | - } else if (!focus && priv.focusedAppDelegate === appDelegate) { |
2679 | + } else if (!focus && priv.focusedAppDelegate === appDelegate && root.state != "spread") { |
2680 | priv.focusedAppDelegate = null; |
2681 | // FIXME: No idea why the Binding{} doens't update when focusedAppDelegate turns null |
2682 | MirFocusController.focusedSurface = null; |
2683 | @@ -403,13 +796,25 @@ |
2684 | decoratedWindow.surfaceOrientationAngle = 0; |
2685 | } |
2686 | |
2687 | + // First, cascade the newly created window, relative to the currently/old focused window. |
2688 | + windowedX = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedX + units.gu(3) : (normalZ - 1) * units.gu(3) |
2689 | + windowedY = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedY + units.gu(3) : normalZ * units.gu(3) |
2690 | + // Now load any saved state. This needs to happen *after* the cascading! |
2691 | + resizeArea.loadWindowState(); |
2692 | + |
2693 | // NB: We're differentiating if this delegate was created in response to a new entry in the model |
2694 | // or if the Repeater is just populating itself with delegates to match the model it received. |
2695 | if (!appRepeater.startingUp) { |
2696 | // a top level window is always the focused one when it first appears, unfocusing |
2697 | // any preexisting one |
2698 | - focus = true; |
2699 | + if (root.state == "spread") { |
2700 | + spreadItem.highlightedIndex = index; |
2701 | + } |
2702 | + claimFocus(); |
2703 | } |
2704 | + |
2705 | + refreshStage(); |
2706 | + _constructing = false; |
2707 | } |
2708 | Component.onDestruction: { |
2709 | if (!root.parent) { |
2710 | @@ -435,13 +840,20 @@ |
2711 | |
2712 | onVisuallyMaximizedChanged: priv.updateForegroundMaximizedApp() |
2713 | |
2714 | + property bool _constructing: true; |
2715 | + onStageChanged: { |
2716 | + if (!_constructing) { |
2717 | + priv.updateMainAndSideStageIndexes(); |
2718 | + } |
2719 | + } |
2720 | + |
2721 | visible: ( |
2722 | !visuallyMinimized |
2723 | && !greeter.fullyShown |
2724 | && (priv.foregroundMaximizedAppDelegate === null || priv.foregroundMaximizedAppDelegate.normalZ <= z) |
2725 | ) |
2726 | - || decoratedWindow.fullscreen |
2727 | - || (spread.state == "altTab" && index === spread.highlightedIndex) |
2728 | + || appDelegate.fullscreen |
2729 | + || focusAnimation.running || rightEdgeFocusAnimation.running || hidingAnimation.running |
2730 | |
2731 | function close() { |
2732 | model.surface.close(); |
2733 | @@ -499,7 +911,44 @@ |
2734 | } |
2735 | |
2736 | function playFocusAnimation() { |
2737 | - focusAnimation.start() |
2738 | + if (state == "stagedRightEdge") { |
2739 | + // TODO: Can we drop this if and find something that always works? |
2740 | + if (root.mode == "staged") { |
2741 | + rightEdgeFocusAnimation.targetX = 0 |
2742 | + rightEdgeFocusAnimation.start() |
2743 | + } else if (root.mode == "stagedWithSideStage") { |
2744 | + rightEdgeFocusAnimation.targetX = appDelegate.stage == ApplicationInfoInterface.SideStage ? sideStage.x : 0 |
2745 | + rightEdgeFocusAnimation.start() |
2746 | + } |
2747 | + } else if (state == "windowedRightEdge" || state == "windowed") { |
2748 | + claimFocus(); |
2749 | + } else { |
2750 | + focusAnimation.start() |
2751 | + } |
2752 | + } |
2753 | + function playHidingAnimation() { |
2754 | + if (state != "windowedRightEdge") { |
2755 | + hidingAnimation.start() |
2756 | + } |
2757 | + } |
2758 | + |
2759 | + function refreshStage() { |
2760 | + var newStage = ApplicationInfoInterface.MainStage; |
2761 | + if (priv.sideStageEnabled) { // we're in lanscape rotation. |
2762 | + if (!isDash && application && application.supportedOrientations & (Qt.PortraitOrientation|Qt.InvertedPortraitOrientation)) { |
2763 | + var defaultStage = ApplicationInfoInterface.SideStage; // if application supports portrait, it defaults to sidestage. |
2764 | + if (application.supportedOrientations & (Qt.LandscapeOrientation|Qt.InvertedLandscapeOrientation)) { |
2765 | + // if it supports lanscape, it defaults to mainstage. |
2766 | + defaultStage = ApplicationInfoInterface.MainStage; |
2767 | + } |
2768 | + newStage = WindowStateStorage.getStage(application.appId, defaultStage); |
2769 | + } |
2770 | + } |
2771 | + |
2772 | + stage = newStage; |
2773 | + if (focus && stage == ApplicationInfoInterface.SideStage && !sideStage.shown) { |
2774 | + sideStage.show(); |
2775 | + } |
2776 | } |
2777 | |
2778 | UbuntuNumberAnimation { |
2779 | @@ -509,32 +958,255 @@ |
2780 | from: 0.98 |
2781 | to: 1 |
2782 | duration: UbuntuAnimation.SnapDuration |
2783 | - } |
2784 | - |
2785 | - // unlike requestedX/Y, this is the last known grab position before being pushed against edges/corners |
2786 | - // when restoring, the window should return to these, not to the place where it was dropped near the edge |
2787 | - property real restoredX |
2788 | - property real restoredY |
2789 | + onStarted: { |
2790 | + topLevelSurfaceList.raiseId(model.id); |
2791 | + } |
2792 | + onStopped: { |
2793 | + appDelegate.claimFocus(); |
2794 | + } |
2795 | + } |
2796 | + ParallelAnimation { |
2797 | + id: rightEdgeFocusAnimation |
2798 | + property int targetX: 0 |
2799 | + UbuntuNumberAnimation { target: appDelegate; properties: "x"; to: rightEdgeFocusAnimation.targetX; duration: priv.animationDuration } |
2800 | + UbuntuNumberAnimation { target: decoratedWindow; properties: "angle"; to: 0; duration: priv.animationDuration } |
2801 | + UbuntuNumberAnimation { target: decoratedWindow; properties: "itemScale"; to: 1; duration: priv.animationDuration } |
2802 | + onStopped: { |
2803 | + appDelegate.focus = true |
2804 | + } |
2805 | + } |
2806 | + ParallelAnimation { |
2807 | + id: hidingAnimation |
2808 | + UbuntuNumberAnimation { target: appDelegate; property: "opacity"; to: 0; duration: priv.animationDuration } |
2809 | + onStopped: appDelegate.opacity = 1 |
2810 | + } |
2811 | + |
2812 | + SpreadMaths { |
2813 | + id: spreadMaths |
2814 | + spread: spreadItem |
2815 | + itemIndex: index |
2816 | + flickable: floatingFlickable |
2817 | + } |
2818 | + StageMaths { |
2819 | + id: stageMaths |
2820 | + sceneWidth: root.width |
2821 | + stage: appDelegate.stage |
2822 | + thisDelegate: appDelegate |
2823 | + mainStageDelegate: priv.mainStageDelegate |
2824 | + sideStageDelegate: priv.sideStageDelegate |
2825 | + sideStageWidth: sideStage.panelWidth |
2826 | + sideStageX: sideStage.x |
2827 | + itemIndex: appDelegate.itemIndex |
2828 | + nextInStack: priv.nextInStack |
2829 | + leftEdgeDragProgress: root.leftEdgeDragProgress |
2830 | + } |
2831 | + |
2832 | + StagedRightEdgeMaths { |
2833 | + id: stagedRightEdgeMaths |
2834 | + sceneWidth: appContainer.width - root.leftMargin |
2835 | + sceneHeight: appContainer.height |
2836 | + isMainStageApp: priv.mainStageDelegate == appDelegate |
2837 | + isSideStageApp: priv.sideStageDelegate == appDelegate |
2838 | + sideStageWidth: sideStage.width |
2839 | + sideStageOpen: sideStage.shown |
2840 | + itemIndex: index |
2841 | + nextInStack: priv.nextInStack |
2842 | + progress: 0 |
2843 | + targetHeight: spreadItem.stackHeight |
2844 | + targetX: spreadMaths.targetX |
2845 | + startY: appDelegate.fullscreen ? 0 : PanelState.panelHeight |
2846 | + targetY: spreadMaths.targetY |
2847 | + targetAngle: spreadMaths.targetAngle |
2848 | + targetScale: spreadMaths.targetScale |
2849 | + shuffledZ: stageMaths.itemZ |
2850 | + breakPoint: spreadItem.rightEdgeBreakPoint |
2851 | + } |
2852 | + |
2853 | + WindowedRightEdgeMaths { |
2854 | + id: windowedRightEdgeMaths |
2855 | + itemIndex: index |
2856 | + startWidth: appDelegate.requestedWidth |
2857 | + startHeight: appDelegate.requestedHeight |
2858 | + targetHeight: spreadItem.stackHeight |
2859 | + targetX: spreadMaths.targetX |
2860 | + targetY: spreadMaths.targetY |
2861 | + normalZ: appDelegate.normalZ |
2862 | + targetAngle: spreadMaths.targetAngle |
2863 | + targetScale: spreadMaths.targetScale |
2864 | + breakPoint: spreadItem.rightEdgeBreakPoint |
2865 | + } |
2866 | |
2867 | states: [ |
2868 | State { |
2869 | + name: "spread"; when: root.state == "spread" |
2870 | + PropertyChanges { |
2871 | + target: decoratedWindow; |
2872 | + showDecoration: false; |
2873 | + angle: spreadMaths.targetAngle |
2874 | + itemScale: spreadMaths.targetScale |
2875 | + scaleToPreviewSize: spreadItem.stackHeight |
2876 | + scaleToPreviewProgress: 1 |
2877 | + hasDecoration: root.mode === "windowed" |
2878 | + shadowOpacity: spreadMaths.shadowOpacity |
2879 | + showHighlight: spreadItem.highlightedIndex === index |
2880 | + darkening: spreadItem.highlightedIndex >= 0 |
2881 | + anchors.topMargin: dragArea.distance |
2882 | + } |
2883 | + PropertyChanges { |
2884 | + target: appDelegate |
2885 | + x: spreadMaths.targetX |
2886 | + y: spreadMaths.targetY |
2887 | + z: index |
2888 | + height: spreadItem.spreadItemHeight |
2889 | + requestedWidth: decoratedWindow.oldRequestedWidth |
2890 | + requestedHeight: decoratedWindow.oldRequestedHeight |
2891 | + visible: spreadMaths.itemVisible |
2892 | + } |
2893 | + PropertyChanges { target: dragArea; enabled: true } |
2894 | + PropertyChanges { target: windowInfoItem; opacity: spreadMaths.tileInfoOpacity; visible: spreadMaths.itemVisible } |
2895 | + }, |
2896 | + State { |
2897 | + name: "stagedRightEdge" |
2898 | + when: (root.mode == "staged" || root.mode == "stagedWithSideStage") && (root.state == "sideStagedRightEdge" || root.state == "stagedRightEdge" || rightEdgeFocusAnimation.running || hidingAnimation.running) |
2899 | + PropertyChanges { |
2900 | + target: stagedRightEdgeMaths |
2901 | + progress: Math.max(edgeBarrier.progress, rightEdgeDragArea.draggedProgress) |
2902 | + } |
2903 | + PropertyChanges { |
2904 | + target: appDelegate |
2905 | + x: stagedRightEdgeMaths.animatedX |
2906 | + y: stagedRightEdgeMaths.animatedY |
2907 | + z: stagedRightEdgeMaths.animatedZ |
2908 | + height: stagedRightEdgeMaths.animatedHeight |
2909 | + requestedWidth: decoratedWindow.oldRequestedWidth |
2910 | + requestedHeight: decoratedWindow.oldRequestedHeight |
2911 | + visible: appDelegate.x < root.width |
2912 | + } |
2913 | + PropertyChanges { |
2914 | + target: decoratedWindow |
2915 | + hasDecoration: false |
2916 | + angle: stagedRightEdgeMaths.animatedAngle |
2917 | + itemScale: stagedRightEdgeMaths.animatedScale |
2918 | + scaleToPreviewSize: spreadItem.stackHeight |
2919 | + scaleToPreviewProgress: stagedRightEdgeMaths.scaleToPreviewProgress |
2920 | + shadowOpacity: .3 |
2921 | + } |
2922 | + }, |
2923 | + State { |
2924 | + name: "windowedRightEdge" |
2925 | + when: root.mode == "windowed" && (root.state == "windowedRightEdge" || rightEdgeFocusAnimation.running || hidingAnimation.running || edgeBarrier.progress > 0) |
2926 | + PropertyChanges { |
2927 | + target: windowedRightEdgeMaths |
2928 | + progress: Math.max(rightEdgeDragArea.progress, edgeBarrier.progress) |
2929 | + } |
2930 | + PropertyChanges { |
2931 | + target: appDelegate |
2932 | + x: windowedRightEdgeMaths.animatedX |
2933 | + y: windowedRightEdgeMaths.animatedY |
2934 | + z: windowedRightEdgeMaths.animatedZ |
2935 | + height: stagedRightEdgeMaths.animatedHeight |
2936 | + requestedWidth: decoratedWindow.oldRequestedWidth |
2937 | + requestedHeight: decoratedWindow.oldRequestedHeight |
2938 | + } |
2939 | + PropertyChanges { |
2940 | + target: decoratedWindow |
2941 | + showDecoration: windowedRightEdgeMaths.decorationHeight |
2942 | + angle: windowedRightEdgeMaths.animatedAngle |
2943 | + itemScale: windowedRightEdgeMaths.animatedScale |
2944 | + scaleToPreviewSize: spreadItem.stackHeight |
2945 | + scaleToPreviewProgress: windowedRightEdgeMaths.scaleToPreviewProgress |
2946 | + shadowOpacity: .3 |
2947 | + } |
2948 | + PropertyChanges { |
2949 | + target: opacityEffect; |
2950 | + opacityValue: windowedRightEdgeMaths.opacityMask |
2951 | + sourceItem: windowedRightEdgeMaths.opacityMask < 1 ? decoratedWindow : null |
2952 | + } |
2953 | + }, |
2954 | + State { |
2955 | + name: "staged"; when: root.state == "staged" |
2956 | + PropertyChanges { |
2957 | + target: appDelegate |
2958 | + x: stageMaths.itemX |
2959 | + y: appDelegate.fullscreen ? 0 : PanelState.panelHeight |
2960 | + requestedWidth: appContainer.width |
2961 | + requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - PanelState.panelHeight |
2962 | + visuallyMaximized: true |
2963 | + visible: appDelegate.x < root.width |
2964 | + } |
2965 | + PropertyChanges { |
2966 | + target: decoratedWindow |
2967 | + hasDecoration: false |
2968 | + } |
2969 | + PropertyChanges { |
2970 | + target: resizeArea |
2971 | + enabled: false |
2972 | + } |
2973 | + PropertyChanges { |
2974 | + target: stageMaths |
2975 | + animateX: !focusAnimation.running && itemIndex !== spreadItem.highlightedIndex |
2976 | + } |
2977 | + }, |
2978 | + State { |
2979 | + name: "stagedWithSideStage"; when: root.state == "stagedWithSideStage" |
2980 | + PropertyChanges { |
2981 | + target: stageMaths |
2982 | + itemIndex: index |
2983 | + } |
2984 | + PropertyChanges { |
2985 | + target: appDelegate |
2986 | + x: stageMaths.itemX |
2987 | + y: appDelegate.fullscreen ? 0 : PanelState.panelHeight |
2988 | + z: stageMaths.itemZ |
2989 | + requestedWidth: stageMaths.itemWidth |
2990 | + requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - PanelState.panelHeight |
2991 | + visuallyMaximized: true |
2992 | + visible: appDelegate.x < root.width |
2993 | + } |
2994 | + PropertyChanges { |
2995 | + target: decoratedWindow |
2996 | + hasDecoration: false |
2997 | + } |
2998 | + PropertyChanges { |
2999 | + target: resizeArea |
3000 | + enabled: false |
3001 | + } |
3002 | + }, |
3003 | + State { |
3004 | + name: "maximized"; when: appDelegate.windowState == WindowStateStorage.WindowStateMaximized |
3005 | + PropertyChanges { |
3006 | + target: appDelegate; |
3007 | + requestedX: root.leftMargin; |
3008 | + requestedY: 0; |
3009 | + visuallyMinimized: false; |
3010 | + visuallyMaximized: true |
3011 | + requestedWidth: appContainer.width - root.leftMargin; |
3012 | + requestedHeight: appContainer.height; |
3013 | + } |
3014 | + PropertyChanges { target: touchControls; enabled: true } |
3015 | + }, |
3016 | + State { |
3017 | name: "fullscreen"; when: appDelegate.fullscreen && !appDelegate.minimized |
3018 | PropertyChanges { |
3019 | target: appDelegate; |
3020 | - x: rotation == 0 ? 0 : (parent.width - width) / 2 + (shellOrientationAngle == 90 ? -PanelState.panelHeight : PanelState.panelHeight) |
3021 | - y: rotation == 0 ? -PanelState.panelHeight : (parent.height - height) / 2 |
3022 | + requestedX: 0 |
3023 | + requestedY: 0 |
3024 | requestedWidth: appContainer.width; |
3025 | requestedHeight: appContainer.height; |
3026 | } |
3027 | + PropertyChanges { target: decoratedWindow; hasDecoration: false } |
3028 | }, |
3029 | State { |
3030 | name: "normal"; |
3031 | when: appDelegate.windowState == WindowStateStorage.WindowStateNormal |
3032 | PropertyChanges { |
3033 | - target: appDelegate; |
3034 | - visuallyMinimized: false; |
3035 | + target: appDelegate |
3036 | + visuallyMinimized: false |
3037 | visuallyMaximized: false |
3038 | } |
3039 | + PropertyChanges { target: touchControls; enabled: true } |
3040 | + PropertyChanges { target: resizeArea; enabled: true } |
3041 | + PropertyChanges { target: decoratedWindow; shadowOpacity: .3} |
3042 | }, |
3043 | State { |
3044 | name: "restored"; |
3045 | @@ -542,30 +1214,25 @@ |
3046 | extend: "normal" |
3047 | PropertyChanges { |
3048 | target: appDelegate; |
3049 | - requestedX: restoredX; |
3050 | - requestedY: restoredY; |
3051 | + windowedX: restoredX; |
3052 | + windowedY: restoredY; |
3053 | } |
3054 | }, |
3055 | State { |
3056 | - name: "maximized"; when: appDelegate.maximized && !appDelegate.minimized |
3057 | - PropertyChanges { |
3058 | - target: appDelegate; |
3059 | - requestedX: root.leftMargin; |
3060 | - requestedY: 0; |
3061 | - requestedWidth: appContainer.width - root.leftMargin; |
3062 | - requestedHeight: appContainer.height; |
3063 | - visuallyMinimized: false; |
3064 | - visuallyMaximized: true |
3065 | - } |
3066 | + name: "semiMaximized" |
3067 | + PropertyChanges { target: touchControls; enabled: true } |
3068 | + PropertyChanges { target: resizeArea; enabled: true } |
3069 | + PropertyChanges { target: decoratedWindow; shadowOpacity: .3 } |
3070 | }, |
3071 | State { |
3072 | name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized |
3073 | + extend: "semiMaximized" |
3074 | PropertyChanges { |
3075 | target: appDelegate |
3076 | - requestedX: root.leftMargin |
3077 | - requestedY: PanelState.panelHeight |
3078 | - requestedWidth: (appContainer.width - root.leftMargin)/2 |
3079 | - requestedHeight: appContainer.height - PanelState.panelHeight |
3080 | + windowedX: root.leftMargin |
3081 | + windowedY: PanelState.panelHeight |
3082 | + windowedWidth: (appContainer.width - root.leftMargin)/2 |
3083 | + windowedHeight: appContainer.height - PanelState.panelHeight |
3084 | } |
3085 | }, |
3086 | State { |
3087 | @@ -573,17 +1240,18 @@ |
3088 | extend: "maximizedLeft" |
3089 | PropertyChanges { |
3090 | target: appDelegate; |
3091 | - requestedX: (appContainer.width + root.leftMargin)/2 |
3092 | + windowedX: (appContainer.width + root.leftMargin)/2 |
3093 | } |
3094 | }, |
3095 | State { |
3096 | name: "maximizedTopLeft"; when: appDelegate.maximizedTopLeft && !appDelegate.minimized |
3097 | + extend: "semiMaximized" |
3098 | PropertyChanges { |
3099 | target: appDelegate |
3100 | - requestedX: root.leftMargin |
3101 | - requestedY: PanelState.panelHeight |
3102 | - requestedWidth: (appContainer.width - root.leftMargin)/2 |
3103 | - requestedHeight: (appContainer.height - PanelState.panelHeight)/2 |
3104 | + windowedX: root.leftMargin |
3105 | + windowedY: PanelState.panelHeight |
3106 | + windowedWidth: (appContainer.width - root.leftMargin)/2 |
3107 | + windowedHeight: (appContainer.height - PanelState.panelHeight)/2 |
3108 | } |
3109 | }, |
3110 | State { |
3111 | @@ -591,17 +1259,18 @@ |
3112 | extend: "maximizedTopLeft" |
3113 | PropertyChanges { |
3114 | target: appDelegate |
3115 | - requestedX: (appContainer.width + root.leftMargin)/2 |
3116 | + windowedX: (appContainer.width + root.leftMargin)/2 |
3117 | } |
3118 | }, |
3119 | State { |
3120 | name: "maximizedBottomLeft"; when: appDelegate.maximizedBottomLeft && !appDelegate.minimized |
3121 | + extend: "semiMaximized" |
3122 | PropertyChanges { |
3123 | target: appDelegate |
3124 | - requestedX: root.leftMargin |
3125 | - requestedY: (appContainer.height + PanelState.panelHeight)/2 |
3126 | - requestedWidth: (appContainer.width - root.leftMargin)/2 |
3127 | - requestedHeight: appContainer.height/2 |
3128 | + windowedX: root.leftMargin |
3129 | + windowedY: (appContainer.height + PanelState.panelHeight)/2 |
3130 | + windowedWidth: (appContainer.width - root.leftMargin)/2 |
3131 | + windowedHeight: appContainer.height/2 |
3132 | } |
3133 | }, |
3134 | State { |
3135 | @@ -609,35 +1278,52 @@ |
3136 | extend: "maximizedBottomLeft" |
3137 | PropertyChanges { |
3138 | target: appDelegate |
3139 | - requestedX: (appContainer.width + root.leftMargin)/2 |
3140 | + windowedX: (appContainer.width + root.leftMargin)/2 |
3141 | } |
3142 | }, |
3143 | State { |
3144 | name: "maximizedHorizontally"; when: appDelegate.maximizedHorizontally && !appDelegate.minimized |
3145 | - PropertyChanges { target: appDelegate; requestedX: root.leftMargin; requestedY: requestedY; requestedWidth: appContainer.width - root.leftMargin } |
3146 | + extend: "semiMaximized" |
3147 | + PropertyChanges { target: appDelegate; requestedX: root.leftMargin; requestedY: windowedY; |
3148 | + requestedWidth: appContainer.width - root.leftMargin; requestedHeight: appDelegate.windowedHeight } |
3149 | }, |
3150 | State { |
3151 | name: "maximizedVertically"; when: appDelegate.maximizedVertically && !appDelegate.minimized |
3152 | - PropertyChanges { target: appDelegate; requestedX: requestedX; requestedY: PanelState.panelHeight; requestedHeight: appContainer.height - PanelState.panelHeight } |
3153 | + extend: "semiMaximized" |
3154 | + PropertyChanges { target: appDelegate; requestedX: windowedX; requestedY: PanelState.panelHeight; |
3155 | + requestedWidth: appDelegate.windowedWidth; requestedHeight: appContainer.height - PanelState.panelHeight } |
3156 | }, |
3157 | State { |
3158 | name: "minimized"; when: appDelegate.minimized |
3159 | PropertyChanges { |
3160 | - target: appDelegate; |
3161 | - requestedX: -appDelegate.width / 2; |
3162 | - scale: units.gu(5) / appDelegate.width; |
3163 | + target: appDelegate |
3164 | + requestedX: -appDelegate.width / 2 |
3165 | + scale: units.gu(5) / appDelegate.width |
3166 | opacity: 0; |
3167 | - visuallyMinimized: true; |
3168 | + visuallyMinimized: true |
3169 | visuallyMaximized: false |
3170 | } |
3171 | } |
3172 | ] |
3173 | transitions: [ |
3174 | Transition { |
3175 | + from: "staged,stagedWithSideStage"; to: "normal" |
3176 | + enabled: appDelegate.animationsEnabled |
3177 | + PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" } |
3178 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedX,requestedY,opacity,requestedWidth,requestedHeight,scale"; duration: priv.animationDuration } |
3179 | + }, |
3180 | + Transition { |
3181 | + from: "normal,maximized,maximizedHorizontally,maximizedVertically,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedBottomLeft,maximizedTopRight,maximizedBottomRight"; |
3182 | + to: "staged,stagedWithSideStage" |
3183 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedX,requestedY,requestedWidth,requestedHeight"; duration: priv.animationDuration} |
3184 | + }, |
3185 | + Transition { |
3186 | + from: "maximized,maximizedHorizontally,maximizedVertically,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedBottomLeft,maximizedTopRight,maximizedBottomRight,minimized"; |
3187 | to: "normal,restored" |
3188 | enabled: appDelegate.animationsEnabled |
3189 | PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" } |
3190 | - UbuntuNumberAnimation { target: appDelegate; properties: "requestedX,requestedY,opacity,scale,requestedWidth,requestedHeight" } |
3191 | + UbuntuNumberAnimation { target: appDelegate; properties: "requestedX,requestedY,windowedX,windowedY,requestedWidth,requestedHeight,windowedWidth,windowedHeight,scale"; |
3192 | + duration: priv.animationDuration } |
3193 | }, |
3194 | Transition { |
3195 | to: "minimized" |
3196 | @@ -657,11 +1343,60 @@ |
3197 | } |
3198 | }, |
3199 | Transition { |
3200 | - to: "*" //maximized and fullscreen |
3201 | + to: "spread" |
3202 | + // DecoratedWindow wants the scaleToPreviewSize set before enabling scaleToPreview |
3203 | + PropertyAction { target: appDelegate; properties: "z,visible" } |
3204 | + PropertyAction { target: decoratedWindow; property: "scaleToPreviewSize" } |
3205 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,height"; duration: priv.animationDuration } |
3206 | + UbuntuNumberAnimation { target: decoratedWindow; properties: "width,height,itemScale,angle,scaleToPreviewProgress"; duration: priv.animationDuration } |
3207 | + }, |
3208 | + Transition { |
3209 | + from: "normal,staged"; to: "stagedWithSideStage" |
3210 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y"; duration: priv.animationDuration } |
3211 | + UbuntuNumberAnimation { target: appDelegate; properties: "requestedWidth,requestedHeight"; duration: priv.animationDuration } |
3212 | + }, |
3213 | + Transition { |
3214 | + to: "windowedRightEdge" |
3215 | + ScriptAction { |
3216 | + script: { |
3217 | + windowedRightEdgeMaths.startX = appDelegate.requestedX |
3218 | + windowedRightEdgeMaths.startY = appDelegate.requestedY |
3219 | + |
3220 | + if (index == 1) { |
3221 | + var thisRect = { x: appDelegate.windowedX, y: appDelegate.windowedY, width: appDelegate.requestedWidth, height: appDelegate.requestedHeight } |
3222 | + var otherDelegate = appRepeater.itemAt(0); |
3223 | + var otherRect = { x: otherDelegate.windowedX, y: otherDelegate.windowedY, width: otherDelegate.requestedWidth, height: otherDelegate.requestedHeight } |
3224 | + var intersectionRect = MathUtils.intersectionRect(thisRect, otherRect) |
3225 | + var mappedInterSectionRect = appDelegate.mapFromItem(root, intersectionRect.x, intersectionRect.y) |
3226 | + opacityEffect.maskX = mappedInterSectionRect.x |
3227 | + opacityEffect.maskY = mappedInterSectionRect.y |
3228 | + opacityEffect.maskWidth = intersectionRect.width |
3229 | + opacityEffect.maskHeight = intersectionRect.height |
3230 | + } |
3231 | + } |
3232 | + } |
3233 | + }, |
3234 | + Transition { |
3235 | + from: "stagedRightEdge"; to: "staged" |
3236 | + enabled: rightEdgeDragArea.cancelled // only transition back to state if the gesture was cancelled, in the other cases we play the focusAnimations. |
3237 | + SequentialAnimation { |
3238 | + ParallelAnimation { |
3239 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,height,width,scale"; duration: priv.animationDuration } |
3240 | + UbuntuNumberAnimation { target: decoratedWindow; properties: "width,height,itemScale,angle,scaleToPreviewProgress"; duration: priv.animationDuration } |
3241 | + } |
3242 | + // We need to release scaleToPreviewSize at last |
3243 | + PropertyAction { target: decoratedWindow; property: "scaleToPreviewSize" } |
3244 | + PropertyAction { target: appDelegate; property: "visible" } |
3245 | + } |
3246 | + }, |
3247 | + Transition { |
3248 | + from: "normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTop,maximizedBottom,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen" |
3249 | + to: "normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTop,maximizedBottom,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen" |
3250 | enabled: appDelegate.animationsEnabled |
3251 | - PropertyAction { target: appDelegate; property: "visuallyMinimized" } |
3252 | SequentialAnimation { |
3253 | - UbuntuNumberAnimation { target: appDelegate; properties: "requestedX,requestedY,opacity,scale,requestedWidth,requestedHeight" } |
3254 | + PropertyAction { target: appDelegate; property: "visuallyMinimized" } |
3255 | + UbuntuNumberAnimation { target: appDelegate; properties: "requestedX,requestedY,windowedX,windowedY,opacity,scale,requestedWidth,requestedHeight,windowedWidth,windowedHeight"; |
3256 | + duration: priv.animationDuration } |
3257 | PropertyAction { target: appDelegate; property: "visuallyMaximized" } |
3258 | ScriptAction { script: { fakeRectangle.stop(); } } |
3259 | } |
3260 | @@ -669,14 +1404,6 @@ |
3261 | ] |
3262 | |
3263 | Binding { |
3264 | - id: previewBinding |
3265 | - target: appDelegate |
3266 | - property: "z" |
3267 | - value: topLevelSurfaceList.count + 1 |
3268 | - when: index == spread.highlightedIndex && spread.ready |
3269 | - } |
3270 | - |
3271 | - Binding { |
3272 | target: PanelState |
3273 | property: "buttonsAlwaysVisible" |
3274 | value: appDelegate && appDelegate.maximized && touchControls.overlayShown |
3275 | @@ -697,26 +1424,15 @@ |
3276 | screenWidth: appContainer.width |
3277 | screenHeight: appContainer.height |
3278 | leftMargin: root.leftMargin |
3279 | - |
3280 | - onPressed: { appDelegate.focus = true; } |
3281 | - |
3282 | - Component.onCompleted: { |
3283 | - loadWindowState(); |
3284 | - } |
3285 | - |
3286 | - property bool saveStateOnDestruction: true |
3287 | - Connections { |
3288 | - target: root |
3289 | - onStageAboutToBeUnloaded: { |
3290 | - resizeArea.saveWindowState(); |
3291 | - resizeArea.saveStateOnDestruction = false; |
3292 | - fullscreenPolicy.active = false; |
3293 | - } |
3294 | - } |
3295 | + enabled: false |
3296 | + visible: enabled |
3297 | + |
3298 | + onPressed: { |
3299 | + appDelegate.focus = true; |
3300 | + } |
3301 | + |
3302 | Component.onDestruction: { |
3303 | - if (saveStateOnDestruction) { |
3304 | - saveWindowState(); |
3305 | - } |
3306 | + saveWindowState(); |
3307 | } |
3308 | } |
3309 | |
3310 | @@ -729,14 +1445,25 @@ |
3311 | surface: model.surface |
3312 | active: appDelegate.focus |
3313 | focus: true |
3314 | + interactive: root.interactive |
3315 | + showDecoration: 1 |
3316 | maximizeButtonShown: appDelegate.canBeMaximized |
3317 | overlayShown: touchControls.overlayShown |
3318 | + width: implicitWidth |
3319 | + height: implicitHeight |
3320 | + highlightSize: windowInfoItem.iconMargin / 2 |
3321 | stageWidth: appContainer.width |
3322 | stageHeight: appContainer.height |
3323 | |
3324 | requestedWidth: appDelegate.requestedWidth |
3325 | requestedHeight: appDelegate.requestedHeight |
3326 | |
3327 | + property int oldRequestedWidth: -1 |
3328 | + property int oldRequestedHeight: -1 |
3329 | + |
3330 | + onRequestedWidthChanged: oldRequestedWidth = requestedWidth |
3331 | + onRequestedHeightChanged: oldRequestedHeight = requestedHeight |
3332 | + |
3333 | onCloseClicked: { appDelegate.close(); } |
3334 | onMaximizeClicked: appDelegate.anyMaximized ? appDelegate.restoreFromMaximized() : appDelegate.maximize(); |
3335 | onMaximizeHorizontallyClicked: appDelegate.maximizedHorizontally ? appDelegate.restoreFromMaximized() : appDelegate.maximizeHorizontally() |
3336 | @@ -744,11 +1471,34 @@ |
3337 | onMinimizeClicked: appDelegate.minimize() |
3338 | onDecorationPressed: { appDelegate.focus = true; } |
3339 | onDecorationReleased: fakeRectangle.commit(); |
3340 | + |
3341 | + property real angle: 0 |
3342 | + property real itemScale: 1 |
3343 | + transform: [ |
3344 | + Scale { |
3345 | + origin.x: 0 |
3346 | + origin.y: decoratedWindow.implicitHeight / 2 |
3347 | + xScale: decoratedWindow.itemScale |
3348 | + yScale: decoratedWindow.itemScale |
3349 | + }, |
3350 | + Rotation { |
3351 | + origin { x: 0; y: (decoratedWindow.height / 2) } |
3352 | + axis { x: 0; y: 1; z: 0 } |
3353 | + angle: decoratedWindow.angle |
3354 | + } |
3355 | + ] |
3356 | + } |
3357 | + |
3358 | + OpacityMask { |
3359 | + id: opacityEffect |
3360 | + anchors.fill: decoratedWindow |
3361 | } |
3362 | |
3363 | WindowControlsOverlay { |
3364 | id: touchControls |
3365 | target: appDelegate |
3366 | + enabled: false |
3367 | + visible: enabled |
3368 | stageWidth: appContainer.width |
3369 | stageHeight: appContainer.height |
3370 | |
3371 | @@ -764,9 +1514,89 @@ |
3372 | } |
3373 | |
3374 | WindowedFullscreenPolicy { |
3375 | - id: fullscreenPolicy |
3376 | - active: true |
3377 | - surface: model.surface |
3378 | + id: windowedFullscreenPolicy |
3379 | + active: root.mode == "windowed" |
3380 | + surface: model.surface |
3381 | + } |
3382 | + StagedFullscreenPolicy { |
3383 | + id: stagedFullscreenPolicy |
3384 | + active: root.mode == "staged" || root.mode == "stagedWithSideStage" |
3385 | + surface: model.surface |
3386 | + } |
3387 | + |
3388 | + SpreadDelegateInputArea { |
3389 | + id: dragArea |
3390 | + objectName: "dragArea" |
3391 | + anchors.fill: decoratedWindow |
3392 | + enabled: false |
3393 | + closeable: !appDelegate.isDash |
3394 | + |
3395 | + onClicked: { |
3396 | + spreadItem.highlightedIndex = index; |
3397 | + if (distance == 0) { |
3398 | + priv.goneToSpread = false; |
3399 | + } |
3400 | + } |
3401 | + onClose: { |
3402 | + priv.closingIndex = index |
3403 | + if (model.surface) { // could be stopped by OOM |
3404 | + model.surface.close() |
3405 | + } else if (model.application) { |
3406 | + root.applicationManager.stopApplication(model.application.appId); |
3407 | + } |
3408 | + } |
3409 | + } |
3410 | + |
3411 | + WindowInfoItem { |
3412 | + id: windowInfoItem |
3413 | + objectName: "windowInfoItem" |
3414 | + anchors { left: parent.left; top: decoratedWindow.bottom; topMargin: units.gu(1) } |
3415 | + title: model.application.name |
3416 | + iconSource: model.application.icon |
3417 | + height: spreadItem.appInfoHeight |
3418 | + opacity: 0 |
3419 | + z: 1 |
3420 | + visible: opacity > 0 |
3421 | + maxWidth: { |
3422 | + var nextApp = appRepeater.itemAt(index + 1); |
3423 | + if (nextApp) { |
3424 | + return nextApp.x - appDelegate.x - units.gu(1) |
3425 | + } |
3426 | + return appDelegate.width; |
3427 | + } |
3428 | + |
3429 | + onClicked: { |
3430 | + spreadItem.highlightedIndex = index; |
3431 | + priv.goneToSpread = false; |
3432 | + } |
3433 | + } |
3434 | + |
3435 | + Image { |
3436 | + id: closeImage |
3437 | + anchors { left: parent.left; top: parent.top; leftMargin: -height / 2; topMargin: -height / 2 + spreadMaths.closeIconOffset } |
3438 | + source: "graphics/window-close.svg" |
3439 | + readonly property var mousePos: hoverMouseArea.mapToItem(appDelegate, hoverMouseArea.mouseX, hoverMouseArea.mouseY) |
3440 | + visible: !appDelegate.isDash && dragArea.distance == 0 |
3441 | + && index == spreadItem.highlightedIndex |
3442 | + && mousePos.y < (decoratedWindow.height / 3) |
3443 | + && mousePos.y > -units.gu(4) |
3444 | + && mousePos.x > -units.gu(4) |
3445 | + && mousePos.x < (decoratedWindow.width * 2 / 3) |
3446 | + height: units.gu(2) |
3447 | + width: height |
3448 | + sourceSize.width: width |
3449 | + sourceSize.height: height |
3450 | + |
3451 | + MouseArea { |
3452 | + id: closeMouseArea |
3453 | + objectName: "closeMouseArea" |
3454 | + anchors.fill: closeImage |
3455 | + anchors.margins: -units.gu(2) |
3456 | + onClicked: { |
3457 | + priv.closingIndex = index; |
3458 | + appDelegate.close(); |
3459 | + } |
3460 | + } |
3461 | } |
3462 | } |
3463 | } |
3464 | @@ -786,7 +1616,8 @@ |
3465 | // NB: it does its own positioning according to the specified edge |
3466 | edge: Qt.RightEdge |
3467 | |
3468 | - onPassed: { spread.show(); } |
3469 | + onPassed: priv.goneToSpread = true; |
3470 | + |
3471 | material: Component { |
3472 | Item { |
3473 | Rectangle { |
3474 | @@ -803,23 +1634,248 @@ |
3475 | } |
3476 | } |
3477 | |
3478 | + MouseArea { |
3479 | + id: hoverMouseArea |
3480 | + objectName: "hoverMouseArea" |
3481 | + anchors.fill: appContainer |
3482 | + propagateComposedEvents: true |
3483 | + hoverEnabled: true |
3484 | + enabled: false |
3485 | + visible: enabled |
3486 | + |
3487 | + property int scrollAreaWidth: width / 3 |
3488 | + property bool progressiveScrollingEnabled: false |
3489 | + |
3490 | + onMouseXChanged: { |
3491 | + mouse.accepted = false |
3492 | + |
3493 | + if (hoverMouseArea.pressed) { |
3494 | + return; |
3495 | + } |
3496 | + |
3497 | + // Find the hovered item and mark it active |
3498 | + var mapped = mapToItem(appContainer, hoverMouseArea.mouseX, hoverMouseArea.mouseY) |
3499 | + var itemUnder = appContainer.childAt(mapped.x, mapped.y) |
3500 | + if (itemUnder) { |
3501 | + mapped = mapToItem(itemUnder, hoverMouseArea.mouseX, hoverMouseArea.mouseY) |
3502 | + var delegateChild = itemUnder.childAt(mapped.x, mapped.y) |
3503 | + if (delegateChild && (delegateChild.objectName === "dragArea" || delegateChild.objectName === "windowInfoItem")) { |
3504 | + spreadItem.highlightedIndex = appRepeater.indexOf(itemUnder) |
3505 | + } |
3506 | + } |
3507 | + |
3508 | + if (floatingFlickable.contentWidth > floatingFlickable.width) { |
3509 | + var margins = floatingFlickable.width * 0.05; |
3510 | + |
3511 | + if (!progressiveScrollingEnabled && mouseX < floatingFlickable.width - scrollAreaWidth) { |
3512 | + progressiveScrollingEnabled = true |
3513 | + } |
3514 | + |
3515 | + // do we need to scroll? |
3516 | + if (mouseX < scrollAreaWidth + margins) { |
3517 | + var progress = Math.min(1, (scrollAreaWidth + margins - mouseX) / (scrollAreaWidth - margins)); |
3518 | + var contentX = (1 - progress) * (floatingFlickable.contentWidth - floatingFlickable.width) |
3519 | + floatingFlickable.contentX = Math.max(0, Math.min(floatingFlickable.contentX, contentX)) |
3520 | + } |
3521 | + if (mouseX > floatingFlickable.width - scrollAreaWidth && progressiveScrollingEnabled) { |
3522 | + var progress = Math.min(1, (mouseX - (floatingFlickable.width - scrollAreaWidth)) / (scrollAreaWidth - margins)) |
3523 | + var contentX = progress * (floatingFlickable.contentWidth - floatingFlickable.width) |
3524 | + floatingFlickable.contentX = Math.min(floatingFlickable.contentWidth - floatingFlickable.width, Math.max(floatingFlickable.contentX, contentX)) |
3525 | + } |
3526 | + } |
3527 | + } |
3528 | + |
3529 | + onPressed: mouse.accepted = false |
3530 | + } |
3531 | + |
3532 | + FloatingFlickable { |
3533 | + id: floatingFlickable |
3534 | + objectName: "spreadFlickable" |
3535 | + anchors.fill: appContainer |
3536 | + enabled: false |
3537 | + contentWidth: spreadItem.spreadTotalWidth |
3538 | + |
3539 | + function snap(toIndex) { |
3540 | + var delegate = appRepeater.itemAt(toIndex) |
3541 | + var targetContentX = floatingFlickable.contentWidth / spreadItem.totalItemCount * toIndex; |
3542 | + if (targetContentX - floatingFlickable.contentX > spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) { |
3543 | + var offset = (spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) - (targetContentX - floatingFlickable.contentX) |
3544 | + snapAnimation.to = floatingFlickable.contentX - offset; |
3545 | + snapAnimation.start(); |
3546 | + } else if (targetContentX - floatingFlickable.contentX < spreadItem.leftStackXPos + units.gu(1)) { |
3547 | + var offset = (spreadItem.leftStackXPos + units.gu(1)) - (targetContentX - floatingFlickable.contentX); |
3548 | + snapAnimation.to = floatingFlickable.contentX - offset; |
3549 | + snapAnimation.start(); |
3550 | + } |
3551 | + } |
3552 | + UbuntuNumberAnimation {id: snapAnimation; target: floatingFlickable; property: "contentX"} |
3553 | + } |
3554 | + |
3555 | + PropertyAnimation { |
3556 | + id: shortRightEdgeSwipeAnimation |
3557 | + property: "x" |
3558 | + to: 0 |
3559 | + duration: priv.animationDuration |
3560 | + } |
3561 | + |
3562 | SwipeArea { |
3563 | + id: rightEdgeDragArea |
3564 | + objectName: "rightEdgeDragArea" |
3565 | direction: Direction.Leftwards |
3566 | anchors { top: parent.top; right: parent.right; bottom: parent.bottom } |
3567 | - width: units.gu(1) |
3568 | - onDraggingChanged: { if (dragging) { spread.show(); } } |
3569 | + width: root.dragAreaWidth |
3570 | + |
3571 | + property var gesturePoints: [] |
3572 | + property bool cancelled: false |
3573 | + |
3574 | + property real progress: dragging ? -touchPosition.x / root.width : 0 |
3575 | + onProgressChanged: { |
3576 | + if (dragging) { |
3577 | + draggedProgress = progress; |
3578 | + } |
3579 | + } |
3580 | + |
3581 | + property real draggedProgress: 0 |
3582 | + |
3583 | + onTouchPositionChanged: { |
3584 | + gesturePoints.push(touchPosition.x); |
3585 | + if (gesturePoints.length > 10) { |
3586 | + gesturePoints.splice(0, gesturePoints.length - 10) |
3587 | + } |
3588 | + } |
3589 | + |
3590 | + onDraggingChanged: { |
3591 | + if (dragging) { |
3592 | + // A potential edge-drag gesture has started. Start recording it |
3593 | + gesturePoints = []; |
3594 | + cancelled = false; |
3595 | + draggedProgress = 0; |
3596 | + } else { |
3597 | + // Ok. The user released. Did he drag far enough to go to full spread? |
3598 | + if (gesturePoints[gesturePoints.length - 1] < -spreadItem.rightEdgeBreakPoint * spreadItem.width ) { |
3599 | + |
3600 | + // He dragged far enough, but if the last movement was a flick to the right again, he wants to cancel the spread again. |
3601 | + var oneWayFlickToRight = true; |
3602 | + var smallestX = gesturePoints[0]-1; |
3603 | + for (var i = 0; i < gesturePoints.length; i++) { |
3604 | + if (gesturePoints[i] <= smallestX) { |
3605 | + oneWayFlickToRight = false; |
3606 | + break; |
3607 | + } |
3608 | + smallestX = gesturePoints[i]; |
3609 | + } |
3610 | + |
3611 | + if (!oneWayFlickToRight) { |
3612 | + // Ok, the user made it, let's go to spread! |
3613 | + priv.goneToSpread = true; |
3614 | + } else { |
3615 | + cancelled = true; |
3616 | + } |
3617 | + } else { |
3618 | + // Ok, the user didn't drag far enough to cross the breakPoint |
3619 | + // Find out if it was a one-way movement to the left, in which case we just switch directly to next app. |
3620 | + var oneWayFlick = true; |
3621 | + var smallestX = rightEdgeDragArea.width; |
3622 | + for (var i = 0; i < gesturePoints.length; i++) { |
3623 | + if (gesturePoints[i] >= smallestX) { |
3624 | + oneWayFlick = false; |
3625 | + break; |
3626 | + } |
3627 | + smallestX = gesturePoints[i]; |
3628 | + } |
3629 | + |
3630 | + if (appRepeater.count > 1 && |
3631 | + (oneWayFlick && rightEdgeDragArea.distance > units.gu(2) || rightEdgeDragArea.distance > spreadItem.rightEdgeBreakPoint * spreadItem.width)) { |
3632 | + var nextStage = appRepeater.itemAt(priv.nextInStack).stage |
3633 | + for (var i = 0; i < appRepeater.count; i++) { |
3634 | + if (i != priv.nextInStack && appRepeater.itemAt(i).stage == nextStage) { |
3635 | + appRepeater.itemAt(i).playHidingAnimation() |
3636 | + break; |
3637 | + } |
3638 | + } |
3639 | + appRepeater.itemAt(priv.nextInStack).playFocusAnimation() |
3640 | + if (appRepeater.itemAt(priv.nextInStack).stage == ApplicationInfoInterface.SideStage && !sideStage.shown) { |
3641 | + sideStage.show(); |
3642 | + } |
3643 | + |
3644 | + } else { |
3645 | + cancelled = true; |
3646 | + } |
3647 | + |
3648 | + gesturePoints = []; |
3649 | + } |
3650 | + } |
3651 | + } |
3652 | } |
3653 | |
3654 | - DesktopSpread { |
3655 | - id: spread |
3656 | - objectName: "spread" |
3657 | - anchors.fill: appContainer |
3658 | - workspace: appContainer |
3659 | - focus: state == "altTab" |
3660 | - altTabPressed: root.altTabPressed |
3661 | - |
3662 | - onPlayFocusAnimation: { |
3663 | - appRepeater.itemAt(index).playFocusAnimation(); |
3664 | + TabletSideStageTouchGesture { |
3665 | + id: triGestureArea |
3666 | + objectName: "triGestureArea" |
3667 | + anchors.fill: parent |
3668 | + enabled: false |
3669 | + property Item appDelegate |
3670 | + |
3671 | + dragComponent: dragComponent |
3672 | + dragComponentProperties: { "appDelegate": appDelegate } |
3673 | + |
3674 | + onPressed: { |
3675 | + function matchDelegate(obj) { return String(obj.objectName).indexOf("appDelegate") >= 0; } |
3676 | + |
3677 | + var delegateAtCenter = Functions.itemAt(appContainer, x, y, matchDelegate); |
3678 | + if (!delegateAtCenter) return; |
3679 | + |
3680 | + appDelegate = delegateAtCenter; |
3681 | + } |
3682 | + |
3683 | + onClicked: { |
3684 | + if (sideStage.shown) { |
3685 | + sideStage.hide(); |
3686 | + } else { |
3687 | + sideStage.show(); |
3688 | + priv.updateMainAndSideStageIndexes() |
3689 | + } |
3690 | + } |
3691 | + |
3692 | + onDragStarted: { |
3693 | + // If we're dragging to the sidestage. |
3694 | + if (!sideStage.shown) { |
3695 | + sideStage.show(); |
3696 | + } |
3697 | + } |
3698 | + |
3699 | + Component { |
3700 | + id: dragComponent |
3701 | + SurfaceContainer { |
3702 | + property Item appDelegate |
3703 | + |
3704 | + surface: appDelegate ? appDelegate.surface : null |
3705 | + |
3706 | + consumesInput: false |
3707 | + interactive: false |
3708 | + focus: false |
3709 | + requestedWidth: appDelegate.requestedWidth |
3710 | + requestedHeight: appDelegate.requestedHeight |
3711 | + |
3712 | + width: units.gu(40) |
3713 | + height: units.gu(40) |
3714 | + |
3715 | + Drag.hotSpot.x: width/2 |
3716 | + Drag.hotSpot.y: height/2 |
3717 | + // only accept opposite stage. |
3718 | + Drag.keys: { |
3719 | + if (!surface) return "Disabled"; |
3720 | + if (appDelegate.isDash) return "Disabled"; |
3721 | + |
3722 | + if (appDelegate.stage === ApplicationInfo.MainStage) { |
3723 | + if (appDelegate.application.supportedOrientations |
3724 | + & (Qt.PortraitOrientation|Qt.InvertedPortraitOrientation)) { |
3725 | + return "MainStage"; |
3726 | + } |
3727 | + return "Disabled"; |
3728 | + } |
3729 | + return "SideStage"; |
3730 | + } |
3731 | + } |
3732 | } |
3733 | } |
3734 | } |
3735 | |
3736 | === added file 'qml/Stage/StageMaths.qml' |
3737 | --- qml/Stage/StageMaths.qml 1970-01-01 00:00:00 +0000 |
3738 | +++ qml/Stage/StageMaths.qml 2016-10-11 21:49:13 +0000 |
3739 | @@ -0,0 +1,79 @@ |
3740 | +import QtQuick 2.4 |
3741 | +import Unity.Application 0.1 |
3742 | +import Ubuntu.Components 1.3 |
3743 | + |
3744 | +QtObject { |
3745 | + id: root |
3746 | + |
3747 | + // input |
3748 | + property int itemIndex: 0 |
3749 | + property int nextInStack: 0 |
3750 | + property int sceneWidth: 0 |
3751 | + property int sideStageWidth: 0 |
3752 | + property int sideStageX: sceneWidth |
3753 | + property bool animateX: false |
3754 | + property int leftEdgeDragProgress: 0 |
3755 | + |
3756 | + property int stage: ApplicationInfoInterface.MainStage |
3757 | + property var thisDelegate: null |
3758 | + property var mainStageDelegate: null |
3759 | + property var sideStageDelegate: null |
3760 | + |
3761 | + // output |
3762 | + |
3763 | + // We need to shuffle z ordering a bit in order to keep side stage apps above main stage apps. |
3764 | + // We don't want to really reorder them in the model because that allows us to keep track |
3765 | + // of the last focused order. |
3766 | + readonly property int itemZ: { |
3767 | + // only shuffle when we've got a main and side stage |
3768 | + if (thisDelegate.isDash && thisDelegate != mainStageDelegate && leftEdgeDragProgress > 0) { |
3769 | + return -1; // Keep the dash behind all other apps for the left edge gesture |
3770 | + } |
3771 | + |
3772 | + if (!sideStageDelegate) return itemIndex; |
3773 | + |
3774 | + // don't shuffle indexes greater than "actives or next" |
3775 | + if (itemIndex > 2) return itemIndex; |
3776 | + |
3777 | + if (thisDelegate == mainStageDelegate) { |
3778 | + // Active main stage always at 0 |
3779 | + return 0; |
3780 | + } |
3781 | + |
3782 | + if (nextInStack > 0) { |
3783 | + var stageOfNextInStack = appRepeater.itemAt(nextInStack).stage; |
3784 | + |
3785 | + if (itemIndex === nextInStack) { |
3786 | + // this is the next app in stack. |
3787 | + |
3788 | + if (stage === ApplicationInfoInterface.SideStage) { |
3789 | + // if the next app in stack is a sidestage app, it must order on top of other side stage app |
3790 | + return Math.min(2, topLevelSurfaceList.count-1); |
3791 | + } |
3792 | + return 1; |
3793 | + } |
3794 | + if (stageOfNextInStack === ApplicationInfoInterface.SideStage) { |
3795 | + // if the next app in stack is a sidestage app, it must order on top of other side stage app |
3796 | + return 1; |
3797 | + } |
3798 | + return Math.min(2, topLevelSurfaceList.count-1); |
3799 | + } |
3800 | + return Math.min(index+1, topLevelSurfaceList.count-1); |
3801 | + } |
3802 | + |
3803 | + |
3804 | + property int itemX: { |
3805 | + if (mainStageDelegate == thisDelegate) { |
3806 | + return thisDelegate.isDash ? 0 : leftEdgeDragProgress; |
3807 | + } |
3808 | + if (sideStageDelegate == thisDelegate) { |
3809 | + return sideStageX; |
3810 | + } |
3811 | + return thisDelegate.isDash && leftEdgeDragProgress > 0 ? 0 : sceneWidth; |
3812 | + } |
3813 | + Behavior on itemX { enabled: root.animateX; UbuntuNumberAnimation {} } |
3814 | + |
3815 | + readonly property int itemWidth: stage == ApplicationInfoInterface.MainStage ? |
3816 | + sideStageDelegate != null ? sideStageX : sceneWidth : |
3817 | + stage == ApplicationInfoInterface.SideStage ? sideStageWidth : sceneWidth |
3818 | +} |
3819 | |
3820 | === modified file 'qml/Stage/SurfaceContainer.qml' |
3821 | --- qml/Stages/SurfaceContainer.qml 2016-05-18 21:58:39 +0000 |
3822 | +++ qml/Stage/SurfaceContainer.qml 2016-10-11 21:49:13 +0000 |
3823 | @@ -23,6 +23,8 @@ |
3824 | FocusScope { |
3825 | id: root |
3826 | objectName: "surfaceContainer" |
3827 | + implicitWidth: surfaceItem.implicitWidth |
3828 | + implicitHeight: surfaceItem.implicitHeight |
3829 | |
3830 | // Must be set from outside |
3831 | property var surface: null |
3832 | @@ -32,7 +34,6 @@ |
3833 | property int requestedHeight: -1 |
3834 | property bool interactive |
3835 | property int surfaceOrientationAngle: 0 |
3836 | - property bool resizeSurface: true |
3837 | property bool isPromptSurface: false |
3838 | // FIME - dont export, use interactive property. Need to fix qtmir to handle consumesInputChanged |
3839 | // to update surface activeFocus. See mock MirSurfaceItem. |
3840 | @@ -58,35 +59,15 @@ |
3841 | MirSurfaceItem { |
3842 | id: surfaceItem |
3843 | objectName: "surfaceItem" |
3844 | + anchors.fill: parent |
3845 | |
3846 | focus: true |
3847 | |
3848 | fillMode: MirSurfaceItem.PadOrCrop |
3849 | consumesInput: true |
3850 | |
3851 | - surfaceWidth: { |
3852 | - if (root.resizeSurface) { |
3853 | - if (root.requestedWidth >= 0) { |
3854 | - return root.requestedWidth; |
3855 | - } else { |
3856 | - return width; |
3857 | - } |
3858 | - } else { |
3859 | - return -1; |
3860 | - } |
3861 | - } |
3862 | - |
3863 | - surfaceHeight: { |
3864 | - if (root.resizeSurface) { |
3865 | - if (root.requestedHeight >= 0) { |
3866 | - return root.requestedHeight; |
3867 | - } else { |
3868 | - return height; |
3869 | - } |
3870 | - } else { |
3871 | - return -1; |
3872 | - } |
3873 | - } |
3874 | + surfaceWidth: root.requestedWidth |
3875 | + surfaceHeight: root.requestedHeight |
3876 | |
3877 | enabled: root.interactive |
3878 | antialiasing: !root.interactive |
3879 | @@ -99,34 +80,6 @@ |
3880 | enabled: surfaceItem.enabled |
3881 | } |
3882 | |
3883 | - // MirSurface size drives SurfaceContainer size |
3884 | - Binding { |
3885 | - target: surfaceItem; property: "width"; value: root.surface ? root.surface.size.width : 0 |
3886 | - when: root.requestedWidth >= 0 && root.surface |
3887 | - } |
3888 | - Binding { |
3889 | - target: surfaceItem; property: "height"; value: root.surface ? root.surface.size.height : 0 |
3890 | - when: root.requestedHeight >= 0 && root.surface |
3891 | - } |
3892 | - Binding { |
3893 | - target: root; property: "width"; value: surfaceItem.width |
3894 | - when: root.requestedWidth >= 0 |
3895 | - } |
3896 | - Binding { |
3897 | - target: root; property: "height"; value: surfaceItem.height |
3898 | - when: root.requestedHeight >= 0 |
3899 | - } |
3900 | - |
3901 | - // SurfaceContainer size drives MirSurface size |
3902 | - Binding { |
3903 | - target: surfaceItem; property: "width"; value: root.width |
3904 | - when: root.requestedWidth < 0 |
3905 | - } |
3906 | - Binding { |
3907 | - target: surfaceItem; property: "height"; value: root.height |
3908 | - when: root.requestedHeight < 0 |
3909 | - } |
3910 | - |
3911 | Loader { |
3912 | id: animationsLoader |
3913 | objectName: "animationsLoader" |
3914 | |
3915 | === modified file 'qml/Stage/TopLevelSurfaceRepeater.qml' |
3916 | --- qml/Stages/TopLevelSurfaceRepeater.qml 2016-09-07 09:48:56 +0000 |
3917 | +++ qml/Stage/TopLevelSurfaceRepeater.qml 2016-10-11 21:49:13 +0000 |
3918 | @@ -55,4 +55,13 @@ |
3919 | startingUp = false; |
3920 | } |
3921 | } |
3922 | + |
3923 | + function indexOf(delegateItem) { |
3924 | + for (var i = 0; i < count; i++) { |
3925 | + if (itemAt(i) === delegateItem) { |
3926 | + return i; |
3927 | + } |
3928 | + } |
3929 | + return -1; |
3930 | + } |
3931 | } |
3932 | |
3933 | === modified file 'qml/Stage/WindowDecoration.qml' |
3934 | --- qml/Stages/WindowDecoration.qml 2016-09-22 07:42:18 +0000 |
3935 | +++ qml/Stage/WindowDecoration.qml 2016-10-11 21:49:13 +0000 |
3936 | @@ -79,7 +79,7 @@ |
3937 | onMaximizeClicked: root.maximizeClicked(); |
3938 | onMaximizeHorizontallyClicked: if (root.target.canBeMaximizedHorizontally) root.maximizeHorizontallyClicked(); |
3939 | onMaximizeVerticallyClicked: if (root.target.canBeMaximizedVertically) root.maximizeVerticallyClicked(); |
3940 | - closeButtonShown: root.target.application.appId !== "unity8-dash" |
3941 | + closeButtonShown: root.target.appId !== "unity8-dash" |
3942 | } |
3943 | |
3944 | Label { |
3945 | |
3946 | === added file 'qml/Stage/WindowInfoItem.qml' |
3947 | --- qml/Stage/WindowInfoItem.qml 1970-01-01 00:00:00 +0000 |
3948 | +++ qml/Stage/WindowInfoItem.qml 2016-10-11 21:49:13 +0000 |
3949 | @@ -0,0 +1,53 @@ |
3950 | +import QtQuick 2.4 |
3951 | +import Ubuntu.Components 1.3 |
3952 | + |
3953 | +Item { |
3954 | + id: root |
3955 | + implicitWidth: Math.max(iconShape.width, titleLabel.width) |
3956 | + implicitHeight: iconShape.height + titleLabel.height + labelMargin + iconMargin |
3957 | + property alias title: titleLabel.text |
3958 | + property alias iconSource: icon.source |
3959 | + |
3960 | + property real iconHeight: (height - titleLabel.height) * 0.65 |
3961 | + property real iconMargin: (height - titleLabel.height) * 0.25 |
3962 | + property real labelMargin: (height - titleLabel.height) * 0.1 |
3963 | + property int maxWidth: units.gu(10) |
3964 | + |
3965 | + signal clicked() |
3966 | + |
3967 | + ProportionalShape { |
3968 | + id: iconShape |
3969 | + anchors { |
3970 | + top: parent.top |
3971 | + topMargin: iconMargin |
3972 | + left: parent.left |
3973 | + } |
3974 | + height: iconHeight |
3975 | + borderSource: "undefined" |
3976 | + aspect: UbuntuShape.Flat |
3977 | + source: Image { |
3978 | + id: icon |
3979 | + sourceSize.width: iconShape.width |
3980 | + sourceSize.height: iconShape.height |
3981 | + cache: false // see lpbug#1543290 why no cache |
3982 | + } |
3983 | + } |
3984 | + |
3985 | + MouseArea { |
3986 | + anchors.fill: iconShape |
3987 | + onClicked: root.clicked() |
3988 | + } |
3989 | + |
3990 | + Label { |
3991 | + id: titleLabel |
3992 | + anchors { |
3993 | + left: iconShape.left |
3994 | + top: iconShape.bottom |
3995 | + topMargin: labelMargin |
3996 | + } |
3997 | + width: root.maxWidth |
3998 | + fontSize: 'small' |
3999 | + color: 'white' |
4000 | + elide: Label.ElideRight |
4001 | + } |
4002 | +} |
4003 | |
4004 | === modified file 'qml/Stage/WindowResizeArea.qml' |
4005 | --- qml/Stages/WindowResizeArea.qml 2016-08-31 13:00:26 +0000 |
4006 | +++ qml/Stage/WindowResizeArea.qml 2016-10-11 21:49:13 +0000 |
4007 | @@ -75,14 +75,15 @@ |
4008 | |
4009 | function loadWindowState() { |
4010 | var windowGeometry = windowStateStorage.getGeometry(root.windowId, |
4011 | - Qt.rect(target.requestedX, target.requestedY, defaultWidth, defaultHeight)); |
4012 | - |
4013 | - target.requestedWidth = Qt.binding(function() { return Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth - root.leftMargin); }); |
4014 | - target.requestedHeight = Qt.binding(function() { return Math.min(Math.max(windowGeometry.height, d.minimumHeight), |
4015 | + Qt.rect(target.windowedX, target.windowedY, defaultWidth, defaultHeight)); |
4016 | + |
4017 | + |
4018 | + target.windowedWidth = Qt.binding(function() { return Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth - root.leftMargin); }); |
4019 | + target.windowedHeight = Qt.binding(function() { return Math.min(Math.max(windowGeometry.height, d.minimumHeight), |
4020 | root.screenHeight - (target.fullscreen ? 0 : PanelState.panelHeight)); }); |
4021 | - target.requestedX = Qt.binding(function() { return Math.max(Math.min(windowGeometry.x, root.screenWidth - root.leftMargin - target.requestedWidth), |
4022 | + target.windowedX = Qt.binding(function() { return Math.max(Math.min(windowGeometry.x, root.screenWidth - root.leftMargin - target.windowedWidth), |
4023 | (target.fullscreen ? 0 : root.leftMargin)); }); |
4024 | - target.requestedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight); }); |
4025 | + target.windowedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, root.screenHeight - target.windowedHeight), PanelState.panelHeight); }); |
4026 | |
4027 | var windowState = windowStateStorage.getState(root.windowId, WindowStateStorage.WindowStateNormal) |
4028 | target.restore(false /* animated */, windowState); |
4029 | @@ -111,28 +112,28 @@ |
4030 | |
4031 | readonly property int minimumWidth: root.target ? Math.max(root.minWidth, root.target.minimumWidth) : root.minWidth |
4032 | onMinimumWidthChanged: { |
4033 | - if (target.requestedWidth < minimumWidth) { |
4034 | - target.requestedWidth = minimumWidth; |
4035 | + if (target.windowedWidth < minimumWidth) { |
4036 | + target.windowedWidth = minimumWidth; |
4037 | } |
4038 | } |
4039 | readonly property int minimumHeight: root.target ? Math.max(root.minHeight, root.target.minimumHeight) : root.minHeight |
4040 | onMinimumHeightChanged: { |
4041 | - if (target.requestedHeight < minimumHeight) { |
4042 | - target.requestedHeight = minimumHeight; |
4043 | + if (target.windowedHeight < minimumHeight) { |
4044 | + target.windowedHeight = minimumHeight; |
4045 | } |
4046 | } |
4047 | readonly property int maximumWidth: root.target && root.target.maximumWidth >= minimumWidth && root.target.maximumWidth > 0 |
4048 | ? root.target.maximumWidth : maxSafeInt |
4049 | onMaximumWidthChanged: { |
4050 | - if (target.requestedWidth > maximumWidth) { |
4051 | - target.requestedWidth = maximumWidth; |
4052 | + if (target.windowedWidth > maximumWidth) { |
4053 | + target.windowedWidth = maximumWidth; |
4054 | } |
4055 | } |
4056 | readonly property int maximumHeight: root.target && root.target.maximumHeight >= minimumHeight && root.target.maximumHeight > 0 |
4057 | ? root.target.maximumHeight : maxSafeInt |
4058 | onMaximumHeightChanged: { |
4059 | - if (target.requestedHeight > maximumHeight) { |
4060 | - target.requestedHeight = maximumHeight; |
4061 | + if (target.windowedHeight > maximumHeight) { |
4062 | + target.windowedHeight = maximumHeight; |
4063 | } |
4064 | } |
4065 | readonly property int widthIncrement: { |
4066 | @@ -247,8 +248,8 @@ |
4067 | var pos = mapToItem(root.target.parent, mouseX, mouseY); |
4068 | d.startMousePosX = pos.x; |
4069 | d.startMousePosY = pos.y; |
4070 | - d.startX = target.requestedX; |
4071 | - d.startY = target.requestedY; |
4072 | + d.startX = target.windowedX; |
4073 | + d.startY = target.windowedY; |
4074 | d.startWidth = target.width; |
4075 | d.startHeight = target.height; |
4076 | d.currentWidth = target.width; |
4077 | @@ -285,53 +286,53 @@ |
4078 | |
4079 | if (d.leftBorder) { |
4080 | var newTargetX = d.startX + deltaX; |
4081 | - var rightBorderX = target.requestedX + target.width; |
4082 | + var rightBorderX = target.windowedX + target.width; |
4083 | if (rightBorderX > newTargetX + d.minimumWidth) { |
4084 | if (rightBorderX < newTargetX + d.maximumWidth) { |
4085 | - target.requestedWidth = rightBorderX - newTargetX; |
4086 | + target.windowedWidth = rightBorderX - newTargetX; |
4087 | } else { |
4088 | - target.requestedWidth = d.maximumWidth; |
4089 | + target.windowedWidth = d.maximumWidth; |
4090 | } |
4091 | } else { |
4092 | - target.requestedWidth = d.minimumWidth; |
4093 | + target.windowedWidth = d.minimumWidth; |
4094 | } |
4095 | |
4096 | } else if (d.rightBorder) { |
4097 | var newWidth = d.startWidth + deltaX; |
4098 | if (newWidth > d.minimumWidth) { |
4099 | if (newWidth < d.maximumWidth) { |
4100 | - target.requestedWidth = newWidth; |
4101 | + target.windowedWidth = newWidth; |
4102 | } else { |
4103 | - target.requestedWidth = d.maximumWidth; |
4104 | + target.windowedWidth = d.maximumWidth; |
4105 | } |
4106 | } else { |
4107 | - target.requestedWidth = d.minimumWidth; |
4108 | + target.windowedWidth = d.minimumWidth; |
4109 | } |
4110 | } |
4111 | |
4112 | if (d.topBorder) { |
4113 | var newTargetY = Math.max(d.startY + deltaY, PanelState.panelHeight); // disallow resizing up past Panel |
4114 | - var bottomBorderY = target.requestedY + target.height; |
4115 | + var bottomBorderY = target.windowedY + target.height; |
4116 | if (bottomBorderY > newTargetY + d.minimumHeight) { |
4117 | if (bottomBorderY < newTargetY + d.maximumHeight) { |
4118 | - target.requestedHeight = bottomBorderY - newTargetY; |
4119 | + target.windowedHeight = bottomBorderY - newTargetY; |
4120 | } else { |
4121 | - target.requestedHeight = d.maximumHeight; |
4122 | + target.windowedHeight = d.maximumHeight; |
4123 | } |
4124 | } else { |
4125 | - target.requestedHeight = d.minimumHeight; |
4126 | + target.windowedHeight = d.minimumHeight; |
4127 | } |
4128 | |
4129 | } else if (d.bottomBorder) { |
4130 | var newHeight = d.startHeight + deltaY; |
4131 | if (newHeight > d.minimumHeight) { |
4132 | if (newHeight < d.maximumHeight) { |
4133 | - target.requestedHeight = newHeight; |
4134 | + target.windowedHeight = newHeight; |
4135 | } else { |
4136 | - target.requestedHeight = d.maximumHeight; |
4137 | + target.windowedHeight = d.maximumHeight; |
4138 | } |
4139 | } else { |
4140 | - target.requestedHeight = d.minimumHeight; |
4141 | + target.windowedHeight = d.minimumHeight; |
4142 | } |
4143 | } |
4144 | } |
4145 | @@ -340,13 +341,13 @@ |
4146 | target: root.target |
4147 | onWidthChanged: { |
4148 | if (d.moveLeftBorder) { |
4149 | - target.requestedX += d.currentWidth - target.width; |
4150 | + target.windowedX += d.currentWidth - target.width; |
4151 | } |
4152 | d.currentWidth = target.width; |
4153 | } |
4154 | onHeightChanged: { |
4155 | if (d.moveTopBorder) { |
4156 | - target.requestedY += d.currentHeight - target.height; |
4157 | + target.windowedY += d.currentHeight - target.height; |
4158 | } |
4159 | d.currentHeight = target.height; |
4160 | } |
4161 | |
4162 | === removed file 'qml/Stages/AbstractStage.qml' |
4163 | --- qml/Stages/AbstractStage.qml 2016-09-07 08:36:59 +0000 |
4164 | +++ qml/Stages/AbstractStage.qml 1970-01-01 00:00:00 +0000 |
4165 | @@ -1,93 +0,0 @@ |
4166 | -/* |
4167 | - * Copyright (C) 2015-2016 Canonical, Ltd. |
4168 | - * |
4169 | - * This program is free software; you can redistribute it and/or modify |
4170 | - * it under the terms of the GNU General Public License as published by |
4171 | - * the Free Software Foundation; version 3. |
4172 | - * |
4173 | - * This program is distributed in the hope that it will be useful, |
4174 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4175 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4176 | - * GNU General Public License for more details. |
4177 | - * |
4178 | - * You should have received a copy of the GNU General Public License |
4179 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4180 | - */ |
4181 | - |
4182 | -import QtQuick 2.4 |
4183 | -import Ubuntu.Components 1.3 |
4184 | -import GlobalShortcut 1.0 |
4185 | -import GSettings 1.0 |
4186 | - |
4187 | -FocusScope { |
4188 | - id: root |
4189 | - |
4190 | - // Controls to be set from outside |
4191 | - property QtObject applicationManager |
4192 | - property QtObject topLevelSurfaceList |
4193 | - property bool altTabPressed |
4194 | - property url background |
4195 | - property bool beingResized |
4196 | - property int dragAreaWidth |
4197 | - property real dragProgress // How far left the stage has been dragged, used externally by tutorial code |
4198 | - property bool interactive |
4199 | - property real inverseProgress // This is the progress for left edge drags, in pixels. |
4200 | - property bool keepDashRunning: true |
4201 | - property real maximizedAppTopMargin |
4202 | - property real nativeHeight |
4203 | - property real nativeWidth |
4204 | - property QtObject orientations |
4205 | - property int shellOrientation |
4206 | - property int shellOrientationAngle |
4207 | - property bool spreadEnabled: true // If false, animations and right edge will be disabled |
4208 | - property bool suspended |
4209 | - // A Stage should paint a wallpaper etc over its full size but not use the margins for window placement |
4210 | - property int leftMargin: 0 |
4211 | - property alias paintBackground: background.visible |
4212 | - property bool oskEnabled: false |
4213 | - |
4214 | - // To be read from outside |
4215 | - property var mainApp: null |
4216 | - property int mainAppWindowOrientationAngle: 0 |
4217 | - property bool orientationChangesEnabled |
4218 | - property int supportedOrientations: Qt.PortraitOrientation |
4219 | - | Qt.LandscapeOrientation |
4220 | - | Qt.InvertedPortraitOrientation |
4221 | - | Qt.InvertedLandscapeOrientation |
4222 | - |
4223 | - property Item itemConfiningMouseCursor: null |
4224 | - |
4225 | - |
4226 | - signal stageAboutToBeUnloaded |
4227 | - signal itemSnapshotRequested(Item item) |
4228 | - |
4229 | - // Shared code for use in stage implementations |
4230 | - GSettings { |
4231 | - id: lifecycleExceptions |
4232 | - schema.id: "com.canonical.qtmir" |
4233 | - } |
4234 | - |
4235 | - function isExemptFromLifecycle(appId) { |
4236 | - var shortAppId = appId.split('_')[0]; |
4237 | - for (var i = 0; i < lifecycleExceptions.lifecycleExemptAppids.length; i++) { |
4238 | - if (shortAppId === lifecycleExceptions.lifecycleExemptAppids[i]) { |
4239 | - return true; |
4240 | - } |
4241 | - } |
4242 | - return false; |
4243 | - } |
4244 | - |
4245 | - Rectangle { |
4246 | - id: background |
4247 | - color: "#060606" |
4248 | - anchors.fill: parent |
4249 | - } |
4250 | - |
4251 | - // shared Alt+F4 functionality |
4252 | - function closeFocusedDelegate() {} // to be implemented by stages |
4253 | - |
4254 | - GlobalShortcut { |
4255 | - shortcut: Qt.AltModifier|Qt.Key_F4 |
4256 | - onTriggered: closeFocusedDelegate() |
4257 | - } |
4258 | -} |
4259 | |
4260 | === removed file 'qml/Stages/DesktopSpread.qml' |
4261 | --- qml/Stages/DesktopSpread.qml 2016-06-15 14:08:18 +0000 |
4262 | +++ qml/Stages/DesktopSpread.qml 1970-01-01 00:00:00 +0000 |
4263 | @@ -1,576 +0,0 @@ |
4264 | -/* |
4265 | - * Copyright (C) 2015-2016 Canonical, Ltd. |
4266 | - * |
4267 | - * This program is free software; you can redistribute it and/or modify |
4268 | - * it under the terms of the GNU General Public License as published by |
4269 | - * the Free Software Foundation; version 3. |
4270 | - * |
4271 | - * This program is distributed in the hope that it will be useful, |
4272 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4273 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4274 | - * GNU General Public License for more details. |
4275 | - * |
4276 | - * You should have received a copy of the GNU General Public License |
4277 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4278 | - */ |
4279 | - |
4280 | -import QtQuick 2.4 |
4281 | -import QtQuick.Layouts 1.1 |
4282 | -import Ubuntu.Components 1.3 |
4283 | -import Ubuntu.Gestures 0.1 |
4284 | -import Unity.Application 0.1 |
4285 | -import "../Components" |
4286 | -import Utils 0.1 |
4287 | - |
4288 | -FocusScope { |
4289 | - id: root |
4290 | - |
4291 | - property bool altTabPressed: false |
4292 | - property Item workspace: null |
4293 | - |
4294 | - readonly property alias ready: blurLayer.ready |
4295 | - readonly property alias highlightedIndex: spreadRepeater.highlightedIndex |
4296 | - |
4297 | - signal playFocusAnimation(int index) |
4298 | - |
4299 | - function show() { |
4300 | - spreadContainer.animateIn = true; |
4301 | - root.state = "altTab"; |
4302 | - } |
4303 | - |
4304 | - onFocusChanged: { |
4305 | - // When the spread comes active, we want to keep focus to the input handler below |
4306 | - // Make sure nothing inside the ApplicationWindow grabs our focus! |
4307 | - if (focus) { |
4308 | - forceActiveFocus(); |
4309 | - } |
4310 | - } |
4311 | - |
4312 | - Keys.onPressed: { |
4313 | - switch (event.key) { |
4314 | - case Qt.Key_Left: |
4315 | - case Qt.Key_Backtab: |
4316 | - selectPrevious(event.isAutoRepeat) |
4317 | - event.accepted = true; |
4318 | - break; |
4319 | - case Qt.Key_Right: |
4320 | - case Qt.Key_Tab: |
4321 | - selectNext(event.isAutoRepeat) |
4322 | - event.accepted = true; |
4323 | - break; |
4324 | - case Qt.Key_Escape: |
4325 | - spreadRepeater.highlightedIndex = -1 |
4326 | - // Falling through intentionally |
4327 | - case Qt.Key_Enter: |
4328 | - case Qt.Key_Return: |
4329 | - case Qt.Key_Space: |
4330 | - root.state = "" |
4331 | - event.accepted = true; |
4332 | - } |
4333 | - } |
4334 | - |
4335 | - function selectNext(isAutoRepeat) { |
4336 | - if (isAutoRepeat && spreadRepeater.highlightedIndex >= topLevelSurfaceList.count -1) { |
4337 | - return; // AutoRepeat is not allowed to wrap around |
4338 | - } |
4339 | - |
4340 | - spreadRepeater.highlightedIndex = (spreadRepeater.highlightedIndex + 1) % topLevelSurfaceList.count; |
4341 | - var newContentX = ((spreadFlickable.contentWidth) / (topLevelSurfaceList.count + 1)) * Math.max(0, Math.min(topLevelSurfaceList.count - 5, spreadRepeater.highlightedIndex - 3)); |
4342 | - if (spreadFlickable.contentX < newContentX || spreadRepeater.highlightedIndex == 0) { |
4343 | - spreadFlickable.snapTo(newContentX) |
4344 | - } |
4345 | - } |
4346 | - |
4347 | - function selectPrevious(isAutoRepeat) { |
4348 | - if (isAutoRepeat && spreadRepeater.highlightedIndex == 0) { |
4349 | - return; // AutoRepeat is not allowed to wrap around |
4350 | - } |
4351 | - |
4352 | - var newIndex = spreadRepeater.highlightedIndex - 1 >= 0 ? spreadRepeater.highlightedIndex - 1 : topLevelSurfaceList.count - 1; |
4353 | - spreadRepeater.highlightedIndex = newIndex; |
4354 | - var newContentX = ((spreadFlickable.contentWidth) / (topLevelSurfaceList.count + 1)) * Math.max(0, Math.min(topLevelSurfaceList.count - 5, spreadRepeater.highlightedIndex - 1)); |
4355 | - if (spreadFlickable.contentX > newContentX || newIndex == topLevelSurfaceList.count -1) { |
4356 | - spreadFlickable.snapTo(newContentX) |
4357 | - } |
4358 | - } |
4359 | - |
4360 | - function focusSelected() { |
4361 | - if (spreadRepeater.highlightedIndex != -1) { |
4362 | - if (spreadContainer.visible) { |
4363 | - root.playFocusAnimation(spreadRepeater.highlightedIndex) |
4364 | - } |
4365 | - var surface = topLevelSurfaceList.surfaceAt(spreadRepeater.highlightedIndex); |
4366 | - surface.requestFocus(); |
4367 | - } |
4368 | - } |
4369 | - |
4370 | - function cancel() { |
4371 | - spreadRepeater.highlightedIndex = -1; |
4372 | - state = "" |
4373 | - } |
4374 | - |
4375 | - BlurLayer { |
4376 | - id: blurLayer |
4377 | - anchors.fill: parent |
4378 | - source: root.workspace |
4379 | - visible: false |
4380 | - } |
4381 | - |
4382 | - Rectangle { |
4383 | - id: spreadBackground |
4384 | - anchors.fill: parent |
4385 | - color: "#B2000000" |
4386 | - visible: false |
4387 | - opacity: visible ? 1 : 0 |
4388 | - Behavior on opacity { |
4389 | - UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } |
4390 | - } |
4391 | - } |
4392 | - |
4393 | - MouseArea { |
4394 | - id: eventEater |
4395 | - anchors.fill: parent |
4396 | - visible: spreadBackground.visible |
4397 | - enabled: visible |
4398 | - acceptedButtons: Qt.AllButtons |
4399 | - onWheel: wheel.accepted = true; |
4400 | - } |
4401 | - |
4402 | - Item { |
4403 | - id: spreadContainer |
4404 | - objectName: "spreadContainer" |
4405 | - anchors.fill: parent |
4406 | - visible: false |
4407 | - |
4408 | - property bool animateIn: false |
4409 | - |
4410 | - Repeater { |
4411 | - id: spreadRepeater |
4412 | - objectName: "spreadRepeater" |
4413 | - model: topLevelSurfaceList |
4414 | - |
4415 | - property int highlightedIndex: -1 |
4416 | - property int closingIndex: -1 |
4417 | - |
4418 | - function indexOf(delegateItem) { |
4419 | - for (var i = 0; i < spreadRepeater.count; i++) { |
4420 | - if (spreadRepeater.itemAt(i) === delegateItem) { |
4421 | - return i; |
4422 | - } |
4423 | - } |
4424 | - return -1; |
4425 | - } |
4426 | - |
4427 | - delegate: Item { |
4428 | - id: spreadDelegate |
4429 | - objectName: "spreadDelegate" |
4430 | - width: units.gu(20) |
4431 | - height: units.gu(20) |
4432 | - |
4433 | - property real angle: 0 |
4434 | - property real itemScale: 1 |
4435 | - property int itemScaleOriginX: 0 |
4436 | - property int itemScaleOriginY: 0 |
4437 | - |
4438 | - readonly property string windowTitle: clippedSpreadDelegate.window.title |
4439 | - |
4440 | - Behavior on x { |
4441 | - id: closeBehavior |
4442 | - enabled: spreadRepeater.closingIndex >= 0 |
4443 | - UbuntuNumberAnimation { |
4444 | - onRunningChanged: if (!running) spreadRepeater.closingIndex = -1 |
4445 | - } |
4446 | - } |
4447 | - |
4448 | - DesktopSpreadDelegate { |
4449 | - id: clippedSpreadDelegate |
4450 | - objectName: "clippedSpreadDelegate" |
4451 | - anchors.left: parent.left |
4452 | - anchors.top: parent.top |
4453 | - application: model.application |
4454 | - surface: model.surface |
4455 | - width: spreadMaths.spreadHeight |
4456 | - height: spreadMaths.spreadHeight |
4457 | - |
4458 | - transform: [ |
4459 | - Scale { |
4460 | - origin.x: itemScaleOriginX |
4461 | - origin.y: itemScaleOriginY |
4462 | - xScale: itemScale |
4463 | - yScale: itemScale |
4464 | - }, |
4465 | - Rotation { |
4466 | - origin { x: 0; y: (clippedSpreadDelegate.height - (clippedSpreadDelegate.height * itemScale / 2)) } |
4467 | - axis { x: 0; y: 1; z: 0 } |
4468 | - angle: spreadDelegate.angle |
4469 | - } |
4470 | - ] |
4471 | - |
4472 | - MouseArea { |
4473 | - id: spreadSelectArea |
4474 | - anchors.fill: parent |
4475 | - anchors.margins: -units.gu(2) |
4476 | - enabled: false |
4477 | - onClicked: { |
4478 | - spreadRepeater.highlightedIndex = index; |
4479 | - root.state = ""; |
4480 | - } |
4481 | - } |
4482 | - } |
4483 | - |
4484 | - SpreadMaths { |
4485 | - id: spreadMaths |
4486 | - flickable: spreadFlickable |
4487 | - itemIndex: index |
4488 | - totalItems: Math.max(6, topLevelSurfaceList.count) |
4489 | - sceneHeight: root.height |
4490 | - itemHeight: spreadDelegate.height |
4491 | - } |
4492 | - |
4493 | - states: [ |
4494 | - State { |
4495 | - name: "altTab"; when: root.state == "altTab" && spreadContainer.visible |
4496 | - PropertyChanges { |
4497 | - target: spreadDelegate |
4498 | - x: spreadMaths.animatedX |
4499 | - y: spreadMaths.animatedY + (spreadDelegate.height - clippedSpreadDelegate.height) - units.gu(2) |
4500 | - width: spreadMaths.spreadHeight |
4501 | - height: spreadMaths.sceneHeight |
4502 | - angle: spreadMaths.animatedAngle |
4503 | - itemScale: spreadMaths.scale |
4504 | - itemScaleOriginY: clippedSpreadDelegate.height / 2; |
4505 | - z: index |
4506 | - visible: spreadMaths.itemVisible |
4507 | - } |
4508 | - PropertyChanges { |
4509 | - target: clippedSpreadDelegate |
4510 | - highlightShown: index == spreadRepeater.highlightedIndex |
4511 | - state: "transformed" |
4512 | - shadowOpacity: spreadMaths.shadowOpacity |
4513 | - anchors.topMargin: units.gu(2) |
4514 | - } |
4515 | - PropertyChanges { |
4516 | - target: tileInfo |
4517 | - visible: true |
4518 | - opacity: spreadMaths.tileInfoOpacity |
4519 | - } |
4520 | - PropertyChanges { |
4521 | - target: spreadSelectArea |
4522 | - enabled: true |
4523 | - } |
4524 | - } |
4525 | - ] |
4526 | - transitions: [ |
4527 | - Transition { |
4528 | - from: "" |
4529 | - to: "altTab" |
4530 | - SequentialAnimation { |
4531 | - ParallelAnimation { |
4532 | - PropertyAction { target: spreadDelegate; properties: "y,height,width,angle,z,itemScale,itemScaleOriginY,visible" } |
4533 | - PropertyAction { target: clippedSpreadDelegate; properties: "anchors.topMargin" } |
4534 | - PropertyAnimation { |
4535 | - target: spreadDelegate; properties: "x" |
4536 | - from: root.width |
4537 | - duration: spreadContainer.animateIn ? UbuntuAnimation.FastDuration :0 |
4538 | - easing: UbuntuAnimation.StandardEasing |
4539 | - } |
4540 | - UbuntuNumberAnimation { target: clippedSpreadDelegate; property: "shadowOpacity"; from: 0; to: spreadMaths.shadowOpacity; duration: spreadContainer.animateIn ? UbuntuAnimation.FastDuration : 0 } |
4541 | - UbuntuNumberAnimation { target: tileInfo; property: "opacity"; from: 0; to: spreadMaths.tileInfoOpacity; duration: spreadContainer.animateIn ? UbuntuAnimation.FastDuration : 0 } |
4542 | - } |
4543 | - PropertyAction { target: spreadSelectArea; property: "enabled" } |
4544 | - } |
4545 | - } |
4546 | - ] |
4547 | - |
4548 | - MouseArea { |
4549 | - id: tileInfo |
4550 | - objectName: "tileInfo" |
4551 | - anchors { |
4552 | - left: parent.left |
4553 | - top: clippedSpreadDelegate.bottom |
4554 | - topMargin: ((spreadMaths.sceneHeight - spreadDelegate.y) - clippedSpreadDelegate.height) * 0.2 |
4555 | - } |
4556 | - property int nextItemX: spreadRepeater.count > index + 1 ? spreadRepeater.itemAt(index + 1).x : spreadDelegate.x + units.gu(30) |
4557 | - width: Math.min(units.gu(30), nextItemX - spreadDelegate.x) |
4558 | - height: titleInfoColumn.height |
4559 | - visible: false |
4560 | - hoverEnabled: true |
4561 | - |
4562 | - onContainsMouseChanged: { |
4563 | - if (containsMouse) { |
4564 | - spreadRepeater.highlightedIndex = index |
4565 | - } |
4566 | - } |
4567 | - |
4568 | - onClicked: { |
4569 | - root.state = "" |
4570 | - } |
4571 | - |
4572 | - ColumnLayout { |
4573 | - id: titleInfoColumn |
4574 | - anchors { left: parent.left; top: parent.top; right: parent.right } |
4575 | - spacing: units.gu(1) |
4576 | - |
4577 | - UbuntuShapeForItem { |
4578 | - Layout.preferredHeight: Math.min(units.gu(6), root.height * .05) |
4579 | - Layout.preferredWidth: height * 8 / 7.6 |
4580 | - image: Image { |
4581 | - anchors.fill: parent |
4582 | - source: model.application.icon |
4583 | - Rectangle { |
4584 | - anchors.fill: parent |
4585 | - color: "black" |
4586 | - opacity: clippedSpreadDelegate.highlightShown ? 0 : .1 |
4587 | - Behavior on opacity { |
4588 | - UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } |
4589 | - } |
4590 | - } |
4591 | - } |
4592 | - } |
4593 | - Label { |
4594 | - Layout.fillWidth: true |
4595 | - Layout.preferredHeight: units.gu(6) |
4596 | - text: model.application ? model.application.name : spreadDelegate.windowTitle |
4597 | - wrapMode: Text.WordWrap |
4598 | - elide: Text.ElideRight |
4599 | - maximumLineCount: 2 |
4600 | - } |
4601 | - } |
4602 | - } |
4603 | - |
4604 | - Image { |
4605 | - id: closeImage |
4606 | - anchors { left: parent.left; top: parent.top; leftMargin: -height / 2; topMargin: -height / 2 + spreadMaths.closeIconOffset + units.gu(2) } |
4607 | - source: "graphics/window-close.svg" |
4608 | - readonly property var mousePos: hoverMouseArea.mapToItem(spreadDelegate, hoverMouseArea.mouseX, hoverMouseArea.mouseY) |
4609 | - visible: index == spreadRepeater.highlightedIndex |
4610 | - && mousePos.y < (clippedSpreadDelegate.height / 3) |
4611 | - && mousePos.y > -units.gu(4) |
4612 | - && mousePos.x > -units.gu(4) |
4613 | - && mousePos.x < (clippedSpreadDelegate.width * 2 / 3) |
4614 | - height: units.gu(1.5) |
4615 | - width: height |
4616 | - sourceSize.width: width |
4617 | - sourceSize.height: height |
4618 | - |
4619 | - MouseArea { |
4620 | - id: closeMouseArea |
4621 | - objectName: "closeMouseArea" |
4622 | - anchors.fill: closeImage |
4623 | - anchors.margins: -units.gu(2) |
4624 | - onClicked: { |
4625 | - spreadRepeater.closingIndex = index; |
4626 | - model.surface.close(); |
4627 | - } |
4628 | - } |
4629 | - } |
4630 | - } |
4631 | - } |
4632 | - } |
4633 | - |
4634 | - |
4635 | - MouseArea { |
4636 | - id: hoverMouseArea |
4637 | - objectName: "hoverMouseArea" |
4638 | - anchors.fill: spreadContainer |
4639 | - propagateComposedEvents: true |
4640 | - hoverEnabled: true |
4641 | - enabled: false |
4642 | - visible: enabled |
4643 | - |
4644 | - property int scrollAreaWidth: root.width / 3 |
4645 | - property bool progressiveScrollingEnabled: false |
4646 | - |
4647 | - onMouseXChanged: { |
4648 | - mouse.accepted = false |
4649 | - |
4650 | - if (hoverMouseArea.pressed) { |
4651 | - return; |
4652 | - } |
4653 | - |
4654 | - // Find the hovered item and mark it active |
4655 | - var mapped = mapToItem(spreadContainer, hoverMouseArea.mouseX, hoverMouseArea.mouseY) |
4656 | - var itemUnder = spreadContainer.childAt(mapped.x, mapped.y) |
4657 | - if (itemUnder) { |
4658 | - mapped = mapToItem(itemUnder, hoverMouseArea.mouseX, hoverMouseArea.mouseY) |
4659 | - var delegateChild = itemUnder.childAt(mapped.x, mapped.y) |
4660 | - if (delegateChild && (delegateChild.objectName === "clippedSpreadDelegate" || delegateChild.objectName === "tileInfo")) { |
4661 | - spreadRepeater.highlightedIndex = spreadRepeater.indexOf(itemUnder) |
4662 | - } |
4663 | - } |
4664 | - |
4665 | - if (spreadFlickable.contentWidth > spreadFlickable.minContentWidth) { |
4666 | - var margins = spreadFlickable.width * 0.05; |
4667 | - |
4668 | - if (!progressiveScrollingEnabled && mouseX < spreadFlickable.width - scrollAreaWidth) { |
4669 | - progressiveScrollingEnabled = true |
4670 | - } |
4671 | - |
4672 | - // do we need to scroll? |
4673 | - if (mouseX < scrollAreaWidth + margins) { |
4674 | - var progress = Math.min(1, (scrollAreaWidth + margins - mouseX) / (scrollAreaWidth - margins)); |
4675 | - var contentX = (1 - progress) * (spreadFlickable.contentWidth - spreadFlickable.width) |
4676 | - spreadFlickable.contentX = Math.max(0, Math.min(spreadFlickable.contentX, contentX)) |
4677 | - } |
4678 | - if (mouseX > spreadFlickable.width - scrollAreaWidth && progressiveScrollingEnabled) { |
4679 | - var progress = Math.min(1, (mouseX - (spreadFlickable.width - scrollAreaWidth)) / (scrollAreaWidth - margins)) |
4680 | - var contentX = progress * (spreadFlickable.contentWidth - spreadFlickable.width) |
4681 | - spreadFlickable.contentX = Math.min(spreadFlickable.contentWidth - spreadFlickable.width, Math.max(spreadFlickable.contentX, contentX)) |
4682 | - } |
4683 | - } |
4684 | - } |
4685 | - onPressed: mouse.accepted = false |
4686 | - } |
4687 | - |
4688 | - FloatingFlickable { |
4689 | - id: spreadFlickable |
4690 | - objectName: "spreadFlickable" |
4691 | - anchors.fill: parent |
4692 | - property int minContentWidth: 6 * Math.min(height / 4, width / 5) |
4693 | - contentWidth: Math.max(6, topLevelSurfaceList.count) * Math.min(height / 4, width / 5) |
4694 | - enabled: false |
4695 | - |
4696 | - function snapTo(contentX) { |
4697 | - snapAnimation.stop(); |
4698 | - snapAnimation.to = contentX |
4699 | - snapAnimation.start(); |
4700 | - } |
4701 | - |
4702 | - UbuntuNumberAnimation { |
4703 | - id: snapAnimation |
4704 | - target: spreadFlickable |
4705 | - property: "contentX" |
4706 | - } |
4707 | - } |
4708 | - |
4709 | - Item { |
4710 | - id: workspaceSelector |
4711 | - anchors { |
4712 | - left: parent.left |
4713 | - top: parent.top |
4714 | - right: parent.right |
4715 | - topMargin: units.gu(3.5) |
4716 | - } |
4717 | - height: root.height * 0.25 |
4718 | - visible: false |
4719 | - |
4720 | - RowLayout { |
4721 | - anchors.fill: parent |
4722 | - spacing: units.gu(1) |
4723 | - Item { Layout.fillWidth: true } |
4724 | - Repeater { |
4725 | - model: 1 // TODO: will be a workspacemodel in the future |
4726 | - Item { |
4727 | - Layout.fillHeight: true |
4728 | - Layout.preferredWidth: ((height - units.gu(6)) * root.width / root.height) |
4729 | - Image { |
4730 | - source: root.background |
4731 | - anchors { |
4732 | - left: parent.left |
4733 | - right: parent.right |
4734 | - verticalCenter: parent.verticalCenter |
4735 | - } |
4736 | - height: parent.height * 0.75 |
4737 | - |
4738 | - ShaderEffect { |
4739 | - anchors.fill: parent |
4740 | - |
4741 | - property var source: ShaderEffectSource { |
4742 | - id: shaderEffectSource |
4743 | - sourceItem: root.workspace |
4744 | - } |
4745 | - |
4746 | - fragmentShader: " |
4747 | - varying highp vec2 qt_TexCoord0; |
4748 | - uniform sampler2D source; |
4749 | - void main(void) |
4750 | - { |
4751 | - highp vec4 sourceColor = texture2D(source, qt_TexCoord0); |
4752 | - gl_FragColor = sourceColor; |
4753 | - }" |
4754 | - } |
4755 | - } |
4756 | - |
4757 | - // TODO: This is the bar for the currently selected workspace |
4758 | - // Enable this once the workspace stuff is implemented |
4759 | - // Rectangle { |
4760 | - // anchors { left: parent.left; right: parent.right; bottom: parent.bottom } |
4761 | - // height: units.dp(2) |
4762 | - // color: theme.palette.normal.focus |
4763 | - // visible: index == 0 // TODO: should be active workspace index |
4764 | - // } |
4765 | - } |
4766 | - |
4767 | - } |
4768 | - // TODO: This is the "new workspace" button. Enable this once workspaces are implemented |
4769 | - // Item { |
4770 | - // Layout.fillHeight: true |
4771 | - // Layout.preferredWidth: ((height - units.gu(6)) * root.width / root.height) |
4772 | - // Rectangle { |
4773 | - // anchors { |
4774 | - // left: parent.left |
4775 | - // right: parent.right |
4776 | - // verticalCenter: parent.verticalCenter |
4777 | - // } |
4778 | - // height: parent.height * 0.75 |
4779 | - // color: "#22ffffff" |
4780 | - |
4781 | - // Label { |
4782 | - // anchors.centerIn: parent |
4783 | - // font.pixelSize: parent.height / 2 |
4784 | - // text: "+" |
4785 | - // } |
4786 | - // } |
4787 | - // } |
4788 | - Item { Layout.fillWidth: true } |
4789 | - } |
4790 | - } |
4791 | - |
4792 | - Label { |
4793 | - id: currentSelectedLabel |
4794 | - anchors { bottom: parent.bottom; bottomMargin: root.height * 0.625; horizontalCenter: parent.horizontalCenter } |
4795 | - text: spreadRepeater.highlightedIndex >= 0 ? spreadRepeater.itemAt(spreadRepeater.highlightedIndex).windowTitle: "" |
4796 | - visible: false |
4797 | - fontSize: "large" |
4798 | - } |
4799 | - |
4800 | - states: [ |
4801 | - State { |
4802 | - name: "altTab"; when: root.altTabPressed |
4803 | - PropertyChanges { target: blurLayer; saturation: 0.8; blurRadius: 60; visible: true } |
4804 | - PropertyChanges { target: workspaceSelector; visible: true } |
4805 | - PropertyChanges { target: spreadContainer; visible: true } |
4806 | - PropertyChanges { target: spreadFlickable; enabled: spreadFlickable.contentWidth > spreadFlickable.minContentWidth } |
4807 | - PropertyChanges { target: currentSelectedLabel; visible: true } |
4808 | - PropertyChanges { target: spreadBackground; visible: true } |
4809 | - PropertyChanges { target: hoverMouseArea; enabled: true } |
4810 | - } |
4811 | - ] |
4812 | - transitions: [ |
4813 | - Transition { |
4814 | - from: "*" |
4815 | - to: "altTab" |
4816 | - SequentialAnimation { |
4817 | - PropertyAction { target: spreadRepeater; property: "highlightedIndex"; value: Math.min(topLevelSurfaceList.count - 1, 1) } |
4818 | - PauseAnimation { duration: spreadContainer.animateIn ? 0 : 140 } |
4819 | - PropertyAction { target: workspaceSelector; property: "visible" } |
4820 | - PropertyAction { target: spreadContainer; property: "visible" } |
4821 | - ParallelAnimation { |
4822 | - UbuntuNumberAnimation { target: blurLayer; properties: "saturation,blurRadius"; duration: UbuntuAnimation.SnapDuration } |
4823 | - PropertyAction { target: spreadFlickable; property: "visible" } |
4824 | - PropertyAction { targets: [currentSelectedLabel,spreadBackground]; property: "visible" } |
4825 | - PropertyAction { target: spreadFlickable; property: "contentX"; value: 0 } |
4826 | - } |
4827 | - PropertyAction { target: hoverMouseArea; properties: "enabled,progressiveScrollingEnabled"; value: false } |
4828 | - } |
4829 | - }, |
4830 | - Transition { |
4831 | - from: "*" |
4832 | - to: "*" |
4833 | - PropertyAnimation { property: "opacity" } |
4834 | - ScriptAction { script: { root.focusSelected() } } |
4835 | - PropertyAction { target: spreadRepeater; property: "highlightedIndex"; value: -1 } |
4836 | - PropertyAction { target: spreadContainer; property: "animateIn"; value: false } |
4837 | - } |
4838 | - ] |
4839 | -} |
4840 | |
4841 | === removed file 'qml/Stages/DesktopSpreadDelegate.qml' |
4842 | --- qml/Stages/DesktopSpreadDelegate.qml 2016-05-17 20:46:51 +0000 |
4843 | +++ qml/Stages/DesktopSpreadDelegate.qml 1970-01-01 00:00:00 +0000 |
4844 | @@ -1,126 +0,0 @@ |
4845 | -/* |
4846 | - * Copyright (C) 2014-2016 Canonical, Ltd. |
4847 | - * |
4848 | - * This program is free software; you can redistribute it and/or modify |
4849 | - * it under the terms of the GNU General Public License as published by |
4850 | - * the Free Software Foundation; version 3. |
4851 | - * |
4852 | - * This program is distributed in the hope that it will be useful, |
4853 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4854 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4855 | - * GNU General Public License for more details. |
4856 | - * |
4857 | - * You should have received a copy of the GNU General Public License |
4858 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4859 | - * |
4860 | - * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
4861 | - */ |
4862 | - |
4863 | -import QtQuick 2.4 |
4864 | -import Ubuntu.Components 1.3 |
4865 | -import Unity.Application 0.1 |
4866 | - |
4867 | -Item { |
4868 | - id: root |
4869 | - |
4870 | - property alias window: applicationWindow |
4871 | - property alias application: applicationWindow.application |
4872 | - property alias surface: applicationWindow.surface |
4873 | - |
4874 | - property bool highlightShown: false |
4875 | - property real shadowOpacity: 1 |
4876 | - |
4877 | - property int windowWidth: surface ? surface.size.width : 0 |
4878 | - property int windowHeight: surface ? surface.size.height : 0 |
4879 | - |
4880 | - state: "normal" |
4881 | - states: [ |
4882 | - State { |
4883 | - name: "normal" |
4884 | - PropertyChanges { |
4885 | - target: root |
4886 | - width: windowWidth |
4887 | - height: windowHeight |
4888 | - } |
4889 | - }, |
4890 | - State { |
4891 | - name: "transformed" |
4892 | - PropertyChanges { |
4893 | - target: applicationWindow |
4894 | - itemScale: Math.max(root.width / root.windowWidth, root.height / root.windowHeight) |
4895 | - interactive: false |
4896 | - } |
4897 | - PropertyChanges { |
4898 | - target: clipper |
4899 | - clip: true |
4900 | - } |
4901 | - } |
4902 | - ] |
4903 | - |
4904 | - scale: highlightShown ? 1.025 : 1 |
4905 | - Behavior on scale { |
4906 | - UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } |
4907 | - } |
4908 | - |
4909 | - BorderImage { |
4910 | - anchors { |
4911 | - fill: root |
4912 | - margins: -units.gu(2) |
4913 | - } |
4914 | - source: "graphics/dropshadow2gu.sci" |
4915 | - opacity: root.shadowOpacity * .3 |
4916 | - } |
4917 | - |
4918 | - Rectangle { |
4919 | - id: selectionHighlight |
4920 | - anchors.fill: parent |
4921 | - anchors.margins: -units.gu(1) |
4922 | - color: "white" |
4923 | - opacity: highlightShown ? 0.55 : 0 |
4924 | - antialiasing: true |
4925 | - } |
4926 | - |
4927 | - Rectangle { |
4928 | - anchors { left: selectionHighlight.left; right: selectionHighlight.right; bottom: selectionHighlight.bottom; } |
4929 | - height: units.dp(2) |
4930 | - color: theme.palette.normal.focus |
4931 | - visible: root.highlightShown |
4932 | - antialiasing: true |
4933 | - } |
4934 | - |
4935 | - Item { |
4936 | - id: clipper |
4937 | - anchors.fill: parent |
4938 | - |
4939 | - ApplicationWindow { |
4940 | - id: applicationWindow |
4941 | - objectName: application ? "appWindow_" + application.appId : "appWindow_null" |
4942 | - anchors.top: parent.top |
4943 | - anchors.topMargin: 0 |
4944 | - anchors.left: parent.left |
4945 | - width: root.windowWidth |
4946 | - height: root.windowHeight |
4947 | - interactive: false |
4948 | - resizeSurface: false |
4949 | - focus: false |
4950 | - |
4951 | - property real itemScale: 1 |
4952 | - transform: [ |
4953 | - Scale { |
4954 | - origin.x: 0; origin.y: 0 |
4955 | - xScale: applicationWindow.itemScale |
4956 | - yScale: applicationWindow.itemScale |
4957 | - } |
4958 | - ] |
4959 | - } |
4960 | - } |
4961 | - |
4962 | - Rectangle { |
4963 | - anchors.fill: parent |
4964 | - color: "black" |
4965 | - opacity: root.highlightShown ? 0 : .1 |
4966 | - Behavior on opacity { |
4967 | - UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } |
4968 | - } |
4969 | - } |
4970 | -} |
4971 | |
4972 | === removed file 'qml/Stages/PhoneStage.qml' |
4973 | --- qml/Stages/PhoneStage.qml 2016-08-08 11:18:19 +0000 |
4974 | +++ qml/Stages/PhoneStage.qml 1970-01-01 00:00:00 +0000 |
4975 | @@ -1,806 +0,0 @@ |
4976 | -/* |
4977 | - * Copyright (C) 2014-2016 Canonical, Ltd. |
4978 | - * |
4979 | - * This program is free software; you can redistribute it and/or modify |
4980 | - * it under the terms of the GNU General Public License as published by |
4981 | - * the Free Software Foundation; version 3. |
4982 | - * |
4983 | - * This program is distributed in the hope that it will be useful, |
4984 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4985 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4986 | - * GNU General Public License for more details. |
4987 | - * |
4988 | - * You should have received a copy of the GNU General Public License |
4989 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4990 | - */ |
4991 | - |
4992 | -import QtQuick 2.4 |
4993 | -import Ubuntu.Components 1.3 |
4994 | -import Ubuntu.Gestures 0.1 |
4995 | -import Unity.Application 0.1 |
4996 | -import Unity.Session 0.1 |
4997 | -import Utils 0.1 |
4998 | -import Powerd 0.1 |
4999 | -import "../Components" |
5000 | - |
FAILED: Continuous integration, rev:2509 /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2167/ /unity8- jenkins. ubuntu. com/job/ build/2848/ console /unity8- jenkins. ubuntu. com/job/ build-0- fetch/2876 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 2734/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 2734/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= yakkety/ 2734/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 2734/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 2734/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= yakkety/ 2734/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 2734/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 2734/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= yakkety/ 2734/console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2167/ rebuild
https:/