on xenial help sign in
rebase on top of lp:~lukas-kde/unity8/horizVertWindowMaximize
commitcf5a47d3aa2cf9c83986e73f233788ba27a7f93a authorLukáš Tinkl <lukas.tinkl@canonical.com> dateWed 18 May 2016, 20:53 (10 years ago) parent3ece1c1a3fc9b2
11 files changed+200−86
plugins/Utils/windowstatestorage.h+13−3 qml/Components/PanelState/PanelState.qml+3−3 qml/Components/WindowControlButtons.qml+17−6 qml/Panel/Panel.qml+5−4 qml/Stages/DecoratedWindow.qml+10−6 qml/Stages/DesktopStage.qml+54−42 qml/Stages/WindowDecoration.qml+12−8 qml/Stages/WindowResizeArea.qml+25−5 tests/mocks/Utils/windowstatestorage.h+14−3 tests/qmltests/Stages/tst_DesktopStage.qml+31−1 tests/qmltests/Stages/tst_WindowResizeArea.qml+16−5
plugins/Utils/windowstatestorage.h+13−3
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2015 Canonical Ltd.
2+ * Copyright 2015-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -25,9 +25,19 @@ class WindowStateStorage: public QObject
2525 Q_ENUMS(WindowState)
2626public:
2727 enum WindowState {
28− WindowStateNormal,
29− WindowStateMaximized
28+ WindowStateNormal = 1 << 0,
29+ WindowStateMaximized = 1 << 1,
30+ WindowStateMinimized = 1 << 2,
31+ WindowStateFullscreen = 1 << 3,
32+ WindowStateMaximizedLeft = 1 << 4,
33+ WindowStateMaximizedRight = 1 << 5,
34+ WindowStateMaximizedHorizontally = 1 << 6,
35+ WindowStateMaximizedVertically = 1 << 7
3036 };
37+ Q_DECLARE_FLAGS(WindowStates, WindowState)
38+#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
39+ Q_FLAG(WindowStates)
40+#endif
3141
3242 WindowStateStorage(QObject *parent = 0);
3343 virtual ~WindowStateStorage();
qml/Components/PanelState/PanelState.qml+3−3
@@ -26,8 +26,8 @@ QtObject {
2626 property bool dropShadow: false
2727 property int panelHeight: 0
2828
29− signal close()
30− signal minimize()
31− signal restore()
29+ signal closeClicked()
30+ signal minimizeClicked()
31+ signal restoreClicked()
3232 signal focusMaximizedApp()
3333}
qml/Components/WindowControlButtons.qml+17−6
@@ -33,9 +33,11 @@ Row {
3333
3434 readonly property bool overlayShown: TouchControlsState.overlayShown && target && target.surface === TouchControlsState.surface
3535
36− signal close()
37− signal minimize()
38− signal maximize()
36+ signal closeClicked()
37+ signal minimizeClicked()
38+ signal maximizeClicked()
39+ signal maximizeVerticallyClicked()
40+ signal maximizeHorizontallyClicked()
3941
4042 MouseArea {
4143 id: closeWindowButton
@@ -43,7 +45,7 @@ Row {
4345 hoverEnabled: true
4446 height: parent.height
4547 width: height
46− onClicked: root.close()
48+ onClicked: root.closeClicked()
4749 visible: root.closeButtonShown
4850
4951 Rectangle {
@@ -66,7 +68,7 @@ Row {
6668 hoverEnabled: true
6769 height: parent.height
6870 width: height
69− onClicked: root.minimize()
71+ onClicked: root.minimizeClicked()
7072
7173 Rectangle {
7274 anchors.fill: parent
@@ -88,7 +90,16 @@ Row {
8890 hoverEnabled: true
8991 height: parent.height
9092 width: height
91− onClicked: root.maximize()
93+ acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
94+ onClicked: {
95+ if (mouse.button == Qt.LeftButton) {
96+ root.maximizeClicked();
97+ } else if (mouse.button == Qt.RightButton) {
98+ root.maximizeHorizontallyClicked();
99+ } else if (mouse.button == Qt.MiddleButton) {
100+ root.maximizeVerticallyClicked();
101+ }
102+ }
92103
93104 Rectangle {
94105 anchors.fill: parent
qml/Panel/Panel.qml+5−4
@@ -110,7 +110,7 @@ Item {
110110 height: indicators.minimizedPanelHeight
111111 hoverEnabled: true
112112 onClicked: callHint.visible ? callHint.showLiveCall() : PanelState.focusMaximizedApp()
113− onDoubleClicked: PanelState.restore()
113+ onDoubleClicked: PanelState.restoreClicked()
114114
115115 // WindowControlButtons inside the mouse area, otherwise QML doesn't grok nested hover events :/
116116 // cf. https://bugreports.qt.io/browse/QTBUG-32909
@@ -125,15 +125,16 @@ Item {
125125 bottomMargin: units.gu(0.5)
126126 }
127127 height: indicators.minimizedPanelHeight - anchors.topMargin - anchors.bottomMargin
128+
128129 visible: ((PanelState.buttonsVisible && parent.containsMouse) ||
129130 (TouchControlsState.overlayShown && TouchControlsState.buttonsShownInPanel))
130131 && !root.locked && !callHint.visible
131132 active: PanelState.buttonsVisible || TouchControlsState.overlayShown
132133 windowIsMaximized: true
134+ onCloseClicked: PanelState.closeClicked()
135+ onMinimizeClicked: PanelState.minimizeClicked()
136+ onMaximizeClicked: PanelState.restoreClicked()
133137 closeButtonShown: PanelState.closeButtonShown
134− onClose: PanelState.close()
135− onMinimize: PanelState.minimize()
136− onMaximize: PanelState.restore()
137138 }
138139 }
139140
qml/Stages/DecoratedWindow.qml+10−6
@@ -46,9 +46,11 @@ FocusScope {
4646 property alias widthIncrement: applicationWindow.widthIncrement
4747 property alias heightIncrement: applicationWindow.heightIncrement
4848
49− signal close()
50− signal maximize()
51− signal minimize()
49+ signal closeClicked()
50+ signal maximizeClicked()
51+ signal maximizeHorizontallyClicked()
52+ signal maximizeVerticallyClicked()
53+ signal minimizeClicked()
5254 signal decorationPressed()
5355
5456 Rectangle {
@@ -86,9 +88,11 @@ FocusScope {
8688 title: applicationWindow.title
8789 visible: root.decorationShown
8890
89− onClose: root.close();
90− onMaximize: { root.decorationPressed(); root.maximize(); }
91− onMinimize: root.minimize();
91+ onCloseClicked: root.closeClicked();
92+ onMaximizeClicked: { root.decorationPressed(); root.maximizeClicked(); }
93+ onMaximizeHorizontallyClicked: { root.decorationPressed(); root.maximizeHorizontallyClicked(); }
94+ onMaximizeVerticallyClicked: { root.decorationPressed(); root.maximizeVerticallyClicked(); }
95+ onMinimizeClicked: root.minimizeClicked();
9296 onPressed: root.decorationPressed();
9397 }
9498
qml/Stages/DesktopStage.qml+54−42
@@ -92,7 +92,8 @@ AbstractStage {
9292 GlobalShortcut {
9393 id: minimizeRestoreShortcut
9494 shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Down
95− onTriggered: priv.focusedAppDelegate.maximized || priv.focusedAppDelegate.maximizedLeft || priv.focusedAppDelegate.maximizedRight
95+ onTriggered: priv.focusedAppDelegate.maximized || priv.focusedAppDelegate.maximizedLeft || priv.focusedAppDelegate.maximizedRight ||
96+ priv.focusedAppDelegate.maximizedHorizontally || priv.focusedAppDelegate.maximizedVertically
9697 ? priv.focusedAppDelegate.restoreFromMaximized() : priv.focusedAppDelegate.minimize()
9798 active: priv.focusedAppDelegate !== null
9899 }
@@ -161,9 +162,9 @@ AbstractStage {
161162
162163 Connections {
163164 target: PanelState
164− onClose: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } }
165− onMinimize: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.minimize(); } }
166− onRestore: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.restoreFromMaximized(); } }
165+ onCloseClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } }
166+ onMinimizeClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.minimize(); } }
167+ onRestoreClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.restoreFromMaximized(); } }
167168 onFocusMaximizedApp: {
168169 if (priv.foregroundMaximizedAppDelegate) {
169170 priv.foregroundMaximizedAppDelegate.focus = true;
@@ -291,19 +292,16 @@ AbstractStage {
291292 property alias widthIncrement: decoratedWindow.widthIncrement
292293 property alias heightIncrement: decoratedWindow.heightIncrement
293294
294− QtObject {
295− id: appDelegatePrivate
296− property bool maximized: false
297− property bool maximizedLeft: false
298− property bool maximizedRight: false
299− property bool minimized: false
300− }
301− readonly property alias maximized: appDelegatePrivate.maximized
302− readonly property alias maximizedLeft: appDelegatePrivate.maximizedLeft
303− readonly property alias maximizedRight: appDelegatePrivate.maximizedRight
304− readonly property alias minimized: appDelegatePrivate.minimized
295+ readonly property bool maximized: windowState & WindowStateStorage.WindowStateMaximized
296+ readonly property bool maximizedLeft: windowState & WindowStateStorage.WindowStateMaximizedLeft
297+ readonly property bool maximizedRight: windowState & WindowStateStorage.WindowStateMaximizedRight
298+ readonly property bool maximizedHorizontally: windowState & WindowStateStorage.WindowStateMaximizedHorizontally
299+ readonly property bool maximizedVertically: windowState & WindowStateStorage.WindowStateMaximizedVertically
300+ readonly property bool minimized: windowState & WindowStateStorage.WindowStateMinimized
305301 readonly property alias fullscreen: decoratedWindow.fullscreen
306302
303+ property int windowState: WindowStateStorage.WindowStateNormal
304+
307305 readonly property var application: model.application
308306 property bool animationsEnabled: true
309307 property alias title: decoratedWindow.title
@@ -402,43 +400,45 @@ AbstractStage {
402400
403401 function maximize(animated) {
404402 animationsEnabled = (animated === undefined) || animated;
405− appDelegatePrivate.minimized = false;
406− appDelegatePrivate.maximized = true;
407− appDelegatePrivate.maximizedLeft = false;
408− appDelegatePrivate.maximizedRight = false;
403+ windowState = WindowStateStorage.WindowStateMaximized;
404+ }
405+ function maximizeLeft(animated) {
406+ animationsEnabled = (animated === undefined) || animated;
407+ windowState = WindowStateStorage.WindowStateMaximizedLeft;
408+ }
409+ function maximizeRight(animated) {
410+ animationsEnabled = (animated === undefined) || animated;
411+ windowState = WindowStateStorage.WindowStateMaximizedRight;
409412 }
410− function maximizeLeft() {
411− appDelegatePrivate.minimized = false;
412− appDelegatePrivate.maximized = false;
413− appDelegatePrivate.maximizedLeft = true;
414− appDelegatePrivate.maximizedRight = false;
413+ function maximizeHorizontally(animated) {
414+ animationsEnabled = (animated === undefined) || animated;
415+ windowState = WindowStateStorage.WindowStateMaximizedHorizontally;
415416 }
416− function maximizeRight() {
417− appDelegatePrivate.minimized = false;
418− appDelegatePrivate.maximized = false;
419− appDelegatePrivate.maximizedLeft = false;
420− appDelegatePrivate.maximizedRight = true;
417+ function maximizeVertically(animated) {
418+ animationsEnabled = (animated === undefined) || animated;
419+ windowState = WindowStateStorage.WindowStateMaximizedVertically;
421420 }
422421 function minimize(animated) {
423422 animationsEnabled = (animated === undefined) || animated;
424− appDelegatePrivate.minimized = true;
423+ windowState |= WindowStateStorage.WindowStateMinimized; // add the minimized bit
425424 }
426425 function restoreFromMaximized(animated) {
427426 animationsEnabled = (animated === undefined) || animated;
428− appDelegatePrivate.minimized = false;
429− appDelegatePrivate.maximized = false;
430− appDelegatePrivate.maximizedLeft = false;
431− appDelegatePrivate.maximizedRight = false;
427+ windowState = WindowStateStorage.WindowStateNormal;
432428 }
433429 function restore(animated) {
434430 animationsEnabled = (animated === undefined) || animated;
435− appDelegatePrivate.minimized = false;
431+ windowState &= ~WindowStateStorage.WindowStateMinimized; // clear the minimized bit
436432 if (maximized)
437433 maximize();
438434 else if (maximizedLeft)
439435 maximizeLeft();
440436 else if (maximizedRight)
441437 maximizeRight();
438+ else if (maximizedHorizontally)
439+ maximizeHorizontally();
440+ else if (maximizedVertically)
441+ maximizeVertically();
442442
443443 focus = true;
444444 }
@@ -469,8 +469,7 @@ AbstractStage {
469469 },
470470 State {
471471 name: "normal";
472− when: !appDelegate.maximized && !appDelegate.minimized
473− && !appDelegate.maximizedLeft && !appDelegate.maximizedRight
472+ when: appDelegate.windowState == WindowStateStorage.WindowStateNormal
474473 PropertyChanges {
475474 target: appDelegate;
476475 visuallyMinimized: false;
@@ -518,13 +517,23 @@ AbstractStage {
518517 requestedHeight: appContainer.height - PanelState.panelHeight
519518 }
520519 },
520+ State {
521+ name: "maximizedHorizontally"; when: appDelegate.maximizedHorizontally && !appDelegate.minimized
522+ PropertyChanges { target: appDelegate; x: root.leftMargin }
523+ PropertyChanges { target: decoratedWindow; requestedWidth: appContainer.width - root.leftMargin }
524+ },
525+ State {
526+ name: "maximizedVertically"; when: appDelegate.maximizedVertically && !appDelegate.minimized
527+ PropertyChanges { target: appDelegate; y: PanelState.panelHeight }
528+ PropertyChanges { target: decoratedWindow; requestedHeight: appContainer.height - PanelState.panelHeight }
529+ },
521530 State {
522531 name: "minimized"; when: appDelegate.minimized
523532 PropertyChanges {
524533 target: appDelegate;
525534 x: -appDelegate.width / 2;
526535 scale: units.gu(5) / appDelegate.width;
527− opacity: 0
536+ opacity: 0;
528537 visuallyMinimized: true;
529538 visuallyMaximized: false
530539 }
@@ -627,10 +636,13 @@ AbstractStage {
627636 requestedWidth: appDelegate.requestedWidth
628637 requestedHeight: appDelegate.requestedHeight
629638
630− onClose: { appDelegate.close(); }
631− onMaximize: appDelegate.maximized || appDelegate.maximizedLeft || appDelegate.maximizedRight
632− ? appDelegate.restoreFromMaximized() : appDelegate.maximize()
633− onMinimize: appDelegate.minimize()
639+ onCloseClicked: { appDelegate.close(); }
640+ onMaximizeClicked: appDelegate.maximized || appDelegate.maximizedLeft || appDelegate.maximizedRight
641+ || appDelegate.maximizedHorizontally || appDelegate.maximizedVertically
642+ ? appDelegate.restoreFromMaximized() : appDelegate.maximize()
643+ onMaximizeHorizontallyClicked: appDelegate.maximizedHorizontally ? appDelegate.restoreFromMaximized() : appDelegate.maximizeHorizontally()
644+ onMaximizeVerticallyClicked: appDelegate.maximizedVertically ? appDelegate.restoreFromMaximized() : appDelegate.maximizeVertically()
645+ onMinimizeClicked: appDelegate.minimize()
634646 onDecorationPressed: { appDelegate.focus = true; }
635647 }
636648
qml/Stages/WindowDecoration.qml+12−8
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -30,11 +30,13 @@ MouseArea {
3030 property bool active: false
3131 hoverEnabled: true
3232
33− signal close()
34− signal minimize()
35− signal maximize()
33+ signal closeClicked()
34+ signal minimizeClicked()
35+ signal maximizeClicked()
36+ signal maximizeHorizontallyClicked()
37+ signal maximizeVerticallyClicked()
3638
37− onDoubleClicked: root.maximize()
39+ onDoubleClicked: root.maximizeClicked()
3840
3941 QtObject {
4042 id: priv
@@ -91,11 +93,13 @@ MouseArea {
9193 id: buttons
9294 height: parent.height
9395 active: root.active
96+ onCloseClicked: root.closeClicked();
97+ onMinimizeClicked: root.minimizeClicked();
98+ onMaximizeClicked: root.maximizeClicked();
99+ onMaximizeHorizontallyClicked: root.maximizeHorizontallyClicked();
100+ onMaximizeVerticallyClicked: root.maximizeVerticallyClicked();
94101 closeButtonShown: root.target.application.appId !== "unity8-dash"
95102 target: root.target
96− onClose: root.close();
97− onMinimize: root.minimize();
98− onMaximize: root.maximize();
99103 }
100104
101105 Label {
qml/Stages/WindowResizeArea.qml+25−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -82,15 +82,35 @@ MouseArea {
8282 target.y = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight); });
8383
8484 var windowState = windowStateStorage.getState(root.windowId, WindowStateStorage.WindowStateNormal)
85− if (windowState === WindowStateStorage.WindowStateMaximized) {
86− target.maximize(false)
85+ switch (windowState) {
86+ case WindowStateStorage.WindowStateNormal:
87+ break;
88+ case WindowStateStorage.WindowStateMaximized:
89+ target.maximize(false);
90+ break;
91+ case WindowStateStorage.WindowStateMaximizedLeft:
92+ target.maximizeLeft(false);
93+ break;
94+ case WindowStateStorage.WindowStateMaximizedRight:
95+ target.maximizeRight(false);
96+ break;
97+ case WindowStateStorage.WindowStateMaximizedHorizontally:
98+ target.maximizeHorizontally(false);
99+ break;
100+ case WindowStateStorage.WindowStateMaximizedVertically:
101+ target.maximizeVertically(false);
102+ break;
103+ default:
104+ console.warn("Unsupported window state");
105+ break;
87106 }
107+
88108 priv.updateNormalGeometry();
89109 }
90110
91111 function saveWindowState() {
92− windowStateStorage.saveState(root.windowId, target.state == "maximized" ? WindowStateStorage.WindowStateMaximized : WindowStateStorage.WindowStateNormal)
93− windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight))
112+ windowStateStorage.saveState(root.windowId, target.windowState & ~WindowStateStorage.WindowStateMinimized); // clear the minimized bit when saving
113+ windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight));
94114 }
95115
96116 QtObject {
tests/mocks/Utils/windowstatestorage.h+14−3
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2015 Canonical Ltd.
2+ * Copyright 2015-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU Lesser General Public License as published by
@@ -25,9 +25,20 @@ class WindowStateStorage: public QObject
2525 Q_ENUMS(WindowState)
2626public:
2727 enum WindowState {
28− WindowStateNormal,
29− WindowStateMaximized
28+ WindowStateNormal = 1 << 0,
29+ WindowStateMaximized = 1 << 1,
30+ WindowStateMinimized = 1 << 2,
31+ WindowStateFullscreen = 1 << 3,
32+ WindowStateMaximizedLeft = 1 << 4,
33+ WindowStateMaximizedRight = 1 << 5,
34+ WindowStateMaximizedHorizontally = 1 << 6,
35+ WindowStateMaximizedVertically = 1 << 7
3036 };
37+ Q_DECLARE_FLAGS(WindowStates, WindowState)
38+#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
39+ Q_FLAG(WindowStates)
40+#endif
41+
3142 WindowStateStorage(QObject *parent = 0);
3243
3344 Q_INVOKABLE void saveState(const QString &windowId, WindowState state);
tests/qmltests/Stages/tst_DesktopStage.qml+31−1
@@ -462,6 +462,36 @@ Item {
462462 verify(topSurfaceList.indexForId(dialerSurfaceId) === -1);
463463 }
464464
465+ function test_windowMaximizeHorizontally() {
466+ var dialerDelegate = startApplication("dialer-app");
467+
468+ var dialerMaximizeButton = findChild(dialerDelegate, "maximizeWindowButton");
469+ verify(dialerMaximizeButton);
470+
471+ // RMB to maximize horizontally
472+ mouseClick(dialerMaximizeButton, dialerMaximizeButton.width/2, dialerMaximizeButton.height/2, Qt.RightButton);
473+ tryCompare(dialerDelegate, "windowState", WindowStateStorage.WindowStateMaximizedHorizontally);
474+
475+ // click again to restore
476+ mouseClick(dialerMaximizeButton);
477+ tryCompare(dialerDelegate, "windowState", WindowStateStorage.WindowStateNormal);
478+ }
479+
480+ function test_windowMaximizeVertically() {
481+ var dialerDelegate = startApplication("dialer-app");
482+
483+ var dialerMaximizeButton = findChild(dialerDelegate, "maximizeWindowButton");
484+ verify(dialerMaximizeButton);
485+
486+ // MMB to maximize vertically
487+ mouseClick(dialerMaximizeButton, dialerMaximizeButton.width/2, dialerMaximizeButton.height/2, Qt.MiddleButton);
488+ tryCompare(dialerDelegate, "windowState", WindowStateStorage.WindowStateMaximizedVertically);
489+
490+ // click again to restore
491+ mouseClick(dialerMaximizeButton);
492+ tryCompare(dialerDelegate, "windowState", WindowStateStorage.WindowStateNormal);
493+ }
494+
465495 function test_smashCursorKeys() {
466496 var apps = ["dialer-app", "gmail-webapp"];
467497 apps.forEach(startApplication);
@@ -483,7 +513,7 @@ Item {
483513 verify(decoratedWindow);
484514
485515 tryCompare(dashSurface, "visible", true);
486− decoratedWindow.minimize();
516+ decoratedWindow.minimizeClicked();
487517 tryCompare(dashSurface, "visible", false);
488518 }
489519
tests/qmltests/Stages/tst_WindowResizeArea.qml+16−5
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2014-2015 Canonical Ltd.
2+ * Copyright 2014-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@ import "../../../qml/Stages"
2424import Ubuntu.Components 1.3
2525import Ubuntu.Components.ListItems 1.3 as ListItem
2626import Unity.Application 0.1
27+import Utils 0.1
2728
2829Item {
2930 id: root
@@ -55,10 +56,20 @@ Item {
5556 property real maximumHeight: 0
5657 property real widthIncrement: 0
5758 property real heightIncrement: 0
58− state: "normal"
59+
60+ property int windowState: WindowStateStorage.WindowStateNormal
61+
62+ states: [
63+ State { name: "normal"; when: windowState == WindowStateStorage.WindowStateNormal },
64+ State { name: "maximized"; when: windowState == WindowStateStorage.WindowStateMaximized }
65+ ]
5966
6067 function maximize() {
61− state = "maximized"
68+ windowState = WindowStateStorage.WindowStateMaximized
69+ }
70+
71+ function restoreFromMaximized() {
72+ windowState = WindowStateStorage.WindowStateNormal
6273 }
6374
6475 WindowResizeArea {
@@ -346,7 +357,7 @@ Item {
346357 fakeWindow.y = initialWindowY + moveDelta
347358
348359 // Now change the state to maximized. The window should not keep updating the stored values
349− fakeWindow.state = "maximized"
360+ fakeWindow.maximize()
350361 fakeWindow.x = 31415 // 0 is too risky to pass the test even when broken
351362 fakeWindow.y = 31415
352363
@@ -363,7 +374,7 @@ Item {
363374 tryCompare(fakeWindow, "state", "maximized")
364375
365376 // clean up
366− fakeWindow.state = "normal"
377+ fakeWindow.restoreFromMaximized()
367378 }
368379
369380 function test_restoreMovesIntoBounds_data() {