on xenial help sign in
shell chrome fixes
077284dLukáš Tinkl
qml/Stage/Stage.qml+35−13
@@ -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,22 @@ FocusScope {
945 }
946 }
946 }
947 }
947
948
949+ // queue the requests to change the window/surface state
950+ Timer {
951+ id: delayedStateTimer
952+ property int windowState: -1 // Mir::State
953+ interval: 1000
954+ onTriggered: {
955+ if (delayedStateTimer.windowState != -1) {
956+ if (windowedFullscreenPolicy.active) { // need to apply the windowed shell chrome policy on top the saved window state
957+ delayedStateTimer.windowState = windowedFullscreenPolicy.applyPolicy(delayedStateTimer.windowState, appDelegate.surface.shellChrome);
958+ }
959+ appDelegate.window.requestState(delayedStateTimer.windowState);
960+ delayedStateTimer.windowState = -1;
961+ }
962+ }
963+ }
964+
948 Component.onCompleted: {
965 Component.onCompleted: {
949 if (application && application.rotatesWindowContents) {
966 if (application && application.rotatesWindowContents) {
950 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
967 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
@@ -955,9 +972,12 @@ FocusScope {
955 // First, cascade the newly created window, relative to the currently/old focused window.
972 // First, cascade the newly created window, relative to the currently/old focused window.
956 windowedX = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedX + units.gu(3) : (normalZ - 1) * units.gu(3)
973 windowedX = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedX + units.gu(3) : (normalZ - 1) * units.gu(3)
957 windowedY = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedY + units.gu(3) : normalZ * units.gu(3)
974 windowedY = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedY + units.gu(3) : normalZ * units.gu(3)
975+
976+ if (root.mode == "windowed") {
958− // Now load any saved state. This needs to happen *after* the cascading!
977+ // Now load any saved state. This needs to happen *after* the cascading!
959− windowStateSaver.load();
960− model.window.requestState(WindowStateStorage.toMirState(windowState));
978+ delayedStateTimer.windowState = WindowStateStorage.toMirState(windowStateSaver.load());
979+ delayedStateTimer.restart();
980+ }
961
981
962 updateQmlFocusFromMirSurfaceFocus();
982 updateQmlFocusFromMirSurfaceFocus();
963
983
@@ -965,7 +985,9 @@ FocusScope {
965 _constructing = false;
985 _constructing = false;
966 }
986 }
967 Component.onDestruction: {
987 Component.onDestruction: {
988+ if (root.mode == "windowed") {
968− windowStateSaver.save();
989+ windowStateSaver.save();
990+ }
969
991
970 if (!root.parent) {
992 if (!root.parent) {
971 // This stage is about to be destroyed. Don't mess up with the model at this point
993 // This stage is about to be destroyed. Don't mess up with the model at this point
@@ -1441,7 +1463,7 @@ FocusScope {
1441 ]
1463 ]
1442 transitions: [
1464 transitions: [
1443 Transition {
1465 Transition {
1444− from: "staged,stagedWithSideStage"; to: "normal"
1466+ from: "staged,stagedWithSideStage"
1445 enabled: appDelegate.animationsEnabled
1467 enabled: appDelegate.animationsEnabled
1446 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
1468 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
1447 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedX,requestedY,opacity,requestedWidth,requestedHeight,scale"; duration: priv.animationDuration }
1469 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedX,requestedY,opacity,requestedWidth,requestedHeight,scale"; duration: priv.animationDuration }
@@ -1462,8 +1484,7 @@ FocusScope {
1462 },
1484 },
1463 Transition {
1485 Transition {
1464 from: "normal,staged"; to: "stagedWithSideStage"
1486 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 }
1487+ UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedWidth,requestedHeight"; duration: priv.animationDuration }
1467 },
1488 },
1468 Transition {
1489 Transition {
1469 to: "windowedRightEdge"
1490 to: "windowedRightEdge"
@@ -1503,7 +1524,6 @@ FocusScope {
1503 from: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
1524 from: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
1504 to: "minimized"
1525 to: "minimized"
1505 SequentialAnimation {
1526 SequentialAnimation {
1506− ScriptAction { script: print("transitioning:", appDelegate.x, appDelegate.y, appDelegate.scale) }
1507 ScriptAction { script: { fakeRectangle.stop(); } }
1527 ScriptAction { script: { fakeRectangle.stop(); } }
1508 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
1528 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
1509 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,scale,opacity"; duration: priv.animationDuration }
1529 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,scale,opacity"; duration: priv.animationDuration }
@@ -1514,7 +1534,6 @@ FocusScope {
1514 from: "minimized"
1534 from: "minimized"
1515 to: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
1535 to: ",normal,restored,maximized,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedTopRight,maximizedBottomLeft,maximizedBottomRight,maximizedHorizontally,maximizedVertically,fullscreen"
1516 SequentialAnimation {
1536 SequentialAnimation {
1517− ScriptAction { script: print("transitioning:", appDelegate.x, appDelegate.y, appDelegate.scale) }
1518 PropertyAction { target: appDelegate; property: "visuallyMinimized,z" }
1537 PropertyAction { target: appDelegate; property: "visuallyMinimized,z" }
1519 ParallelAnimation {
1538 ParallelAnimation {
1520 UbuntuNumberAnimation { target: appDelegate; properties: "x"; from: -appDelegate.width / 2; duration: priv.animationDuration }
1539 UbuntuNumberAnimation { target: appDelegate; properties: "x"; from: -appDelegate.width / 2; duration: priv.animationDuration }
@@ -1662,12 +1681,15 @@ FocusScope {
1662 WindowedFullscreenPolicy {
1681 WindowedFullscreenPolicy {
1663 id: windowedFullscreenPolicy
1682 id: windowedFullscreenPolicy
1664 active: root.mode == "windowed"
1683 active: root.mode == "windowed"
1665− surface: model.window.surface
1666 }
1684 }
1667 StagedFullscreenPolicy {
1685 StagedFullscreenPolicy {
1668 id: stagedFullscreenPolicy
1686 id: stagedFullscreenPolicy
1669 active: root.mode == "staged" || root.mode == "stagedWithSideStage"
1687 active: root.mode == "staged" || root.mode == "stagedWithSideStage"
1670 surface: model.window.surface
1688 surface: model.window.surface
1689+ onStateRequested: {
1690+ delayedStateTimer.windowState = requestedState;
1691+ delayedStateTimer.restart();
1692+ }
1671 }
1693 }
1672
1694
1673 SpreadDelegateInputArea {
1695 SpreadDelegateInputArea {
qml/Stage/StagedFullscreenPolicy.qml+7−5
@@ -28,11 +28,13 @@ import Unity.Application 0.1
28QtObject {
28QtObject {
29 property bool active: true
29 property bool active: true
30
30
31+ signal stateRequested(int requestedState)
32+
31 property var surface: null
33 property var surface: null
32 onSurfaceChanged: {
34 onSurfaceChanged: {
33 if (!active || !surface) return;
35 if (!active || !surface) return;
34 if (surface.shellChrome === Mir.LowChrome) {
36 if (surface.shellChrome === Mir.LowChrome) {
35− surface.requestState(Mir.FullscreenState);
37+ stateRequested(Mir.FullscreenState);
36 }
38 }
37 }
39 }
38
40
@@ -41,15 +43,15 @@ QtObject {
41 onShellChromeChanged: {
43 onShellChromeChanged: {
42 if (!active || !surface) return;
44 if (!active || !surface) return;
43 if (surface.shellChrome === Mir.LowChrome) {
45 if (surface.shellChrome === Mir.LowChrome) {
44− surface.requestState(Mir.FullscreenState);
46+ stateRequested(Mir.FullscreenState);
45 } else {
47 } else {
46− surface.requestState(Mir.RestoredState);
48+ stateRequested(Mir.RestoredState);
47 }
49 }
48 }
50 }
49 onStateChanged: {
51 onStateChanged: {
50− if (!active) return;
52+ if (!active || !surface) return;
51 if (surface.state === Mir.RestoredState && surface.shellChrome === Mir.LowChrome) {
53 if (surface.state === Mir.RestoredState && surface.shellChrome === Mir.LowChrome) {
52− surface.requestState(Mir.FullscreenState);
54+ stateRequested(Mir.FullscreenState);
53 }
55 }
54 }
56 }
55 }
57 }
qml/Stage/WindowStateSaver.qml+2−1
@@ -42,13 +42,14 @@ QtObject {
42 target.windowedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, screenHeight - target.windowedHeight), minimumY); });
42 target.windowedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, screenHeight - target.windowedHeight), minimumY); });
43
43
44 var windowState = WindowStateStorage.getState(target.appId, WindowStateStorage.WindowStateNormal)
44 var windowState = WindowStateStorage.getState(target.appId, WindowStateStorage.WindowStateNormal)
45− target.restore(false /* animated */, windowState);
46
45
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+ return windowState;
52 }
53 }
53
54
54 function save() {
55 function save() {
qml/Stage/WindowedFullscreenPolicy.qml+4−10
@@ -23,17 +23,11 @@ import Unity.Application 0.1
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 property bool active: true
26− property QtObject surface: null
27
26
28− property bool _firstTimeSurface: true
27+ function applyPolicy(surfaceState, surfaceChrome) {
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) {
28+ if (surfaceState === Mir.FullscreenState && surfaceChrome === Mir.LowChrome) {
36− surface.requestState(Mir.RestoredState);
29+ return Mir.RestoredState;
37 }
30 }
31+ return surfaceState;
38 }
32 }
39}
33}
tests/qmltests/tst_Shell.qml+6−10
@@ -334,7 +334,7 @@ Rectangle {
334
334
335 Row {
335 Row {
336 CheckBox {
336 CheckBox {
337− id: fullscreeAppCheck
337+ id: fullscreenAppCheck
338 activeFocusOnPress: false
338 activeFocusOnPress: false
339 activeFocusOnTab: false
339 activeFocusOnTab: false
340
340
@@ -348,13 +348,10 @@ Rectangle {
348 }
348 }
349
349
350 Binding {
350 Binding {
351− target: fullscreeAppCheck
351+ target: fullscreenAppCheck
352 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow
352 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow
353 property: "checked"
353 property: "checked"
354− value: {
355− if (!topLevelSurfaceList || !topLevelSurfaceList.focusedWindow) return false;
356− return topLevelSurfaceList.focusedWindow.state === Mir.FullscreenState
354+ value: topLevelSurfaceList.focusedWindow.state === Mir.FullscreenState
357− }
358 }
355 }
359 }
356 }
360 Label {
357 Label {
@@ -365,6 +362,8 @@ Rectangle {
365 Row {
362 Row {
366 CheckBox {
363 CheckBox {
367 id: chromeAppCheck
364 id: chromeAppCheck
365+ activeFocusOnPress: false
366+ activeFocusOnTab: false
368
367
369 onTriggered: {
368 onTriggered: {
370 if (!topLevelSurfaceList.focusedWindow || !topLevelSurfaceList.focusedWindow.surface) return;
369 if (!topLevelSurfaceList.focusedWindow || !topLevelSurfaceList.focusedWindow.surface) return;
@@ -380,10 +379,7 @@ Rectangle {
380 target: chromeAppCheck
379 target: chromeAppCheck
381 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow !== null && topLevelSurfaceList.focusedWindow.surface !== null
380 when: topLevelSurfaceList && topLevelSurfaceList.focusedWindow !== null && topLevelSurfaceList.focusedWindow.surface !== null
382 property: "checked"
381 property: "checked"
383− value: {
384− if (!topLevelSurfaceList || !topLevelSurfaceList.focusedWindow || !topLevelSurfaceList.focusedWindow.surface) return false;
385− topLevelSurfaceList.focusedWindow.surface.shellChrome === Mir.LowChrome
382+ value: topLevelSurfaceList.focusedWindow.surface.shellChrome === Mir.LowChrome
386− }
387 }
383 }
388 }
384 }
389 Label {
385 Label {