@@ -90,7 +90,8 @@ AbstractStage {
9090 GlobalShortcut {
9191 id: minimizeRestoreShortcut
9292 shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Down
93− onTriggered: priv.focusedAppDelegate.maximized || priv.focusedAppDelegate.maximizedLeft || priv.focusedAppDelegate.maximizedRight
93+ onTriggered: priv.focusedAppDelegate.maximized || priv.focusedAppDelegate.maximizedLeft || priv.focusedAppDelegate.maximizedRight ||
94+ priv.focusedAppDelegate.maximizedHorizontally || priv.focusedAppDelegate.maximizedVertically
9495 ? priv.focusedAppDelegate.restoreFromMaximized() : priv.focusedAppDelegate.minimize()
9596 active: priv.focusedAppDelegate !== null
9697 }
@@ -159,9 +160,9 @@ AbstractStage {
159160
160161 Connections {
161162 target: PanelState
162− onClose: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } }
163− onMinimize: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.minimize(); } }
164− onMaximize: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.restoreFromMaximized(); } }
163+ onCloseClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } }
164+ onMinimizeClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.minimize(); } }
165+ onRestoreClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.restoreFromMaximized(); } }
165166 onFocusMaximizedApp: {
166167 if (priv.foregroundMaximizedAppDelegate) {
167168 priv.foregroundMaximizedAppDelegate.focus = true;
@@ -276,19 +277,16 @@ AbstractStage {
276277 property alias widthIncrement: decoratedWindow.widthIncrement
277278 property alias heightIncrement: decoratedWindow.heightIncrement
278279
279− QtObject {
280− id: appDelegatePrivate
281− property bool maximized: false
282− property bool maximizedLeft: false
283− property bool maximizedRight: false
284− property bool minimized: false
285− }
286− readonly property alias maximized: appDelegatePrivate.maximized
287− readonly property alias maximizedLeft: appDelegatePrivate.maximizedLeft
288− readonly property alias maximizedRight: appDelegatePrivate.maximizedRight
289− readonly property alias minimized: appDelegatePrivate.minimized
280+ readonly property bool maximized: windowState & WindowStateStorage.WindowStateMaximized
281+ readonly property bool maximizedLeft: windowState & WindowStateStorage.WindowStateMaximizedLeft
282+ readonly property bool maximizedRight: windowState & WindowStateStorage.WindowStateMaximizedRight
283+ readonly property bool maximizedHorizontally: windowState & WindowStateStorage.WindowStateMaximizedHorizontally
284+ readonly property bool maximizedVertically: windowState & WindowStateStorage.WindowStateMaximizedVertically
285+ readonly property bool minimized: windowState & WindowStateStorage.WindowStateMinimized
290286 readonly property alias fullscreen: decoratedWindow.fullscreen
291287
288+ property int windowState: WindowStateStorage.WindowStateNormal
289+
292290 readonly property var application: model.application
293291 property bool animationsEnabled: true
294292 property alias title: decoratedWindow.title
@@ -386,43 +384,45 @@ AbstractStage {
386384
387385 function maximize(animated) {
388386 animationsEnabled = (animated === undefined) || animated;
389− appDelegatePrivate.minimized = false;
390− appDelegatePrivate.maximized = true;
391− appDelegatePrivate.maximizedLeft = false;
392− appDelegatePrivate.maximizedRight = false;
387+ windowState = WindowStateStorage.WindowStateMaximized;
388+ }
389+ function maximizeLeft(animated) {
390+ animationsEnabled = (animated === undefined) || animated;
391+ windowState = WindowStateStorage.WindowStateMaximizedLeft;
392+ }
393+ function maximizeRight(animated) {
394+ animationsEnabled = (animated === undefined) || animated;
395+ windowState = WindowStateStorage.WindowStateMaximizedRight;
393396 }
394− function maximizeLeft() {
395− appDelegatePrivate.minimized = false;
396− appDelegatePrivate.maximized = false;
397− appDelegatePrivate.maximizedLeft = true;
398− appDelegatePrivate.maximizedRight = false;
397+ function maximizeHorizontally(animated) {
398+ animationsEnabled = (animated === undefined) || animated;
399+ windowState = WindowStateStorage.WindowStateMaximizedHorizontally;
399400 }
400− function maximizeRight() {
401− appDelegatePrivate.minimized = false;
402− appDelegatePrivate.maximized = false;
403− appDelegatePrivate.maximizedLeft = false;
404− appDelegatePrivate.maximizedRight = true;
401+ function maximizeVertically(animated) {
402+ animationsEnabled = (animated === undefined) || animated;
403+ windowState = WindowStateStorage.WindowStateMaximizedVertically;
405404 }
406405 function minimize(animated) {
407406 animationsEnabled = (animated === undefined) || animated;
408− appDelegatePrivate.minimized = true;
407+ windowState |= WindowStateStorage.WindowStateMinimized; // add the minimized bit
409408 }
410409 function restoreFromMaximized(animated) {
411410 animationsEnabled = (animated === undefined) || animated;
412− appDelegatePrivate.minimized = false;
413− appDelegatePrivate.maximized = false;
414− appDelegatePrivate.maximizedLeft = false;
415− appDelegatePrivate.maximizedRight = false;
411+ windowState = WindowStateStorage.WindowStateNormal;
416412 }
417413 function restore(animated) {
418414 animationsEnabled = (animated === undefined) || animated;
419− appDelegatePrivate.minimized = false;
415+ windowState &= ~WindowStateStorage.WindowStateMinimized; // clear the minimized bit
420416 if (maximized)
421417 maximize();
422418 else if (maximizedLeft)
423419 maximizeLeft();
424420 else if (maximizedRight)
425421 maximizeRight();
422+ else if (maximizedHorizontally)
423+ maximizeHorizontally();
424+ else if (maximizedVertically)
425+ maximizeVertically();
426426
427427 focus = true;
428428 }
@@ -453,8 +453,7 @@ AbstractStage {
453453 },
454454 State {
455455 name: "normal";
456− when: !appDelegate.maximized && !appDelegate.minimized
457− && !appDelegate.maximizedLeft && !appDelegate.maximizedRight
456+ when: appDelegate.windowState == WindowStateStorage.WindowStateNormal
458457 PropertyChanges {
459458 target: appDelegate;
460459 visuallyMinimized: false;
@@ -502,13 +501,23 @@ AbstractStage {
502501 requestedHeight: appContainer.height - PanelState.panelHeight
503502 }
504503 },
504+ State {
505+ name: "maximizedHorizontally"; when: appDelegate.maximizedHorizontally && !appDelegate.minimized
506+ PropertyChanges { target: appDelegate; x: root.leftMargin }
507+ PropertyChanges { target: decoratedWindow; requestedWidth: appContainer.width - root.leftMargin }
508+ },
509+ State {
510+ name: "maximizedVertically"; when: appDelegate.maximizedVertically && !appDelegate.minimized
511+ PropertyChanges { target: appDelegate; y: PanelState.panelHeight }
512+ PropertyChanges { target: decoratedWindow; requestedHeight: appContainer.height - PanelState.panelHeight }
513+ },
505514 State {
506515 name: "minimized"; when: appDelegate.minimized
507516 PropertyChanges {
508517 target: appDelegate;
509518 x: -appDelegate.width / 2;
510519 scale: units.gu(5) / appDelegate.width;
511− opacity: 0
520+ opacity: 0;
512521 visuallyMinimized: true;
513522 visuallyMaximized: false
514523 }
@@ -611,10 +620,13 @@ AbstractStage {
611620 requestedWidth: appDelegate.requestedWidth
612621 requestedHeight: appDelegate.requestedHeight
613622
614− onClose: { appDelegate.close(); }
615− onMaximize: appDelegate.maximized || appDelegate.maximizedLeft || appDelegate.maximizedRight
616− ? appDelegate.restoreFromMaximized() : appDelegate.maximize()
617− onMinimize: appDelegate.minimize()
623+ onCloseClicked: { appDelegate.close(); }
624+ onMaximizeClicked: appDelegate.maximized || appDelegate.maximizedLeft || appDelegate.maximizedRight
625+ || appDelegate.maximizedHorizontally || appDelegate.maximizedVertically
626+ ? appDelegate.restoreFromMaximized() : appDelegate.maximize()
627+ onMaximizeHorizontallyClicked: appDelegate.maximizedHorizontally ? appDelegate.restoreFromMaximized() : appDelegate.maximizeHorizontally()
628+ onMaximizeVerticallyClicked: appDelegate.maximizedVertically ? appDelegate.restoreFromMaximized() : appDelegate.maximizeVertically()
629+ onMinimizeClicked: appDelegate.minimize()
618630 onDecorationPressed: { appDelegate.focus = true; }
619631 }
620632