on xenial help sign in
Shell chrome fixes
64ed07fLukáš Tinkl
qml/Stage/ApplicationWindow.qml+1
@@ -28,6 +28,7 @@ FocusScope {
28 property bool orientationChangesEnabled: d.supportsSurfaceResize ? d.surfaceOldEnoughToBeResized : true
28 property bool orientationChangesEnabled: d.supportsSurfaceResize ? d.surfaceOldEnoughToBeResized : true
29 readonly property string title: surface && surface.name !== "" ? surface.name : d.name
29 readonly property string title: surface && surface.name !== "" ? surface.name : d.name
30 readonly property QtObject focusedSurface: d.focusedSurface.surface
30 readonly property QtObject focusedSurface: d.focusedSurface.surface
31+ readonly property alias surfaceInitialized: d.surfaceInitialized
31
32
32 // to be set from outside
33 // to be set from outside
33 property QtObject surface
34 property QtObject surface
qml/Stage/Stage.qml+21−11
@@ -470,7 +470,7 @@ FocusScope {
470 extend: "stagedRightEdge"
470 extend: "stagedRightEdge"
471 PropertyChanges {
471 PropertyChanges {
472 target: sideStage
472 target: sideStage
473− opacity: priv.sideStageDelegate.x === sideStage.x ? 1 : 0
473+ opacity: priv.sideStageDelegate && priv.sideStageDelegate.x === sideStage.x ? 1 : 0
474 visible: true
474 visible: true
475 }
475 }
476 },
476 },
@@ -723,6 +723,7 @@ FocusScope {
723 // miral doesn't know about our window decorations. So we have to deduct them
723 // miral doesn't know about our window decorations. So we have to deduct them
724 value: Qt.point(appDelegate.requestedX + appDelegate.clientAreaItem.x,
724 value: Qt.point(appDelegate.requestedX + appDelegate.clientAreaItem.x,
725 appDelegate.requestedY + appDelegate.clientAreaItem.y)
725 appDelegate.requestedY + appDelegate.clientAreaItem.y)
726+ when: root.mode == "windowed"
726 }
727 }
727
728
728 // In those are for windowed mode. Those values basically store the window's properties
729 // In those are for windowed mode. Those values basically store the window's properties
@@ -768,7 +769,6 @@ FocusScope {
768 Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
769 Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
769 when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored")
770 when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored")
770 && root.inputMethodRect.height > 0
771 && root.inputMethodRect.height > 0
771−
772 }
772 }
773
773
774 Behavior on x { id: xBehavior; enabled: priv.closingIndex >= 0; UbuntuNumberAnimation { onRunningChanged: if (!running) priv.closingIndex = -1} }
774 Behavior on x { id: xBehavior; enabled: priv.closingIndex >= 0; UbuntuNumberAnimation { onRunningChanged: if (!running) priv.closingIndex = -1} }
@@ -933,7 +933,8 @@ FocusScope {
933 } else if (model.window.state === Mir.MaximizedBottomRightState) {
933 } else if (model.window.state === Mir.MaximizedBottomRightState) {
934 appDelegate.maximizeBottomRight();
934 appDelegate.maximizeBottomRight();
935 } else if (model.window.state === Mir.RestoredState) {
935 } 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) {
937 model.window.requestState(WindowStateStorage.toMirState(appDelegate.prevWindowState));
938 model.window.requestState(WindowStateStorage.toMirState(appDelegate.prevWindowState));
938 } else {
939 } else {
939 appDelegate.restore();
940 appDelegate.restore();
@@ -945,6 +946,21 @@ FocusScope {
945 }
946 }
946 }
947 }
947
948
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+
948 Component.onCompleted: {
964 Component.onCompleted: {
949 if (application && application.rotatesWindowContents) {
965 if (application && application.rotatesWindowContents) {
950 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
966 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
@@ -957,7 +973,6 @@ FocusScope {
957 windowedY = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedY + units.gu(3) : normalZ * units.gu(3)
973 windowedY = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedY + units.gu(3) : normalZ * units.gu(3)
958 // Now load any saved state. This needs to happen *after* the cascading!
974 // Now load any saved state. This needs to happen *after* the cascading!
959 windowStateSaver.load();
975 windowStateSaver.load();
960− model.window.requestState(WindowStateStorage.toMirState(windowState));
961
976
962 updateQmlFocusFromMirSurfaceFocus();
977 updateQmlFocusFromMirSurfaceFocus();
963
978
@@ -1441,7 +1456,7 @@ FocusScope {
1441 ]
1456 ]
1442 transitions: [
1457 transitions: [
1443 Transition {
1458 Transition {
1444− from: "staged,stagedWithSideStage"; to: "normal"
1459+ from: "staged,stagedWithSideStage"
1445 enabled: appDelegate.animationsEnabled
1460 enabled: appDelegate.animationsEnabled
1446 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
1461 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
1447 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedX,requestedY,opacity,requestedWidth,requestedHeight,scale"; duration: priv.animationDuration }
1462 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedX,requestedY,opacity,requestedWidth,requestedHeight,scale"; duration: priv.animationDuration }
@@ -1462,8 +1477,7 @@ FocusScope {
1462 },
1477 },
1463 Transition {
1478 Transition {
1464 from: "normal,staged"; to: "stagedWithSideStage"
1479 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 }
1467 },
1481 },
1468 Transition {
1482 Transition {
1469 to: "windowedRightEdge"
1483 to: "windowedRightEdge"
@@ -1503,7 +1517,6 @@ FocusScope {
1503 from: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
1517 from: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
1504 to: "minimized"
1518 to: "minimized"
1505 SequentialAnimation {
1519 SequentialAnimation {
1506− ScriptAction { script: print("transitioning:", appDelegate.x, appDelegate.y, appDelegate.scale) }
1507 ScriptAction { script: { fakeRectangle.stop(); } }
1520 ScriptAction { script: { fakeRectangle.stop(); } }
1508 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
1521 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
1509 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,scale,opacity"; duration: priv.animationDuration }
1522 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,scale,opacity"; duration: priv.animationDuration }
@@ -1514,7 +1527,6 @@ FocusScope {
1514 from: "minimized"
1527 from: "minimized"
1515 to: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
1528 to: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
1516 SequentialAnimation {
1529 SequentialAnimation {
1517− ScriptAction { script: print("transitioning:", appDelegate.x, appDelegate.y, appDelegate.scale) }
1518 PropertyAction { target: appDelegate; property: "visuallyMinimized,z" }
1530 PropertyAction { target: appDelegate; property: "visuallyMinimized,z" }
1519 ParallelAnimation {
1531 ParallelAnimation {
1520 UbuntuNumberAnimation { target: appDelegate; properties: "x"; from: -appDelegate.width / 2; duration: priv.animationDuration }
1532 UbuntuNumberAnimation { target: appDelegate; properties: "x"; from: -appDelegate.width / 2; duration: priv.animationDuration }
@@ -1661,8 +1673,6 @@ FocusScope {
1661
1673
1662 WindowedFullscreenPolicy {
1674 WindowedFullscreenPolicy {
1663 id: windowedFullscreenPolicy
1675 id: windowedFullscreenPolicy
1664− active: root.mode == "windowed"
1665− surface: model.window.surface
1666 }
1676 }
1667 StagedFullscreenPolicy {
1677 StagedFullscreenPolicy {
1668 id: stagedFullscreenPolicy
1678 id: stagedFullscreenPolicy
qml/Stage/StagedFullscreenPolicy.qml+5−11
@@ -28,14 +28,14 @@ import Unity.Application 0.1
28QtObject {
28QtObject {
29 property bool active: true
29 property bool active: true
30
30
31− property var surface: null
31+ function applyPolicy(surfaceState, surfaceChrome) {
32− onSurfaceChanged: {
33− if (!active || !surface) return;
34− if (surface.shellChrome === Mir.LowChrome) {
32+ if (surfaceChrome === Mir.LowChrome) {
35− surface.requestState(Mir.FullscreenState);
33+ return Mir.FullscreenState;
36 }
34 }
35+ return surfaceState;
37 }
36 }
38
37
38+ property var surface: null
39 property var _connections: Connections {
39 property var _connections: Connections {
40 target: surface
40 target: surface
41 onShellChromeChanged: {
41 onShellChromeChanged: {
@@ -46,11 +46,5 @@ QtObject {
46 surface.requestState(Mir.RestoredState);
46 surface.requestState(Mir.RestoredState);
47 }
47 }
48 }
48 }
49− onStateChanged: {
50− if (!active) return;
51− if (surface.state === Mir.RestoredState && surface.shellChrome === Mir.LowChrome) {
52− surface.requestState(Mir.FullscreenState);
53− }
54− }
55 }
49 }
56}
50}
qml/Stage/WindowStateSaver.qml+4−3
@@ -28,6 +28,8 @@ QtObject {
28 property int leftMargin: 0
28 property int leftMargin: 0
29 property int minimumY: 0
29 property int minimumY: 0
30
30
31+ property int loadedState
32+
31 function load() {
33 function load() {
32 var defaultWidth = units.gu(60);
34 var defaultWidth = units.gu(60);
33 var defaultHeight = units.gu(50);
35 var defaultHeight = units.gu(50);
@@ -41,14 +43,13 @@ QtObject {
41 (target.fullscreen ? 0 : root.leftMargin)); });
43 (target.fullscreen ? 0 : root.leftMargin)); });
42 target.windowedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, screenHeight - target.windowedHeight), minimumY); });
44 target.windowedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, screenHeight - target.windowedHeight), minimumY); });
43
45
44− var windowState = WindowStateStorage.getState(target.appId, WindowStateStorage.WindowStateNormal)
45− target.restore(false /* animated */, windowState);
46−
47 target.updateNormalGeometry();
46 target.updateNormalGeometry();
48
47
49 // initialize the x/y to restore to
48 // initialize the x/y to restore to
50 target.restoredX = target.normalX;
49 target.restoredX = target.normalX;
51 target.restoredY = target.normalY;
50 target.restoredY = target.normalY;
51+
52+ loadedState = WindowStateStorage.getState(target.appId, WindowStateStorage.WindowStateNormal);
52 }
53 }
53
54
54 function save() {
55 function save() {
qml/Stage/WindowedFullscreenPolicy.qml+4−12
@@ -22,18 +22,10 @@ import Unity.Application 0.1
22// On first surface load; if the surface is set to low chrome & fullscreen, the
22// On first surface load; if the surface is set to low chrome & fullscreen, the
23// state of the window is returned to restored.
23// state of the window is returned to restored.
24QtObject {
24QtObject {
25− property bool active: true
25+ function applyPolicy(surfaceState, surfaceChrome) {
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) {
26+ if (surfaceState === Mir.FullscreenState && surfaceChrome === Mir.LowChrome) {
36− surface.requestState(Mir.RestoredState);
27+ return Mir.RestoredState;
37 }
28 }
29+ return surfaceState;
38 }
30 }
39}
31}
tests/mocks/Unity/Application/ApplicationManager.cpp+1
@@ -337,6 +337,7 @@ void ApplicationManager::buildListOfAvailableApplications()
337 application->setScreenshotId("camera");
337 application->setScreenshotId("camera");
338 application->setIconId("camera");
338 application->setIconId("camera");
339 application->setFullscreen(true);
339 application->setFullscreen(true);
340+ application->setShellChrome(Mir::LowChrome);
340 application->setSupportedOrientations(Qt::PortraitOrientation
341 application->setSupportedOrientations(Qt::PortraitOrientation
341 | Qt::LandscapeOrientation
342 | Qt::LandscapeOrientation
342 | Qt::InvertedPortraitOrientation
343 | Qt::InvertedPortraitOrientation
tests/qmltests/Stage/tst_DesktopStage.qml+3−3
@@ -321,7 +321,7 @@ Item {
321 var maximizeButton = findChild(appDelegate, "maximizeWindowButton");
321 var maximizeButton = findChild(appDelegate, "maximizeWindowButton");
322 verify(maximizeButton);
322 verify(maximizeButton);
323 mouseClick(maximizeButton);
323 mouseClick(maximizeButton);
324− tryCompare(appDelegate, "visuallyMaximized", true);
324+ tryCompare(appDelegate, "maximized", true);
325 }
325 }
326
326
327 function test_tappingOnDecorationFocusesApplication(data) {
327 function test_tappingOnDecorationFocusesApplication(data) {
@@ -637,7 +637,7 @@ Item {
637 var dialerAppDelegate = startApplication("dialer-app");
637 var dialerAppDelegate = startApplication("dialer-app");
638
638
639 // verify the drop shadow becomes visible
639 // verify the drop shadow becomes visible
640− verify(PanelState.dropShadow == true);
640+ tryCompareFunction(function() { return PanelState.dropShadow; }, true);
641
641
642 // close the maximized app
642 // close the maximized app
643 ApplicationManager.stopApplication("facebook-webapp");
643 ApplicationManager.stopApplication("facebook-webapp");
@@ -785,7 +785,7 @@ Item {
785 waitUntilTransitionsEnd(dialerAppDelegate);
785 waitUntilTransitionsEnd(dialerAppDelegate);
786 waitUntilTransitionsEnd(stage);
786 waitUntilTransitionsEnd(stage);
787
787
788− tryCompare(dialerAppDelegate, "state", "maximized");
788+ tryCompare(dialerAppDelegate, "maximized", true);
789 }
789 }
790
790
791 function test_saveRestoreSize() {
791 function test_saveRestoreSize() {
tests/qmltests/tst_OrientedShell.qml+5−3
@@ -695,9 +695,11 @@ Rectangle {
695 // false -> true -> false
695 // false -> true -> false
696 compare(transitionSpy.count, 2);
696 compare(transitionSpy.count, 2);
697
697
698+ if (!data.windowed) { // subject to shell-chrome policies
698− // It should retain native dimensions regardless of its rotation/orientation
699+ // It should retain native dimensions regardless of its rotation/orientation
699− compare(cameraSurface.width, orientedShell.width);
700+ compare(cameraSurface.width, orientedShell.width);
700− compare(cameraSurface.height, orientedShell.height);
701+ compare(cameraSurface.height, orientedShell.height);
702+ }
701
703
702 // Surface focus shouldn't have been touched because of the rotation
704 // Surface focus shouldn't have been touched because of the rotation
703 compare(focusChangedSpy.count, 0);
705 compare(focusChangedSpy.count, 0);
tests/qmltests/tst_Shell.qml+10−14
@@ -335,7 +335,7 @@ Rectangle {
335
335
336 Row {
336 Row {
337 CheckBox {
337 CheckBox {
338− id: fullscreeAppCheck
338+ id: fullscreenAppCheck
339 activeFocusOnPress: false
339 activeFocusOnPress: false
340 activeFocusOnTab: false
340 activeFocusOnTab: false
341
341
@@ -349,13 +349,10 @@ Rectangle {
349 }
349 }
350
350
351 Binding {
351 Binding {
352− target: fullscreeAppCheck
352+ target: fullscreenAppCheck
353 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow
353 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow
354 property: "checked"
354 property: "checked"
355− value: {
356− if (!topLevelSurfaceList || !topLevelSurfaceList.focusedWindow) return false;
357− return topLevelSurfaceList.focusedWindow.state === Mir.FullscreenState
355+ value: topLevelSurfaceList.focusedWindow.state === Mir.FullscreenState
358− }
359 }
356 }
360 }
357 }
361 Label {
358 Label {
@@ -366,6 +363,8 @@ Rectangle {
366 Row {
363 Row {
367 CheckBox {
364 CheckBox {
368 id: chromeAppCheck
365 id: chromeAppCheck
366+ activeFocusOnPress: false
367+ activeFocusOnTab: false
369
368
370 onTriggered: {
369 onTriggered: {
371 if (!topLevelSurfaceList.focusedWindow || !topLevelSurfaceList.focusedWindow.surface) return;
370 if (!topLevelSurfaceList.focusedWindow || !topLevelSurfaceList.focusedWindow.surface) return;
@@ -381,10 +380,8 @@ Rectangle {
381 target: chromeAppCheck
380 target: chromeAppCheck
382 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow !== null && topLevelSurfaceList.focusedWindow.surface !== null
381 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow !== null && topLevelSurfaceList.focusedWindow.surface !== null
383 property: "checked"
382 property: "checked"
384− value: {
385− if (!topLevelSurfaceList || !topLevelSurfaceList.focusedWindow || !topLevelSurfaceList.focusedWindow.surface) return false;
383+ value: topLevelSurfaceList.focusedWindow.surface &&
386− topLevelSurfaceList.focusedWindow.surface.shellChrome === Mir.LowChrome
384+ topLevelSurfaceList.focusedWindow.surface.shellChrome === Mir.LowChrome
387− }
388 }
385 }
389 }
386 }
390 Label {
387 Label {
@@ -2295,7 +2292,6 @@ Rectangle {
2295 return [
2292 return [
2296 { tag: "phone" },
2293 { tag: "phone" },
2297 { tag: "tablet" },
2294 { tag: "tablet" },
2298− { tag: "desktop" },
2299 ]
2295 ]
2300 }
2296 }
2301
2297
@@ -2675,8 +2671,8 @@ Rectangle {
2675 }
2671 }
2676
2672
2677 function test_cursorHidingWithFullscreenApp() {
2673 function test_cursorHidingWithFullscreenApp() {
2678− loadShell("desktop");
2674+ loadShell("phone");
2679− shell.usageScenario = "desktop";
2675+ shell.usageScenario = "phone";
2680 waitForRendering(shell);
2676 waitForRendering(shell);
2681 swipeAwayGreeter();
2677 swipeAwayGreeter();
2682
2678
@@ -2780,7 +2776,7 @@ Rectangle {
2780 tryCompare(stage, "state", "staged");
2776 tryCompare(stage, "state", "staged");
2781
2777
2782 // Try by Super+W
2778 // Try by Super+W
2783− keyPress(Qt.Key_W, Qt.MetaModifier)
2779+ keyPress(Qt.Key_W, Qt.MetaModifier, 200);
2784 tryCompare(stage, "state", data.spreadEnabled ? "spread" : "staged");
2780 tryCompare(stage, "state", data.spreadEnabled ? "spread" : "staged");
2785 keyRelease(Qt.Key_W, Qt.MetaModifier)
2781 keyRelease(Qt.Key_W, Qt.MetaModifier)
2786 }
2782 }