on xenial help sign in
Take save/restore functions out of WindowResizeArea

They've no relationship with resizing whatsoever and are closely tied to the environment in Stage.qml

commit1d037c5684cae441ecd759684154fb5ce39fed23 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateWed 23 Nov 2016, 10:13 (10 years ago) parentc8c2543
4 files changed+118−116
qml/Stage/Stage.qml+39−9 qml/Stage/WindowResizeArea.qml+6−41 tests/qmltests/Stage/tst_DesktopStage.qml+72 tests/qmltests/Stage/tst_WindowResizeArea.qml+1−66
qml/Stage/Stage.qml+39−9
@@ -847,6 +847,38 @@ FocusScope {
847847 MirFocusController.focusedSurface = null;
848848 }
849849 }
850+
851+ function loadWindowState() {
852+ var defaultWidth = units.gu(60);
853+ var defaultHeight = units.gu(50);
854+ var windowGeometry = WindowStateStorage.getGeometry(appDelegate.appId,
855+ Qt.rect(appDelegate.windowedX, appDelegate.windowedY, defaultWidth, defaultHeight));
856+
857+ appDelegate.windowedWidth = Qt.binding(function() { return Math.min(Math.max(windowGeometry.width, appDelegate.minimumWidth), appContainer.width - root.leftMargin); });
858+ appDelegate.windowedHeight = Qt.binding(function() { return Math.min(Math.max(windowGeometry.height, appDelegate.minimumHeight),
859+ appContainer.height - (appDelegate.fullscreen ? 0 : PanelState.panelHeight)); });
860+ appDelegate.windowedX = Qt.binding(function() { return Math.max(Math.min(windowGeometry.x, appContainer.width - root.leftMargin - appDelegate.windowedWidth),
861+ (appDelegate.fullscreen ? 0 : root.leftMargin)); });
862+ appDelegate.windowedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, appContainer.height - appDelegate.windowedHeight), PanelState.panelHeight); });
863+
864+ var windowState = WindowStateStorage.getState(appDelegate.appId, WindowStateStorage.WindowStateNormal)
865+ appDelegate.restore(false /* animated */, windowState);
866+
867+ // initialize the x/y to restore to
868+ appDelegate.restoredX = windowGeometry.x;
869+ appDelegate.restoredY = windowGeometry.y;
870+ }
871+ function saveWindowState() {
872+ var state = appDelegate.windowState;
873+ if (state === WindowStateStorage.WindowStateRestored) {
874+ state = WindowStateStorage.WindowStateNormal;
875+ }
876+
877+ WindowStateStorage.saveState(appDelegate.appId, state & ~WindowStateStorage.WindowStateMinimized); // clear the minimized bit when saving
878+ WindowStateStorage.saveGeometry(appDelegate.appId, Qt.rect(appDelegate.windowedX, appDelegate.windowedY,
879+ appDelegate.windowedWidth, appDelegate.windowedHeight));
880+ }
881+
850882 Component.onCompleted: {
851883 if (application && application.rotatesWindowContents) {
852884 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
@@ -858,7 +890,8 @@ FocusScope {
858890 windowedX = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedX + units.gu(3) : (normalZ - 1) * units.gu(3)
859891 windowedY = priv.focusedAppDelegate ? priv.focusedAppDelegate.windowedY + units.gu(3) : normalZ * units.gu(3)
860892 // Now load any saved state. This needs to happen *after* the cascading!
861− resizeArea.loadWindowState();
893+ loadWindowState();
894+ resizeArea.init();
862895
863896 // NB: We're differentiating if this delegate was created in response to a new entry in the model
864897 // or if the Repeater is just populating itself with delegates to match the model it received.
@@ -875,6 +908,8 @@ FocusScope {
875908 _constructing = false;
876909 }
877910 Component.onDestruction: {
911+ saveWindowState();
912+
878913 if (!root.parent) {
879914 // This stage is about to be destroyed. Don't mess up with the model at this point
880915 return;
@@ -1477,27 +1512,22 @@ FocusScope {
14771512 id: resizeArea
14781513 objectName: "windowResizeArea"
14791514
1515+ anchors.fill: appDelegate
1516+
14801517 // workaround so that it chooses the correct resize borders when you drag from a corner ResizeGrip
14811518 anchors.margins: touchControls.overlayShown ? borderThickness/2 : -borderThickness
14821519
14831520 target: appDelegate
1521+ minimumY: PanelState.panelHeight // disallow resizing up past Panel
14841522 minWidth: units.gu(10)
14851523 minHeight: units.gu(10)
14861524 borderThickness: units.gu(2)
1487− windowId: model.application.appId // FIXME: Change this to point to windowId once we have such a thing
1488− screenWidth: appContainer.width
1489− screenHeight: appContainer.height
1490− leftMargin: root.leftMargin
14911525 enabled: false
14921526 visible: enabled
14931527
14941528 onPressed: {
14951529 appDelegate.focus = true;
14961530 }
1497−
1498− Component.onDestruction: {
1499− saveWindowState();
1500− }
15011531 }
15021532
15031533 DecoratedWindow {
qml/Stage/WindowResizeArea.qml+6−41
@@ -18,17 +18,14 @@ import QtQuick 2.4
1818import Ubuntu.Components 1.3
1919import Utils 0.1
2020import Unity.Application 0.1 // for Mir.cursorName
21−import "../Components/PanelState"
2221
2322MouseArea {
2423 id: root
2524
26− anchors.fill: target
2725 anchors.margins: -borderThickness
2826
2927 hoverEnabled: target && !target.maximized // don't grab the resize under the panel
3028
31− property var windowStateStorage: WindowStateStorage
3229 readonly property alias dragging: d.dragging
3330 readonly property alias normalWidth: priv.normalWidth
3431 readonly property alias normalHeight: priv.normalHeight
@@ -36,15 +33,14 @@ MouseArea {
3633 // The target item managed by this. Must be a parent or a sibling
3734 // The area will anchor to it and manage resize events
3835 property Item target: null
39− property string windowId: ""
4036 property int borderThickness: 0
37+ property real minimumY: -100000000 // By default, impose no limit
4138 property int minWidth: 0
4239 property int minHeight: 0
43− property int defaultWidth: units.gu(60)
44− property int defaultHeight: units.gu(50)
45− property int screenWidth: 0
46− property int screenHeight: 0
47− property int leftMargin: 0
40+
41+ function init() {
42+ priv.updateNormalGeometry();
43+ }
4844
4945 QtObject {
5046 id: priv
@@ -73,37 +69,6 @@ MouseArea {
7369 onHeightChanged: priv.updateNormalGeometry();
7470 }
7571
76− function loadWindowState() {
77− var windowGeometry = windowStateStorage.getGeometry(root.windowId,
78− Qt.rect(target.windowedX, target.windowedY, defaultWidth, defaultHeight));
79−
80−
81− target.windowedWidth = Qt.binding(function() { return Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth - root.leftMargin); });
82− target.windowedHeight = Qt.binding(function() { return Math.min(Math.max(windowGeometry.height, d.minimumHeight),
83− root.screenHeight - (target.fullscreen ? 0 : PanelState.panelHeight)); });
84− target.windowedX = Qt.binding(function() { return Math.max(Math.min(windowGeometry.x, root.screenWidth - root.leftMargin - target.windowedWidth),
85− (target.fullscreen ? 0 : root.leftMargin)); });
86− target.windowedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, root.screenHeight - target.windowedHeight), PanelState.panelHeight); });
87−
88− var windowState = windowStateStorage.getState(root.windowId, WindowStateStorage.WindowStateNormal)
89− target.restore(false /* animated */, windowState);
90−
91− priv.updateNormalGeometry();
92−
93− // initialize the x/y to restore to
94− target.restoredX = priv.normalX;
95− target.restoredY = priv.normalY;
96− }
97−
98− function saveWindowState() {
99− var state = target.windowState;
100− if (state === WindowStateStorage.WindowStateRestored) {
101− state = WindowStateStorage.WindowStateNormal;
102− }
103− windowStateStorage.saveState(root.windowId, state & ~WindowStateStorage.WindowStateMinimized); // clear the minimized bit when saving
104− windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight));
105− }
106−
10772 QtObject {
10873 id: d
10974
@@ -311,7 +276,7 @@ MouseArea {
311276 }
312277
313278 if (d.topBorder) {
314− var newTargetY = Math.max(d.startY + deltaY, PanelState.panelHeight); // disallow resizing up past Panel
279+ var newTargetY = Math.max(d.startY + deltaY, root.minimumY);
315280 var bottomBorderY = target.windowedY + target.height;
316281 if (bottomBorderY > newTargetY + d.minimumHeight) {
317282 if (bottomBorderY < newTargetY + d.maximumHeight) {
tests/qmltests/Stage/tst_DesktopStage.qml+72
@@ -789,5 +789,77 @@ Item {
789789
790790 tryCompare(dialerAppDelegate, "state", "maximized");
791791 }
792+
793+ function test_saveRestoreSize() {
794+ var originalWindowCount = topSurfaceList.count;
795+ var appDelegate = startApplication("dialer-app");
796+ compare(topSurfaceList.count, originalWindowCount + 1);
797+
798+ var initialWindowX = appDelegate.windowedX;
799+ var initialWindowY = appDelegate.windowedY;
800+ var initialWindowWidth = appDelegate.width
801+ var initialWindowHeight = appDelegate.height
802+
803+ var resizeDelta = units.gu(5)
804+ var startDragX = initialWindowX + initialWindowWidth + 1
805+ var startDragY = initialWindowY + initialWindowHeight + 1
806+ mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
807+
808+ tryCompare(appDelegate, "width", initialWindowWidth + resizeDelta);
809+ tryCompare(appDelegate, "height", initialWindowHeight + resizeDelta);
810+
811+ // Close the window and restart the application
812+ var closeButton = findChild(appDelegate, "closeWindowButton");
813+ appDelegate = null;
814+ verify(closeButton);
815+ mouseClick(closeButton);
816+ tryCompare(topSurfaceList, "count", originalWindowCount);
817+ wait(100); // plus some spare room
818+ appDelegate = startApplication("dialer-app");
819+
820+ // Make sure its size is again the same as before
821+ tryCompare(appDelegate, "width", initialWindowWidth + resizeDelta);
822+ tryCompare(appDelegate, "height", initialWindowHeight + resizeDelta);
823+ }
824+
825+ function test_saveRestoreMaximized() {
826+ var originalWindowCount = topSurfaceList.count;
827+ var appDelegate = startApplication("dialer-app");
828+ compare(topSurfaceList.count, originalWindowCount + 1);
829+
830+ var initialWindowX = appDelegate.windowedX;
831+ var initialWindowY = appDelegate.windowedY;
832+
833+ var moveDelta = units.gu(5);
834+
835+ appDelegate.windowedX = initialWindowX + moveDelta
836+ appDelegate.windowedY = initialWindowY + moveDelta
837+
838+ // Now change the state to maximized. The window should not keep updating the stored values
839+ maximizeAppDelegate(appDelegate);
840+
841+ // Close the window and restart the application
842+ var closeButton = findChild(appDelegate, "closeWindowButton");
843+ appDelegate = null;
844+ verify(closeButton);
845+ mouseClick(closeButton);
846+ closeButton = null;
847+ tryCompare(topSurfaceList, "count", originalWindowCount);
848+ wait(100); // plus some spare room
849+ appDelegate = startApplication("dialer-app");
850+
851+ // Make sure it's again where we left it in normal state before destroying
852+ tryCompare(appDelegate, "windowedX", initialWindowX + moveDelta)
853+ tryCompare(appDelegate, "windowedY", initialWindowY + moveDelta)
854+
855+ // Make sure maximize() has been called after restoring
856+ tryCompare(appDelegate, "state", "maximized")
857+
858+ // clean up
859+ // click on restore button (same one as maximize)
860+ var maximizeButton = findChild(appDelegate, "maximizeWindowButton");
861+ mouseClick(maximizeButton);
862+ }
792863 }
864+
793865}
tests/qmltests/Stage/tst_WindowResizeArea.qml+1−66
@@ -88,22 +88,11 @@ Item {
8888
8989 WindowResizeArea {
9090 id: windowResizeArea
91+ anchors.fill: parent
9192 target: fakeWindow
9293 borderThickness: units.gu(2)
9394 minWidth: units.gu(15)
9495 minHeight: units.gu(10)
95− defaultWidth: units.gu(20)
96− defaultHeight: units.gu(20)
97− windowId: "test-window-id"
98− screenWidth: root.width
99− screenHeight: root.height
100−
101− Component.onCompleted: {
102− loadWindowState();
103− }
104− Component.onDestruction: {
105− saveWindowState();
106− }
10796 }
10897
10998 Rectangle {
@@ -312,30 +301,6 @@ Item {
312301 compare(fakeWindow.requestedY, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
313302 }
314303
315− function test_saveRestoreSize() {
316− var initialWindowX = fakeWindow.windowedX;
317− var initialWindowY = fakeWindow.windowedY;
318− var initialWindowWidth = fakeWindow.width
319− var initialWindowHeight = fakeWindow.height
320−
321− var resizeDelta = units.gu(5)
322− var startDragX = initialWindowX + initialWindowWidth + 1
323− var startDragY = initialWindowY + initialWindowHeight + 1
324− mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
325−
326− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
327− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
328−
329− // This will destroy the window and recreate it
330− windowLoader.active = false;
331− waitForRendering(root);
332− windowLoader.active = true;
333−
334− // Make sure its size is again the same as before
335− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
336− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
337− }
338−
339304 // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
340305 // to the mouse, instead of immediately making the window grow again when switching direction
341306 function test_resizeSmallerAndLarger_data() {
@@ -361,36 +326,6 @@ Item {
361326 tryCompare(fakeWindow, "height", initialWindowHeight);
362327 }
363328
364− function test_saveRestoreMaximized() {
365− var initialWindowX = fakeWindow.windowedX;
366− var initialWindowY = fakeWindow.windowedY;
367−
368− var moveDelta = units.gu(5);
369−
370− fakeWindow.windowedX = initialWindowX + moveDelta
371− fakeWindow.windowedY = initialWindowY + moveDelta
372−
373− // Now change the state to maximized. The window should not keep updating the stored values
374− fakeWindow.maximize()
375− fakeWindow.windowedX = 31415 // 0 is too risky to pass the test even when broken
376− fakeWindow.windowedY = 31415
377−
378− // This will destroy the window and recreate it
379− windowLoader.active = false;
380− waitForRendering(root);
381− windowLoader.active = true;
382−
383− // Make sure it's again where we left it in normal state before destroying
384− tryCompare(fakeWindow, "x", initialWindowX + moveDelta)
385− tryCompare(fakeWindow, "y", initialWindowX + moveDelta)
386−
387− // Make sure maximize() has been called after restoring
388− tryCompare(fakeWindow, "state", "maximized")
389−
390− // clean up
391− fakeWindow.restoreFromMaximized()
392− }
393−
394329 function test_restoreMovesIntoBounds_data() {
395330 return [
396331 {tag: "left off", x: -units.gu(5), y: units.gu(5), w: units.gu(10), h: units.gu(10)},