on xenial help sign in
Shell chrome fixes

Correctly save and load the window state from storage, do not restore our QML window right away but queue the state, filter it with the shell chrome policy (when in windowed mode) later on, and then apply it at altogether, once the surface creation is settled. For a more elegant longterm fix, we should probably introduce "initialSurfaceState" in qtmir, much like the recent "initialSurfaceSize" so that the window/surface gets the correct state right from the beginning. (LP: #1658117, #1665723, #1665724, #1669010) Approved by: Michael Zanetti, Unity8 CI Bot

commit64ed07f9c2949f27ae689a2a8cf156e44efc81b8 authorLukáš Tinkl <lukas.tinkl@canonical.com> dateWed 8 Mar 2017, 09:50 (10 years ago) parent73a64d5d336bf8
9 files changed+54−57
qml/Stage/ApplicationWindow.qml+1 qml/Stage/Stage.qml+21−11 qml/Stage/StagedFullscreenPolicy.qml+5−11 qml/Stage/WindowStateSaver.qml+4−3 qml/Stage/WindowedFullscreenPolicy.qml+4−12 tests/mocks/Unity/Application/ApplicationManager.cpp+1 tests/qmltests/Stage/tst_DesktopStage.qml+3−3 tests/qmltests/tst_OrientedShell.qml+5−3 tests/qmltests/tst_Shell.qml+10−14
qml/Stage/ApplicationWindow.qml+1
@@ -28,6 +28,7 @@ FocusScope {
2828 property bool orientationChangesEnabled: d.supportsSurfaceResize ? d.surfaceOldEnoughToBeResized : true
2929 readonly property string title: surface && surface.name !== "" ? surface.name : d.name
3030 readonly property QtObject focusedSurface: d.focusedSurface.surface
31+ readonly property alias surfaceInitialized: d.surfaceInitialized
3132
3233 // to be set from outside
3334 property QtObject surface
qml/Stage/Stage.qml+21−11
@@ -470,7 +470,7 @@ FocusScope {
470470 extend: "stagedRightEdge"
471471 PropertyChanges {
472472 target: sideStage
473− opacity: priv.sideStageDelegate.x === sideStage.x ? 1 : 0
473+ opacity: priv.sideStageDelegate && priv.sideStageDelegate.x === sideStage.x ? 1 : 0
474474 visible: true
475475 }
476476 },
@@ -723,6 +723,7 @@ FocusScope {
723723 // miral doesn't know about our window decorations. So we have to deduct them
724724 value: Qt.point(appDelegate.requestedX + appDelegate.clientAreaItem.x,
725725 appDelegate.requestedY + appDelegate.clientAreaItem.y)
726+ when: root.mode == "windowed"
726727 }
727728
728729 // In those are for windowed mode. Those values basically store the window's properties
@@ -768,7 +769,6 @@ FocusScope {
768769 Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
769770 when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored")
770771 && root.inputMethodRect.height > 0
771−
772772 }
773773
774774 Behavior on x { id: xBehavior; enabled: priv.closingIndex >= 0; UbuntuNumberAnimation { onRunningChanged: if (!running) priv.closingIndex = -1} }
@@ -933,7 +933,8 @@ FocusScope {
933933 } else if (model.window.state === Mir.MaximizedBottomRightState) {
934934 appDelegate.maximizeBottomRight();
935935 } else if (model.window.state === Mir.RestoredState) {
936− if (appDelegate.fullscreen && appDelegate.prevWindowState != WindowStateStorage.WindowStateRestored) {
936+ if (appDelegate.fullscreen && appDelegate.prevWindowState != WindowStateStorage.WindowStateRestored
937+ && appDelegate.prevWindowState != WindowStateStorage.WindowStateNormal) {
937938 model.window.requestState(WindowStateStorage.toMirState(appDelegate.prevWindowState));
938939 } else {
939940 appDelegate.restore();
@@ -945,6 +946,21 @@ FocusScope {
945946 }
946947 }
947948
949+ readonly property bool windowReady: clientAreaItem.surfaceInitialized
950+ onWindowReadyChanged: {
951+ if (windowReady) {
952+ var loadedMirState = WindowStateStorage.toMirState(windowStateSaver.loadedState);
953+ // need to apply the shell chrome policy on top the saved window state
954+ var policy;
955+ if (root.mode == "windowed") {
956+ policy = windowedFullscreenPolicy;
957+ } else {
958+ policy = stagedFullscreenPolicy
959+ }
960+ window.requestState(policy.applyPolicy(loadedMirState, surface.shellChrome));
961+ }
962+ }
963+
948964 Component.onCompleted: {
949965 if (application && application.rotatesWindowContents) {
950966 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
@@ -957,7 +973,6 @@ FocusScope {
957973 windowedY = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedY + units.gu(3) : normalZ * units.gu(3)
958974 // Now load any saved state. This needs to happen *after* the cascading!
959975 windowStateSaver.load();
960− model.window.requestState(WindowStateStorage.toMirState(windowState));
961976
962977 updateQmlFocusFromMirSurfaceFocus();
963978
@@ -1441,7 +1456,7 @@ FocusScope {
14411456 ]
14421457 transitions: [
14431458 Transition {
1444− from: "staged,stagedWithSideStage"; to: "normal"
1459+ from: "staged,stagedWithSideStage"
14451460 enabled: appDelegate.animationsEnabled
14461461 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
14471462 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedX,requestedY,opacity,requestedWidth,requestedHeight,scale"; duration: priv.animationDuration }
@@ -1462,8 +1477,7 @@ FocusScope {
14621477 },
14631478 Transition {
14641479 from: "normal,staged"; to: "stagedWithSideStage"
1465− UbuntuNumberAnimation { target: appDelegate; properties: "x,y"; duration: priv.animationDuration }
1466− UbuntuNumberAnimation { target: appDelegate; properties: "requestedWidth,requestedHeight"; duration: priv.animationDuration }
1480+ UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedWidth,requestedHeight"; duration: priv.animationDuration }
14671481 },
14681482 Transition {
14691483 to: "windowedRightEdge"
@@ -1503,7 +1517,6 @@ FocusScope {
15031517 from: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
15041518 to: "minimized"
15051519 SequentialAnimation {
1506− ScriptAction { script: print("transitioning:", appDelegate.x, appDelegate.y, appDelegate.scale) }
15071520 ScriptAction { script: { fakeRectangle.stop(); } }
15081521 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
15091522 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,scale,opacity"; duration: priv.animationDuration }
@@ -1514,7 +1527,6 @@ FocusScope {
15141527 from: "minimized"
15151528 to: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
15161529 SequentialAnimation {
1517− ScriptAction { script: print("transitioning:", appDelegate.x, appDelegate.y, appDelegate.scale) }
15181530 PropertyAction { target: appDelegate; property: "visuallyMinimized,z" }
15191531 ParallelAnimation {
15201532 UbuntuNumberAnimation { target: appDelegate; properties: "x"; from: -appDelegate.width / 2; duration: priv.animationDuration }
@@ -1661,8 +1673,6 @@ FocusScope {
16611673
16621674 WindowedFullscreenPolicy {
16631675 id: windowedFullscreenPolicy
1664− active: root.mode == "windowed"
1665− surface: model.window.surface
16661676 }
16671677 StagedFullscreenPolicy {
16681678 id: stagedFullscreenPolicy
qml/Stage/StagedFullscreenPolicy.qml+5−11
@@ -28,14 +28,14 @@ import Unity.Application 0.1
2828QtObject {
2929 property bool active: true
3030
31− property var surface: null
32− onSurfaceChanged: {
33− if (!active || !surface) return;
34− if (surface.shellChrome === Mir.LowChrome) {
35− surface.requestState(Mir.FullscreenState);
31+ function applyPolicy(surfaceState, surfaceChrome) {
32+ if (surfaceChrome === Mir.LowChrome) {
33+ return Mir.FullscreenState;
3634 }
35+ return surfaceState;
3736 }
3837
38+ property var surface: null
3939 property var _connections: Connections {
4040 target: surface
4141 onShellChromeChanged: {
@@ -46,11 +46,5 @@ QtObject {
4646 surface.requestState(Mir.RestoredState);
4747 }
4848 }
49− onStateChanged: {
50− if (!active) return;
51− if (surface.state === Mir.RestoredState && surface.shellChrome === Mir.LowChrome) {
52− surface.requestState(Mir.FullscreenState);
53− }
54− }
5549 }
5650}
qml/Stage/WindowStateSaver.qml+4−3
@@ -28,6 +28,8 @@ QtObject {
2828 property int leftMargin: 0
2929 property int minimumY: 0
3030
31+ property int loadedState
32+
3133 function load() {
3234 var defaultWidth = units.gu(60);
3335 var defaultHeight = units.gu(50);
@@ -41,14 +43,13 @@ QtObject {
4143 (target.fullscreen ? 0 : root.leftMargin)); });
4244 target.windowedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, screenHeight - target.windowedHeight), minimumY); });
4345
44− var windowState = WindowStateStorage.getState(target.appId, WindowStateStorage.WindowStateNormal)
45− target.restore(false /* animated */, windowState);
46−
4746 target.updateNormalGeometry();
4847
4948 // initialize the x/y to restore to
5049 target.restoredX = target.normalX;
5150 target.restoredY = target.normalY;
51+
52+ loadedState = WindowStateStorage.getState(target.appId, WindowStateStorage.WindowStateNormal);
5253 }
5354
5455 function save() {
qml/Stage/WindowedFullscreenPolicy.qml+4−12
@@ -22,18 +22,10 @@ import Unity.Application 0.1
2222// On first surface load; if the surface is set to low chrome & fullscreen, the
2323// state of the window is returned to restored.
2424QtObject {
25− property bool active: true
26− property QtObject surface: null
27−
28− property bool _firstTimeSurface: true
29−
30− onSurfaceChanged: {
31− if (!active || !surface) return;
32− if (!_firstTimeSurface) return;
33− _firstTimeSurface = false;
34−
35− if (surface.state === Mir.FullscreenState && surface.shellChrome === Mir.LowChrome) {
36− surface.requestState(Mir.RestoredState);
25+ function applyPolicy(surfaceState, surfaceChrome) {
26+ if (surfaceState === Mir.FullscreenState && surfaceChrome === Mir.LowChrome) {
27+ return Mir.RestoredState;
3728 }
29+ return surfaceState;
3830 }
3931}
tests/mocks/Unity/Application/ApplicationManager.cpp+1
@@ -337,6 +337,7 @@ void ApplicationManager::buildListOfAvailableApplications()
337337 application->setScreenshotId("camera");
338338 application->setIconId("camera");
339339 application->setFullscreen(true);
340+ application->setShellChrome(Mir::LowChrome);
340341 application->setSupportedOrientations(Qt::PortraitOrientation
341342 | Qt::LandscapeOrientation
342343 | Qt::InvertedPortraitOrientation
tests/qmltests/Stage/tst_DesktopStage.qml+3−3
@@ -321,7 +321,7 @@ Item {
321321 var maximizeButton = findChild(appDelegate, "maximizeWindowButton");
322322 verify(maximizeButton);
323323 mouseClick(maximizeButton);
324− tryCompare(appDelegate, "visuallyMaximized", true);
324+ tryCompare(appDelegate, "maximized", true);
325325 }
326326
327327 function test_tappingOnDecorationFocusesApplication(data) {
@@ -637,7 +637,7 @@ Item {
637637 var dialerAppDelegate = startApplication("dialer-app");
638638
639639 // verify the drop shadow becomes visible
640− verify(PanelState.dropShadow == true);
640+ tryCompareFunction(function() { return PanelState.dropShadow; }, true);
641641
642642 // close the maximized app
643643 ApplicationManager.stopApplication("facebook-webapp");
@@ -785,7 +785,7 @@ Item {
785785 waitUntilTransitionsEnd(dialerAppDelegate);
786786 waitUntilTransitionsEnd(stage);
787787
788− tryCompare(dialerAppDelegate, "state", "maximized");
788+ tryCompare(dialerAppDelegate, "maximized", true);
789789 }
790790
791791 function test_saveRestoreSize() {
tests/qmltests/tst_OrientedShell.qml+5−3
@@ -695,9 +695,11 @@ Rectangle {
695695 // false -> true -> false
696696 compare(transitionSpy.count, 2);
697697
698− // It should retain native dimensions regardless of its rotation/orientation
699− compare(cameraSurface.width, orientedShell.width);
700− compare(cameraSurface.height, orientedShell.height);
698+ if (!data.windowed) { // subject to shell-chrome policies
699+ // It should retain native dimensions regardless of its rotation/orientation
700+ compare(cameraSurface.width, orientedShell.width);
701+ compare(cameraSurface.height, orientedShell.height);
702+ }
701703
702704 // Surface focus shouldn't have been touched because of the rotation
703705 compare(focusChangedSpy.count, 0);
tests/qmltests/tst_Shell.qml+10−14
@@ -335,7 +335,7 @@ Rectangle {
335335
336336 Row {
337337 CheckBox {
338− id: fullscreeAppCheck
338+ id: fullscreenAppCheck
339339 activeFocusOnPress: false
340340 activeFocusOnTab: false
341341
@@ -349,13 +349,10 @@ Rectangle {
349349 }
350350
351351 Binding {
352− target: fullscreeAppCheck
352+ target: fullscreenAppCheck
353353 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow
354354 property: "checked"
355− value: {
356− if (!topLevelSurfaceList || !topLevelSurfaceList.focusedWindow) return false;
357− return topLevelSurfaceList.focusedWindow.state === Mir.FullscreenState
358− }
355+ value: topLevelSurfaceList.focusedWindow.state === Mir.FullscreenState
359356 }
360357 }
361358 Label {
@@ -366,6 +363,8 @@ Rectangle {
366363 Row {
367364 CheckBox {
368365 id: chromeAppCheck
366+ activeFocusOnPress: false
367+ activeFocusOnTab: false
369368
370369 onTriggered: {
371370 if (!topLevelSurfaceList.focusedWindow || !topLevelSurfaceList.focusedWindow.surface) return;
@@ -381,10 +380,8 @@ Rectangle {
381380 target: chromeAppCheck
382381 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow !== null && topLevelSurfaceList.focusedWindow.surface !== null
383382 property: "checked"
384− value: {
385− if (!topLevelSurfaceList || !topLevelSurfaceList.focusedWindow || !topLevelSurfaceList.focusedWindow.surface) return false;
386− topLevelSurfaceList.focusedWindow.surface.shellChrome === Mir.LowChrome
387− }
383+ value: topLevelSurfaceList.focusedWindow.surface &&
384+ topLevelSurfaceList.focusedWindow.surface.shellChrome === Mir.LowChrome
388385 }
389386 }
390387 Label {
@@ -2295,7 +2292,6 @@ Rectangle {
22952292 return [
22962293 { tag: "phone" },
22972294 { tag: "tablet" },
2298− { tag: "desktop" },
22992295 ]
23002296 }
23012297
@@ -2675,8 +2671,8 @@ Rectangle {
26752671 }
26762672
26772673 function test_cursorHidingWithFullscreenApp() {
2678− loadShell("desktop");
2679− shell.usageScenario = "desktop";
2674+ loadShell("phone");
2675+ shell.usageScenario = "phone";
26802676 waitForRendering(shell);
26812677 swipeAwayGreeter();
26822678
@@ -2780,7 +2776,7 @@ Rectangle {
27802776 tryCompare(stage, "state", "staged");
27812777
27822778 // Try by Super+W
2783− keyPress(Qt.Key_W, Qt.MetaModifier)
2779+ keyPress(Qt.Key_W, Qt.MetaModifier, 200);
27842780 tryCompare(stage, "state", data.spreadEnabled ? "spread" : "staged");
27852781 keyRelease(Qt.Key_W, Qt.MetaModifier)
27862782 }