2 * Copyright (C) 2014-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 import Ubuntu.Components 1.3
19 import Unity.Application 0.1
20 import "../Components/PanelState"
21 import "../Components"
23 import Ubuntu.Gestures 0.1
24 import GlobalShortcut 1.0
29 paintBackground: false
31 // functions to be called from outside
32 function updateFocusedAppOrientation() { /* TODO */ }
33 function updateFocusedAppOrientationAnimated() { /* TODO */}
34 function pushRightEdge(amount) {
35 if (spread.state === "") {
36 edgeBarrier.push(amount);
39 function closeFocusedDelegate() {
40 if (priv.focusedAppDelegate && !priv.focusedAppDelegate.isDash) {
41 priv.focusedAppDelegate.close();
45 // Used by TutorialRight
46 property bool spreadShown: spread.state == "altTab"
48 // used by the snap windows (edge maximize) feature
49 readonly property alias previewRectangle: fakeRectangle
51 mainApp: priv.focusedAppDelegate ? priv.focusedAppDelegate.application : null
53 // application windows never rotate independently
54 mainAppWindowOrientationAngle: shellOrientationAngle
56 orientationChangesEnabled: true
59 itemConfiningMouseCursor: !spreadShown && priv.focusedAppDelegate && priv.focusedAppDelegate.surface &&
60 priv.focusedAppDelegate.surface.confinesMousePointer ?
61 priv.focusedAppDelegate.clientAreaItem : null;
64 id: showSpreadShortcut
65 shortcut: Qt.MetaModifier|Qt.Key_W
66 onTriggered: spread.state = "altTab"
70 id: minimizeAllShortcut
71 shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_D
72 onTriggered: priv.minimizeAllWindows()
76 id: maximizeWindowShortcut
77 shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Up
78 onTriggered: priv.focusedAppDelegate.maximize()
79 active: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.canBeMaximized
83 id: maximizeWindowLeftShortcut
84 shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Left
85 onTriggered: priv.focusedAppDelegate.maximizeLeft()
86 active: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.canBeMaximizedLeftRight
90 id: maximizeWindowRightShortcut
91 shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Right
92 onTriggered: priv.focusedAppDelegate.maximizeRight()
93 active: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.canBeMaximizedLeftRight
97 id: minimizeRestoreShortcut
98 shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Down
99 onTriggered: priv.focusedAppDelegate.anyMaximized
100 ? priv.focusedAppDelegate.restoreFromMaximized() : priv.focusedAppDelegate.minimize()
101 active: priv.focusedAppDelegate !== null
105 shortcut: Qt.AltModifier|Qt.Key_Print
106 onTriggered: root.itemSnapshotRequested(priv.focusedAppDelegate)
107 active: priv.focusedAppDelegate !== null
111 target: root.topLevelSurfaceList
113 if (spread.state == "altTab") {
121 objectName: "DesktopStagePrivate"
123 property var focusedAppDelegate: null
124 onFocusedAppDelegateChanged: {
125 if (spread.state == "altTab") {
130 property var foregroundMaximizedAppDelegate: null // for stuff like drop shadow and focusing maximized app by clicking panel
132 function updateForegroundMaximizedApp() {
134 for (var i = 0; i < appRepeater.count && !found; i++) {
135 var item = appRepeater.itemAt(i);
136 if (item && item.visuallyMaximized) {
137 foregroundMaximizedAppDelegate = item;
142 foregroundMaximizedAppDelegate = null;
146 function minimizeAllWindows() {
147 for (var i = 0; i < appRepeater.count; i++) {
148 var appDelegate = appRepeater.itemAt(i);
149 if (appDelegate && !appDelegate.minimized) {
150 appDelegate.minimize();
155 function focusNext() {
156 for (var i = 0; i < appRepeater.count; i++) {
157 var appDelegate = appRepeater.itemAt(i);
158 if (appDelegate && !appDelegate.minimized) {
159 appDelegate.focus = true;
165 readonly property real virtualKeyboardHeight: SurfaceManager.inputMethodSurface
166 ? SurfaceManager.inputMethodSurface.inputBounds.height
172 onCloseClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } }
173 onMinimizeClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.minimize(); } }
174 onRestoreClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.restoreFromMaximized(); } }
179 property: "buttonsVisible"
180 value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized // FIXME for Locally integrated menus
181 && spread.state == ""
188 if (priv.focusedAppDelegate !== null && spread.state == "") {
189 if (priv.focusedAppDelegate.maximized)
190 return priv.focusedAppDelegate.title
192 return priv.focusedAppDelegate.appName
196 when: priv.focusedAppDelegate
201 property: "dropShadow"
202 value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppDelegate !== null
207 property: "closeButtonShown"
208 value: priv.focusedAppDelegate && priv.focusedAppDelegate.maximized && !priv.focusedAppDelegate.isDash
211 Component.onDestruction: {
212 PanelState.title = "";
213 PanelState.buttonsVisible = false;
214 PanelState.dropShadow = false;
218 model: root.applicationManager
220 target: model.application
221 property: "requestedState"
223 // TODO: figure out some lifecycle policy, like suspending minimized apps
224 // if running on a tablet or something.
225 // TODO: If the device has a dozen suspended apps because it was running
226 // in staged mode, when it switches to Windowed mode it will suddenly
227 // resume all those apps at once. We might want to avoid that.
228 value: ApplicationInfoInterface.RequestedRunning // Always running for now
233 target: MirFocusController
234 property: "focusedSurface"
235 value: priv.focusedAppDelegate ? priv.focusedAppDelegate.focusedSurface : null
236 when: !appRepeater.startingUp && root.parent
241 objectName: "appContainer"
243 focus: spread.state !== "altTab"
248 source: root.background
251 TopLevelSurfaceRepeater {
253 model: topLevelSurfaceList
254 objectName: "appRepeater"
256 delegate: FocusScope {
258 objectName: "appDelegate_" + model.id
259 // z might be overriden in some cases by effects, but we need z ordering
260 // to calculate occlusion detection
261 property int normalZ: topLevelSurfaceList.count - index
263 if (visuallyMaximized) {
264 priv.updateForegroundMaximizedApp();
268 x: requestedX // may be overridden in some states. Do not directly write to this.
269 y: requestedY // may be overridden in some states. Do not directly write to this.
270 property real requestedX: priv.focusedAppDelegate ? priv.focusedAppDelegate.x + units.gu(3) : (normalZ - 1) * units.gu(3)
271 property real requestedY: priv.focusedAppDelegate ? priv.focusedAppDelegate.y + units.gu(3) : normalZ * units.gu(3)
276 value: appDelegate.requestedY -
277 Math.min(appDelegate.requestedY - PanelState.panelHeight,
278 Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
279 when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored")
280 && SurfaceManager.inputMethodSurface
281 && SurfaceManager.inputMethodSurface.state != Mir.HiddenState
282 && SurfaceManager.inputMethodSurface.state != Mir.MinimizedState
286 width: decoratedWindow.width
287 height: decoratedWindow.height
291 onShellOrientationAngleChanged: {
292 // at this point decoratedWindow.surfaceOrientationAngle is the old shellOrientationAngle
293 if (application && application.rotatesWindowContents) {
294 if (state == "normal" || state == "restored") {
295 var angleDiff = decoratedWindow.surfaceOrientationAngle - shellOrientationAngle;
296 angleDiff = (360 + angleDiff) % 360;
297 if (angleDiff === 90 || angleDiff === 270) {
298 var aux = decoratedWindow.requestedHeight;
299 decoratedWindow.requestedHeight = decoratedWindow.requestedWidth + decoratedWindow.visibleDecorationHeight;
300 decoratedWindow.requestedWidth = aux - decoratedWindow.visibleDecorationHeight;
303 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
305 decoratedWindow.surfaceOrientationAngle = 0;
310 readonly property alias application: decoratedWindow.application
311 readonly property alias minimumWidth: decoratedWindow.minimumWidth
312 readonly property alias minimumHeight: decoratedWindow.minimumHeight
313 readonly property alias maximumWidth: decoratedWindow.maximumWidth
314 readonly property alias maximumHeight: decoratedWindow.maximumHeight
315 readonly property alias widthIncrement: decoratedWindow.widthIncrement
316 readonly property alias heightIncrement: decoratedWindow.heightIncrement
317 property int requestedWidth: -1
318 property int requestedHeight: -1
320 readonly property bool maximized: windowState === WindowStateStorage.WindowStateMaximized
321 readonly property bool maximizedLeft: windowState === WindowStateStorage.WindowStateMaximizedLeft
322 readonly property bool maximizedRight: windowState === WindowStateStorage.WindowStateMaximizedRight
323 readonly property bool maximizedHorizontally: windowState === WindowStateStorage.WindowStateMaximizedHorizontally
324 readonly property bool maximizedVertically: windowState === WindowStateStorage.WindowStateMaximizedVertically
325 readonly property bool maximizedTopLeft: windowState === WindowStateStorage.WindowStateMaximizedTopLeft
326 readonly property bool maximizedTopRight: windowState === WindowStateStorage.WindowStateMaximizedTopRight
327 readonly property bool maximizedBottomLeft: windowState === WindowStateStorage.WindowStateMaximizedBottomLeft
328 readonly property bool maximizedBottomRight: windowState === WindowStateStorage.WindowStateMaximizedBottomRight
329 readonly property bool anyMaximized: maximized || maximizedLeft || maximizedRight || maximizedHorizontally || maximizedVertically ||
330 maximizedTopLeft || maximizedTopRight || maximizedBottomLeft || maximizedBottomRight
332 readonly property bool minimized: windowState & WindowStateStorage.WindowStateMinimized
333 readonly property alias fullscreen: decoratedWindow.fullscreen
335 readonly property bool canBeMaximized: canBeMaximizedHorizontally && canBeMaximizedVertically
336 readonly property bool canBeMaximizedLeftRight: (maximumWidth == 0 || maximumWidth >= appContainer.width/2) &&
337 (maximumHeight == 0 || maximumHeight >= appContainer.height)
338 readonly property bool canBeCornerMaximized: (maximumWidth == 0 || maximumWidth >= appContainer.width/2) &&
339 (maximumHeight == 0 || maximumHeight >= appContainer.height/2)
340 readonly property bool canBeMaximizedHorizontally: maximumWidth == 0 || maximumWidth >= appContainer.width
341 readonly property bool canBeMaximizedVertically: maximumHeight == 0 || maximumHeight >= appContainer.height
343 property int windowState: WindowStateStorage.WindowStateNormal
344 property bool animationsEnabled: true
345 property alias title: decoratedWindow.title
346 readonly property string appName: model.application ? model.application.name : ""
347 property bool visuallyMaximized: false
348 property bool visuallyMinimized: false
350 readonly property var surface: model.surface
351 readonly property alias resizeArea: resizeArea
352 readonly property alias focusedSurface: decoratedWindow.focusedSurface
353 readonly property bool dragging: touchControls.overlayShown ? touchControls.dragging : decoratedWindow.dragging
355 readonly property bool isDash: model.application.appId == "unity8-dash"
356 readonly property alias clientAreaItem: decoratedWindow.clientAreaItem
358 function claimFocus() {
359 if (spread.state == "altTab") {
362 appDelegate.restore(true /* animated */, appDelegate.windowState);
365 target: model.surface
366 onFocusRequested: claimFocus();
369 target: model.application
371 if (!model.surface) {
372 // when an app has no surfaces, we assume there's only one entry representing it:
376 // if the application has surfaces, focus request should be at surface-level.
382 if (appRepeater.startingUp)
386 // If we're orphan (!parent) it means this stage is no longer the current one
387 // and will be deleted shortly. So we should no longer have a say over the model
389 topLevelSurfaceList.raiseId(model.id);
392 priv.focusedAppDelegate = appDelegate;
393 } else if (!focus && priv.focusedAppDelegate === appDelegate) {
394 priv.focusedAppDelegate = null;
395 // FIXME: No idea why the Binding{} doens't update when focusedAppDelegate turns null
396 MirFocusController.focusedSurface = null;
399 Component.onCompleted: {
400 if (application && application.rotatesWindowContents) {
401 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
403 decoratedWindow.surfaceOrientationAngle = 0;
406 // NB: We're differentiating if this delegate was created in response to a new entry in the model
407 // or if the Repeater is just populating itself with delegates to match the model it received.
408 if (!appRepeater.startingUp) {
409 // a top level window is always the focused one when it first appears, unfocusing
410 // any preexisting one
414 Component.onDestruction: {
416 // This stage is about to be destroyed. Don't mess up with the model at this point
420 if (visuallyMaximized) {
421 priv.updateForegroundMaximizedApp();
425 // focus some other window
426 for (var i = 0; i < appRepeater.count; i++) {
427 var appDelegate = appRepeater.itemAt(i);
428 if (appDelegate && !appDelegate.minimized && i != index) {
429 appDelegate.focus = true;
436 onVisuallyMaximizedChanged: priv.updateForegroundMaximizedApp()
440 && !greeter.fullyShown
441 && (priv.foregroundMaximizedAppDelegate === null || priv.foregroundMaximizedAppDelegate.normalZ <= z)
443 || decoratedWindow.fullscreen
444 || (spread.state == "altTab" && index === spread.highlightedIndex)
447 model.surface.close();
450 function maximize(animated) {
451 animationsEnabled = (animated === undefined) || animated;
452 windowState = WindowStateStorage.WindowStateMaximized;
454 function maximizeLeft(animated) {
455 animationsEnabled = (animated === undefined) || animated;
456 windowState = WindowStateStorage.WindowStateMaximizedLeft;
458 function maximizeRight(animated) {
459 animationsEnabled = (animated === undefined) || animated;
460 windowState = WindowStateStorage.WindowStateMaximizedRight;
462 function maximizeHorizontally(animated) {
463 animationsEnabled = (animated === undefined) || animated;
464 windowState = WindowStateStorage.WindowStateMaximizedHorizontally;
466 function maximizeVertically(animated) {
467 animationsEnabled = (animated === undefined) || animated;
468 windowState = WindowStateStorage.WindowStateMaximizedVertically;
470 function maximizeTopLeft(animated) {
471 animationsEnabled = (animated === undefined) || animated;
472 windowState = WindowStateStorage.WindowStateMaximizedTopLeft;
474 function maximizeTopRight(animated) {
475 animationsEnabled = (animated === undefined) || animated;
476 windowState = WindowStateStorage.WindowStateMaximizedTopRight;
478 function maximizeBottomLeft(animated) {
479 animationsEnabled = (animated === undefined) || animated;
480 windowState = WindowStateStorage.WindowStateMaximizedBottomLeft;
482 function maximizeBottomRight(animated) {
483 animationsEnabled = (animated === undefined) || animated;
484 windowState = WindowStateStorage.WindowStateMaximizedBottomRight;
486 function minimize(animated) {
487 animationsEnabled = (animated === undefined) || animated;
488 windowState |= WindowStateStorage.WindowStateMinimized; // add the minimized bit
490 function restoreFromMaximized(animated) {
491 animationsEnabled = (animated === undefined) || animated;
492 windowState = WindowStateStorage.WindowStateRestored;
494 function restore(animated,state) {
495 animationsEnabled = (animated === undefined) || animated;
496 windowState = state || WindowStateStorage.WindowStateRestored;
497 windowState &= ~WindowStateStorage.WindowStateMinimized; // clear the minimized bit
501 function playFocusAnimation() {
502 focusAnimation.start()
505 UbuntuNumberAnimation {
511 duration: UbuntuAnimation.SnapDuration
514 // unlike requestedX/Y, this is the last known grab position before being pushed against edges/corners
515 // when restoring, the window should return to these, not to the place where it was dropped near the edge
516 property real restoredX
517 property real restoredY
521 name: "fullscreen"; when: appDelegate.fullscreen && !appDelegate.minimized
524 x: rotation == 0 ? 0 : (parent.width - width) / 2 + (shellOrientationAngle == 90 ? -PanelState.panelHeight : PanelState.panelHeight)
525 y: rotation == 0 ? -PanelState.panelHeight : (parent.height - height) / 2
526 requestedWidth: appContainer.width;
527 requestedHeight: appContainer.height;
532 when: appDelegate.windowState == WindowStateStorage.WindowStateNormal
535 visuallyMinimized: false;
536 visuallyMaximized: false
541 when: appDelegate.windowState == WindowStateStorage.WindowStateRestored
545 requestedX: restoredX;
546 requestedY: restoredY;
550 name: "maximized"; when: appDelegate.maximized && !appDelegate.minimized
553 requestedX: root.leftMargin;
555 requestedWidth: appContainer.width - root.leftMargin;
556 requestedHeight: appContainer.height;
557 visuallyMinimized: false;
558 visuallyMaximized: true
562 name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized
565 requestedX: root.leftMargin
566 requestedY: PanelState.panelHeight
567 requestedWidth: (appContainer.width - root.leftMargin)/2
568 requestedHeight: appContainer.height - PanelState.panelHeight
572 name: "maximizedRight"; when: appDelegate.maximizedRight && !appDelegate.minimized
573 extend: "maximizedLeft"
576 requestedX: (appContainer.width + root.leftMargin)/2
580 name: "maximizedTopLeft"; when: appDelegate.maximizedTopLeft && !appDelegate.minimized
583 requestedX: root.leftMargin
584 requestedY: PanelState.panelHeight
585 requestedWidth: (appContainer.width - root.leftMargin)/2
586 requestedHeight: (appContainer.height - PanelState.panelHeight)/2
590 name: "maximizedTopRight"; when: appDelegate.maximizedTopRight && !appDelegate.minimized
591 extend: "maximizedTopLeft"
594 requestedX: (appContainer.width + root.leftMargin)/2
598 name: "maximizedBottomLeft"; when: appDelegate.maximizedBottomLeft && !appDelegate.minimized
601 requestedX: root.leftMargin
602 requestedY: (appContainer.height + PanelState.panelHeight)/2
603 requestedWidth: (appContainer.width - root.leftMargin)/2
604 requestedHeight: appContainer.height/2
608 name: "maximizedBottomRight"; when: appDelegate.maximizedBottomRight && !appDelegate.minimized
609 extend: "maximizedBottomLeft"
612 requestedX: (appContainer.width + root.leftMargin)/2
616 name: "maximizedHorizontally"; when: appDelegate.maximizedHorizontally && !appDelegate.minimized
617 PropertyChanges { target: appDelegate; requestedX: root.leftMargin; requestedY: requestedY; requestedWidth: appContainer.width - root.leftMargin }
620 name: "maximizedVertically"; when: appDelegate.maximizedVertically && !appDelegate.minimized
621 PropertyChanges { target: appDelegate; requestedX: requestedX; requestedY: PanelState.panelHeight; requestedHeight: appContainer.height - PanelState.panelHeight }
624 name: "minimized"; when: appDelegate.minimized
627 requestedX: -appDelegate.width / 2;
628 scale: units.gu(5) / appDelegate.width;
630 visuallyMinimized: true;
631 visuallyMaximized: false
637 to: "normal,restored"
638 enabled: appDelegate.animationsEnabled
639 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
640 UbuntuNumberAnimation { target: appDelegate; properties: "requestedX,requestedY,opacity,scale,requestedWidth,requestedHeight" }
644 enabled: appDelegate.animationsEnabled
645 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
646 SequentialAnimation {
647 UbuntuNumberAnimation { target: appDelegate; properties: "requestedX,requestedY,opacity,scale,requestedWidth,requestedHeight" }
648 PropertyAction { target: appDelegate; property: "visuallyMinimized" }
651 if (appDelegate.minimized) {
652 appDelegate.focus = false;
660 to: "*" //maximized and fullscreen
661 enabled: appDelegate.animationsEnabled
662 PropertyAction { target: appDelegate; property: "visuallyMinimized" }
663 SequentialAnimation {
664 UbuntuNumberAnimation { target: appDelegate; properties: "requestedX,requestedY,opacity,scale,requestedWidth,requestedHeight" }
665 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
666 ScriptAction { script: { fakeRectangle.stop(); } }
675 value: topLevelSurfaceList.count + 1
676 when: index == spread.highlightedIndex && spread.ready
681 property: "buttonsAlwaysVisible"
682 value: appDelegate && appDelegate.maximized && touchControls.overlayShown
687 objectName: "windowResizeArea"
689 // workaround so that it chooses the correct resize borders when you drag from a corner ResizeGrip
690 anchors.margins: touchControls.overlayShown ? borderThickness/2 : -borderThickness
693 minWidth: units.gu(10)
694 minHeight: units.gu(10)
695 borderThickness: units.gu(2)
696 windowId: model.application.appId // FIXME: Change this to point to windowId once we have such a thing
697 screenWidth: appContainer.width
698 screenHeight: appContainer.height
699 leftMargin: root.leftMargin
701 onPressed: { appDelegate.focus = true; }
703 Component.onCompleted: {
707 property bool saveStateOnDestruction: true
710 onStageAboutToBeUnloaded: {
711 resizeArea.saveWindowState();
712 resizeArea.saveStateOnDestruction = false;
713 fullscreenPolicy.active = false;
716 Component.onDestruction: {
717 if (saveStateOnDestruction) {
725 objectName: "decoratedWindow"
726 anchors.left: appDelegate.left
727 anchors.top: appDelegate.top
728 application: model.application
729 surface: model.surface
730 active: appDelegate.focus
732 maximizeButtonShown: appDelegate.canBeMaximized
733 overlayShown: touchControls.overlayShown
734 stageWidth: appContainer.width
735 stageHeight: appContainer.height
737 requestedWidth: appDelegate.requestedWidth
738 requestedHeight: appDelegate.requestedHeight
740 onCloseClicked: { appDelegate.close(); }
741 onMaximizeClicked: appDelegate.anyMaximized ? appDelegate.restoreFromMaximized() : appDelegate.maximize();
742 onMaximizeHorizontallyClicked: appDelegate.maximizedHorizontally ? appDelegate.restoreFromMaximized() : appDelegate.maximizeHorizontally()
743 onMaximizeVerticallyClicked: appDelegate.maximizedVertically ? appDelegate.restoreFromMaximized() : appDelegate.maximizeVertically()
744 onMinimizeClicked: appDelegate.minimize()
745 onDecorationPressed: { appDelegate.focus = true; }
746 onDecorationReleased: fakeRectangle.commit();
749 WindowControlsOverlay {
752 stageWidth: appContainer.width
753 stageHeight: appContainer.height
755 onFakeMaximizeAnimationRequested: if (!appDelegate.maximized) fakeRectangle.maximize(amount, true)
756 onFakeMaximizeLeftAnimationRequested: if (!appDelegate.maximizedLeft) fakeRectangle.maximizeLeft(amount, true)
757 onFakeMaximizeRightAnimationRequested: if (!appDelegate.maximizedRight) fakeRectangle.maximizeRight(amount, true)
758 onFakeMaximizeTopLeftAnimationRequested: if (!appDelegate.maximizedTopLeft) fakeRectangle.maximizeTopLeft(amount, true);
759 onFakeMaximizeTopRightAnimationRequested: if (!appDelegate.maximizedTopRight) fakeRectangle.maximizeTopRight(amount, true);
760 onFakeMaximizeBottomLeftAnimationRequested: if (!appDelegate.maximizedBottomLeft) fakeRectangle.maximizeBottomLeft(amount, true);
761 onFakeMaximizeBottomRightAnimationRequested: if (!appDelegate.maximizedBottomRight) fakeRectangle.maximizeBottomRight(amount, true);
762 onStopFakeAnimation: fakeRectangle.stop();
763 onDragReleased: fakeRectangle.commit();
766 WindowedFullscreenPolicy {
769 surface: model.surface
775 FakeMaximizeDelegate {
777 target: priv.focusedAppDelegate
778 leftMargin: root.leftMargin
779 appContainerWidth: appContainer.width
780 appContainerHeight: appContainer.height
786 // NB: it does its own positioning according to the specified edge
789 onPassed: { spread.show(); }
790 material: Component {
796 anchors.centerIn: parent
798 GradientStop { position: 0.0; color: Qt.rgba(0.16,0.16,0.16,0.5)}
799 GradientStop { position: 1.0; color: Qt.rgba(0.16,0.16,0.16,0)}
807 direction: Direction.Leftwards
808 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
810 onDraggingChanged: { if (dragging) { spread.show(); } }
816 anchors.fill: appContainer
817 workspace: appContainer
818 focus: state == "altTab"
819 altTabPressed: root.altTabPressed
821 onPlayFocusAnimation: {
822 appRepeater.itemAt(index).playFocusAnimation();