@@ -1,5 +1,5 @@
2− * Copyright (C) 2014-2016 Canonical, Ltd.
2+ * Copyright (C) 2014-2017 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@ import GlobalShortcut 1.0
25import GSettings 1.0
25import GSettings 1.0
26import "Spread"
26import "Spread"
27import "Spread/MathUtils.js" as MathUtils
27import "Spread/MathUtils.js" as MathUtils
28+import WindowManager 1.0
29FocusScope {
30FocusScope {
@@ -43,10 +44,10 @@ FocusScope {
43 property int shellOrientationAngle
44 property int shellOrientationAngle
44 property bool spreadEnabled: true // If false, animations and right edge will be disabled
45 property bool spreadEnabled: true // If false, animations and right edge will be disabled
45 property bool suspended
46 property bool suspended
46− property int leftMargin: 0
47 property bool oskEnabled: false
47 property bool oskEnabled: false
48 property rect inputMethodRect
48 property rect inputMethodRect
49 property real rightEdgePushProgress: 0
49 property real rightEdgePushProgress: 0
50+ property Item availableDesktopArea
51 // Configuration
52 // Configuration
52 property string mode: "staged"
53 property string mode: "staged"
@@ -120,6 +121,12 @@ FocusScope {
124+ // For MirAL window management
126+ normal: Qt.rect(0, root.mode === "windowed" ? priv.windowDecorationHeight : 0, 0, 0)
123 property Item itemConfiningMouseCursor: !spreadShown && priv.focusedAppDelegate && priv.focusedAppDelegate.window.confinesMousePointer ?
130 property Item itemConfiningMouseCursor: !spreadShown && priv.focusedAppDelegate && priv.focusedAppDelegate.window.confinesMousePointer ?
124 priv.focusedAppDelegate.clientAreaItem : null;
131 priv.focusedAppDelegate.clientAreaItem : null;
@@ -224,10 +231,30 @@ FocusScope {
224 active: priv.focusedAppDelegate !== null
231 active: priv.focusedAppDelegate !== null
235+ shortcut: Qt.ControlModifier|Qt.AltModifier|Qt.Key_T
237+ // try in this order: snap pkg, new deb name, old deb name
238+ var candidates = ["ubuntu-terminal-app_ubuntu-terminal-app", "ubuntu-terminal-app", "com.ubuntu.terminal"];
239+ for (var i = 0; i < candidates.length; i++) {
240+ if (priv.startApp(candidates[i]))
227 QtObject {
246 QtObject {
229 objectName: "DesktopStagePrivate"
248 objectName: "DesktopStagePrivate"
250+ function startApp(appId) {
251+ if (root.applicationManager.findApplication(appId)) {
252+ return root.applicationManager.requestFocusApplication(appId);
254+ return root.applicationManager.startApplication(appId) !== null;
231 property var focusedAppDelegate: null
258 property var focusedAppDelegate: null
232 property var foregroundMaximizedAppDelegate: null // for stuff like drop shadow and focusing maximized app by clicking panel
259 property var foregroundMaximizedAppDelegate: null // for stuff like drop shadow and focusing maximized app by clicking panel
@@ -347,8 +374,8 @@ FocusScope {
349 readonly property real virtualKeyboardHeight: root.inputMethodRect.height
376 readonly property real virtualKeyboardHeight: root.inputMethodRect.height
351 property bool anyWindowAnimating: false
377 property bool anyWindowAnimating: false
378+ readonly property real windowDecorationHeight: units.gu(3)
354 Component.onCompleted: priv.updateMainAndSideStageIndexes();
381 Component.onCompleted: priv.updateMainAndSideStageIndexes();
@@ -569,7 +596,7 @@ FocusScope {
569 id: spreadItem
596 id: spreadItem
570 objectName: "spreadItem"
597 objectName: "spreadItem"
571 anchors.fill: appContainer
598 anchors.fill: appContainer
572− leftMargin: root.leftMargin
599+ leftMargin: root.availableDesktopArea.x
573 model: root.topLevelSurfaceList
600 model: root.topLevelSurfaceList
574 spreadFlickable: floatingFlickable
601 spreadFlickable: floatingFlickable
@@ -677,13 +704,6 @@ FocusScope {
681− id: boundariesForWindowPlacement
682− anchors.fill: parent
683− anchors.topMargin: PanelState.panelHeight
687 Repeater {
707 Repeater {
688 id: appRepeater
708 id: appRepeater
689 model: topLevelSurfaceList
709 model: topLevelSurfaceList
@@ -781,7 +801,7 @@ FocusScope {
781 target: appDelegate
801 target: appDelegate
782 property: "y"
802 property: "y"
783 value: appDelegate.requestedY -
803 value: appDelegate.requestedY -
784− Math.min(appDelegate.requestedY - PanelState.panelHeight,
804+ Math.min(appDelegate.requestedY - root.availableDesktopArea.y,
785 Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
805 Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
786 when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored")
806 when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored")
787 && root.inputMethodRect.height > 0
807 && root.inputMethodRect.height > 0
@@ -799,8 +819,8 @@ FocusScope {
799 angleDiff = (360 + angleDiff) % 360;
819 angleDiff = (360 + angleDiff) % 360;
800 if (angleDiff === 90 || angleDiff === 270) {
820 if (angleDiff === 90 || angleDiff === 270) {
801 var aux = decoratedWindow.requestedHeight;
821 var aux = decoratedWindow.requestedHeight;
802− decoratedWindow.requestedHeight = decoratedWindow.requestedWidth + decoratedWindow.decorationHeight;
822+ decoratedWindow.requestedHeight = decoratedWindow.requestedWidth + decoratedWindow.actualDecorationHeight;
803− decoratedWindow.requestedWidth = aux - decoratedWindow.decorationHeight;
823+ decoratedWindow.requestedWidth = aux - decoratedWindow.actualDecorationHeight;
806 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
826 decoratedWindow.surfaceOrientationAngle = shellOrientationAngle;
@@ -901,12 +921,13 @@ FocusScope {
901 priv.updateMainAndSideStageIndexes();
921 priv.updateMainAndSideStageIndexes();
903 appDelegate.focus = true;
923 appDelegate.focus = true;
924+ priv.focusedAppDelegate = appDelegate;
906 function updateQmlFocusFromMirSurfaceFocus() {
927 function updateQmlFocusFromMirSurfaceFocus() {
907 if (model.window.focused) {
928 if (model.window.focused) {
908 claimFocus();
929 claimFocus();
909− priv.focusedAppDelegate = appDelegate;
930+ decoratedWindow.focus = true;
@@ -915,8 +936,8 @@ FocusScope {
915 target: appDelegate
936 target: appDelegate
916 screenWidth: appContainer.width
937 screenWidth: appContainer.width
917 screenHeight: appContainer.height
938 screenHeight: appContainer.height
918− leftMargin: root.leftMargin
939+ leftMargin: root.availableDesktopArea.x
919− minimumY: boundariesForWindowPlacement.y
940+ minimumY: root.availableDesktopArea.y
922 Connections {
943 Connections {
@@ -1169,7 +1190,7 @@ FocusScope {
1170 StagedRightEdgeMaths {
1191 StagedRightEdgeMaths {
1171 id: stagedRightEdgeMaths
1192 id: stagedRightEdgeMaths
1172− sceneWidth: appContainer.width - root.leftMargin
1193+ sceneWidth: root.availableDesktopArea.width
1173 sceneHeight: appContainer.height
1194 sceneHeight: appContainer.height
1174 isMainStageApp: priv.mainStageDelegate == appDelegate
1195 isMainStageApp: priv.mainStageDelegate == appDelegate
1175 isSideStageApp: priv.sideStageDelegate == appDelegate
1196 isSideStageApp: priv.sideStageDelegate == appDelegate
@@ -1180,7 +1201,7 @@ FocusScope {
1180 progress: 0
1201 progress: 0
1181 targetHeight: spreadItem.stackHeight
1202 targetHeight: spreadItem.stackHeight
1182 targetX: spreadMaths.targetX
1203 targetX: spreadMaths.targetX
1183− startY: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1204+ startY: appDelegate.fullscreen ? 0 : root.availableDesktopArea.y
1184 targetY: spreadMaths.targetY
1205 targetY: spreadMaths.targetY
1185 targetAngle: spreadMaths.targetAngle
1206 targetAngle: spreadMaths.targetAngle
1186 targetScale: spreadMaths.targetScale
1207 targetScale: spreadMaths.targetScale
@@ -1301,9 +1322,9 @@ FocusScope {
1301 PropertyChanges {
1322 PropertyChanges {
1302 target: appDelegate
1323 target: appDelegate
1303 x: stageMaths.itemX
1324 x: stageMaths.itemX
1304− y: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1325+ y: root.availableDesktopArea.y
1305 requestedWidth: appContainer.width
1326 requestedWidth: appContainer.width
1306− requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - PanelState.panelHeight
1327+ requestedHeight: root.availableDesktopArea.height
1307 visuallyMaximized: true
1328 visuallyMaximized: true
1308 visible: appDelegate.x < root.width
1329 visible: appDelegate.x < root.width
@@ -1333,10 +1354,10 @@ FocusScope {
1333 PropertyChanges {
1354 PropertyChanges {
1334 target: appDelegate
1355 target: appDelegate
1335 x: stageMaths.itemX
1356 x: stageMaths.itemX
1336− y: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1357+ y: root.availableDesktopArea.y
1337 z: stageMaths.itemZ
1358 z: stageMaths.itemZ
1338 requestedWidth: stageMaths.itemWidth
1359 requestedWidth: stageMaths.itemWidth
1339− requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - PanelState.panelHeight
1360+ requestedHeight: root.availableDesktopArea.height
1340 visuallyMaximized: true
1361 visuallyMaximized: true
1341 visible: appDelegate.x < root.width
1362 visible: appDelegate.x < root.width
@@ -1357,11 +1378,11 @@ FocusScope {
1357 name: "maximized"; when: appDelegate.maximized && !appDelegate.minimized
1378 name: "maximized"; when: appDelegate.maximized && !appDelegate.minimized
1358 PropertyChanges {
1379 PropertyChanges {
1359 target: appDelegate;
1380 target: appDelegate;
1360− requestedX: root.leftMargin;
1381+ requestedX: root.availableDesktopArea.x;
1361 requestedY: 0;
1382 requestedY: 0;
1362 visuallyMinimized: false;
1383 visuallyMinimized: false;
1363 visuallyMaximized: true
1384 visuallyMaximized: true
1364− requestedWidth: appContainer.width - root.leftMargin;
1385+ requestedWidth: root.availableDesktopArea.width;
1365 requestedHeight: appContainer.height;
1386 requestedHeight: appContainer.height;
1367 PropertyChanges { target: touchControls; enabled: true }
1388 PropertyChanges { target: touchControls; enabled: true }
@@ -1394,6 +1415,7 @@ FocusScope {
1394 when: appDelegate.windowState == WindowStateStorage.WindowStateRestored
1415 when: appDelegate.windowState == WindowStateStorage.WindowStateRestored
1395 extend: "normal"
1416 extend: "normal"
1396 PropertyChanges {
1417 PropertyChanges {
1418+ restoreEntryValues: false
1397 target: appDelegate;
1419 target: appDelegate;
1398 windowedX: restoredX;
1420 windowedX: restoredX;
1399 windowedY: restoredY;
1421 windowedY: restoredY;
@@ -1404,10 +1426,10 @@ FocusScope {
1404 extend: "normal"
1426 extend: "normal"
1405 PropertyChanges {
1427 PropertyChanges {
1406 target: appDelegate
1428 target: appDelegate
1407− windowedX: root.leftMargin
1429+ windowedX: root.availableDesktopArea.x
1408− windowedY: PanelState.panelHeight
1430+ windowedY: root.availableDesktopArea.y
1409− windowedWidth: (appContainer.width - root.leftMargin)/2
1431+ windowedWidth: root.availableDesktopArea.width / 2
1410− windowedHeight: appContainer.height - PanelState.panelHeight
1432+ windowedHeight: root.availableDesktopArea.height
@@ -1415,7 +1437,7 @@ FocusScope {
1415 extend: "maximizedLeft"
1437 extend: "maximizedLeft"
1416 PropertyChanges {
1438 PropertyChanges {
1417 target: appDelegate;
1439 target: appDelegate;
1418− windowedX: (appContainer.width + root.leftMargin)/2
1440+ windowedX: root.availableDesktopArea.x + (root.availableDesktopArea.width / 2)
@@ -1423,10 +1445,10 @@ FocusScope {
1423 extend: "normal"
1445 extend: "normal"
1424 PropertyChanges {
1446 PropertyChanges {
1425 target: appDelegate
1447 target: appDelegate
1426− windowedX: root.leftMargin
1448+ windowedX: root.availableDesktopArea.x
1427− windowedY: PanelState.panelHeight
1449+ windowedY: root.availableDesktopArea.y
1428− windowedWidth: (appContainer.width - root.leftMargin)/2
1450+ windowedWidth: root.availableDesktopArea.width / 2
1429− windowedHeight: (appContainer.height - PanelState.panelHeight)/2
1451+ windowedHeight: root.availableDesktopArea.height / 2
@@ -1434,7 +1456,7 @@ FocusScope {
1434 extend: "maximizedTopLeft"
1456 extend: "maximizedTopLeft"
1435 PropertyChanges {
1457 PropertyChanges {
1436 target: appDelegate
1458 target: appDelegate
1437− windowedX: (appContainer.width + root.leftMargin)/2
1459+ windowedX: root.availableDesktopArea.x + (root.availableDesktopArea.width / 2)
@@ -1442,10 +1464,10 @@ FocusScope {
1442 extend: "normal"
1464 extend: "normal"
1443 PropertyChanges {
1465 PropertyChanges {
1444 target: appDelegate
1466 target: appDelegate
1445− windowedX: root.leftMargin
1467+ windowedX: root.availableDesktopArea.x
1446− windowedY: (appContainer.height + PanelState.panelHeight)/2
1468+ windowedY: root.availableDesktopArea.y + (root.availableDesktopArea.height / 2)
1447− windowedWidth: (appContainer.width - root.leftMargin)/2
1469+ windowedWidth: root.availableDesktopArea.width / 2
1448− windowedHeight: appContainer.height/2
1470+ windowedHeight: root.availableDesktopArea.height / 2
@@ -1453,20 +1475,26 @@ FocusScope {
1453 extend: "maximizedBottomLeft"
1475 extend: "maximizedBottomLeft"
1454 PropertyChanges {
1476 PropertyChanges {
1455 target: appDelegate
1477 target: appDelegate
1456− windowedX: (appContainer.width + root.leftMargin)/2
1478+ windowedX: root.availableDesktopArea.x + (root.availableDesktopArea.width / 2)
1460 name: "maximizedHorizontally"; when: appDelegate.maximizedHorizontally && !appDelegate.minimized
1482 name: "maximizedHorizontally"; when: appDelegate.maximizedHorizontally && !appDelegate.minimized
1461 extend: "normal"
1483 extend: "normal"
1485+ target: appDelegate
1462− PropertyChanges { target: appDelegate; windowedX: root.leftMargin; windowedY: windowedY;
1486+ windowedX: root.availableDesktopArea.x; windowedY: windowedY
1463− windowedWidth: appContainer.width - root.leftMargin; windowedHeight: windowedHeight }
1487+ windowedWidth: root.availableDesktopArea.width; windowedHeight: windowedHeight
1466 name: "maximizedVertically"; when: appDelegate.maximizedVertically && !appDelegate.minimized
1491 name: "maximizedVertically"; when: appDelegate.maximizedVertically && !appDelegate.minimized
1467 extend: "normal"
1492 extend: "normal"
1494+ target: appDelegate
1468− PropertyChanges { target: appDelegate; windowedX: windowedX; windowedY: PanelState.panelHeight;
1495+ windowedX: windowedX; windowedY: root.availableDesktopArea.y
1469− windowedWidth: windowedWidth; windowedHeight: appContainer.height - PanelState.panelHeight }
1496+ windowedWidth: windowedWidth; windowedHeight: root.availableDesktopArea.height
1472 name: "minimized"; when: appDelegate.minimized
1500 name: "minimized"; when: appDelegate.minimized
@@ -1595,7 +1623,7 @@ FocusScope {
1595 anchors.margins: touchControls.overlayShown ? borderThickness/2 : -borderThickness
1623 anchors.margins: touchControls.overlayShown ? borderThickness/2 : -borderThickness
1597 target: appDelegate
1625 target: appDelegate
1598− boundsItem: boundariesForWindowPlacement
1626+ boundsItem: root.availableDesktopArea
1599 minWidth: units.gu(10)
1627 minWidth: units.gu(10)
1600 minHeight: units.gu(10)
1628 minHeight: units.gu(10)
1601 borderThickness: units.gu(2)
1629 borderThickness: units.gu(2)
@@ -1618,13 +1646,14 @@ FocusScope {
1618 focus: true
1646 focus: true
1619 interactive: root.interactive
1647 interactive: root.interactive
1620 showDecoration: 1
1648 showDecoration: 1
1649+ decorationHeight: priv.windowDecorationHeight
1621 maximizeButtonShown: appDelegate.canBeMaximized
1650 maximizeButtonShown: appDelegate.canBeMaximized
1622 overlayShown: touchControls.overlayShown
1651 overlayShown: touchControls.overlayShown
1623 width: implicitWidth
1652 width: implicitWidth
1624 height: implicitHeight
1653 height: implicitHeight
1625 highlightSize: windowInfoItem.iconMargin / 2
1654 highlightSize: windowInfoItem.iconMargin / 2
1626− boundsItem: boundariesForWindowPlacement
1627 altDragEnabled: root.mode == "windowed"
1655 altDragEnabled: root.mode == "windowed"
1656+ boundsItem: root.availableDesktopArea
1629 requestedWidth: appDelegate.requestedWidth
1658 requestedWidth: appDelegate.requestedWidth
1630 requestedHeight: appDelegate.requestedHeight
1659 requestedHeight: appDelegate.requestedHeight
@@ -1687,7 +1716,7 @@ FocusScope {
1687 resizeArea: resizeArea
1716 resizeArea: resizeArea
1688 enabled: false
1717 enabled: false
1689 visible: enabled
1718 visible: enabled
1690− boundsItem: boundariesForWindowPlacement
1719+ boundsItem: root.availableDesktopArea
1692 onFakeMaximizeAnimationRequested: if (!appDelegate.maximized) fakeRectangle.maximize(amount, true)
1721 onFakeMaximizeAnimationRequested: if (!appDelegate.maximized) fakeRectangle.maximize(amount, true)
1693 onFakeMaximizeLeftAnimationRequested: if (!appDelegate.maximizedLeft) fakeRectangle.maximizeLeft(amount, true)
1722 onFakeMaximizeLeftAnimationRequested: if (!appDelegate.maximizedLeft) fakeRectangle.maximizeLeft(amount, true)
@@ -1808,9 +1837,18 @@ FocusScope {
1808 displacementX: appDelegate.clientAreaItem.x
1837 displacementX: appDelegate.clientAreaItem.x
1809 displacementY: appDelegate.clientAreaItem.y
1838 displacementY: appDelegate.clientAreaItem.y
1811− boundsItem: boundariesForWindowPlacement
1840+ boundsItem: root.availableDesktopArea
1841+ decorationHeight: priv.windowDecorationHeight
1813 z: childWindowRepeater.count - model.index
1843 z: childWindowRepeater.count - model.index
1847+ // some child surface in this tree got focus.
1848+ // Ensure we also have it at the top-level hierarchy
1849+ appDelegate.claimFocus();
@@ -1821,7 +1859,7 @@ FocusScope {
1821 FakeMaximizeDelegate {
1859 FakeMaximizeDelegate {
1822 id: fakeRectangle
1860 id: fakeRectangle
1823 target: priv.focusedAppDelegate
1861 target: priv.focusedAppDelegate
1824− leftMargin: root.leftMargin
1862+ leftMargin: root.availableDesktopArea.x
1825 appContainerWidth: appContainer.width
1863 appContainerWidth: appContainer.width
1826 appContainerHeight: appContainer.height
1864 appContainerHeight: appContainer.height