@@ -48,6 +48,9 @@ FocusScope {
4848 property rect inputMethodRect
4949 property real rightEdgePushProgress: 0
5050 property Item availableDesktopArea
51+ property PanelState panelState
52+
53+ readonly property var temporarySelectedWorkspace: state == "spread" ? screensAndWorkspaces.activeWorkspace : null
5154
5255 // Configuration
5356 property string mode: "staged"
@@ -154,6 +157,7 @@ FocusScope {
154157 function updateFocusedAppOrientationAnimated() { /* TODO */}
155158
156159 function closeSpread() {
160+ spreadItem.highlightedIndex = -1;
157161 priv.goneToSpread = false;
158162 }
159163
@@ -260,6 +264,43 @@ FocusScope {
260264 }
261265 }
262266
267+ GlobalShortcut {
268+ id: showWorkspaceSwitcherShortcutLeft
269+ shortcut: Qt.AltModifier|Qt.ControlModifier|Qt.Key_Left
270+ active: !workspaceSwitcher.active
271+ onTriggered: {
272+ root.focus = true;
273+ workspaceSwitcher.showLeft()
274+ }
275+ }
276+ GlobalShortcut {
277+ id: showWorkspaceSwitcherShortcutRight
278+ shortcut: Qt.AltModifier|Qt.ControlModifier|Qt.Key_Right
279+ active: !workspaceSwitcher.active
280+ onTriggered: {
281+ root.focus = true;
282+ workspaceSwitcher.showRight()
283+ }
284+ }
285+ GlobalShortcut {
286+ id: showWorkspaceSwitcherShortcutUp
287+ shortcut: Qt.AltModifier|Qt.ControlModifier|Qt.Key_Up
288+ active: !workspaceSwitcher.active
289+ onTriggered: {
290+ root.focus = true;
291+ workspaceSwitcher.showUp()
292+ }
293+ }
294+ GlobalShortcut {
295+ id: showWorkspaceSwitcherShortcutDown
296+ shortcut: Qt.AltModifier|Qt.ControlModifier|Qt.Key_Down
297+ active: !workspaceSwitcher.active
298+ onTriggered: {
299+ root.focus = true;
300+ workspaceSwitcher.showDown()
301+ }
302+ }
303+
263304 QtObject {
264305 id: priv
265306 objectName: "DesktopStagePrivate"
@@ -395,23 +436,23 @@ FocusScope {
395436 readonly property real windowDecorationHeight: units.gu(3)
396437 }
397438
398− Component.onCompleted: priv.updateMainAndSideStageIndexes();
439+ Component.onCompleted: priv.updateMainAndSideStageIndexes()
399440
400441 Connections {
401− target: PanelState
442+ target: panelState
402443 onCloseClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } }
403444 onMinimizeClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.requestMinimize(); } }
404445 onRestoreClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.requestRestore(); } }
405446 }
406447
407448 Binding {
408− target: PanelState
449+ target: panelState
409450 property: "decorationsVisible"
410451 value: mode == "windowed" && priv.focusedAppDelegate && priv.focusedAppDelegate.maximized && !root.spreadShown
411452 }
412453
413454 Binding {
414− target: PanelState
455+ target: panelState
415456 property: "title"
416457 value: {
417458 if (priv.focusedAppDelegate !== null) {
@@ -426,7 +467,7 @@ FocusScope {
426467 }
427468
428469 Binding {
429− target: PanelState
470+ target: panelState
430471 property: "focusedPersistentSurfaceId"
431472 value: {
432473 if (priv.focusedAppDelegate !== null) {
@@ -440,21 +481,21 @@ FocusScope {
440481 }
441482
442483 Binding {
443− target: PanelState
484+ target: panelState
444485 property: "dropShadow"
445486 value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppDelegate !== null && mode == "windowed"
446487 }
447488
448489 Binding {
449− target: PanelState
490+ target: panelState
450491 property: "closeButtonShown"
451492 value: priv.focusedAppDelegate && priv.focusedAppDelegate.maximized
452493 }
453494
454495 Component.onDestruction: {
455− PanelState.title = "";
456− PanelState.decorationsVisible = false;
457− PanelState.dropShadow = false;
496+ panelState.title = "";
497+ panelState.decorationsVisible = false;
498+ panelState.dropShadow = false;
458499 }
459500
460501 Instantiator {
@@ -500,6 +541,7 @@ FocusScope {
500541 PropertyChanges { target: noAppsRunningHint; visible: (root.topLevelSurfaceList.count < 1) }
501542 PropertyChanges { target: blurLayer; visible: true; blurRadius: 32; brightness: .65; opacity: 1 }
502543 PropertyChanges { target: wallpaper; visible: false }
544+ PropertyChanges { target: screensAndWorkspaces; opacity: 1 }
503545 },
504546 State {
505547 name: "stagedRightEdge"; when: root.spreadEnabled && (rightEdgeDragArea.dragging || rightEdgePushProgress > 0) && root.mode == "staged"
@@ -554,11 +596,16 @@ FocusScope {
554596 Transition {
555597 from: "stagedRightEdge,sideStagedRightEdge,windowedRightEdge"; to: "spread"
556598 PropertyAction { target: spreadItem; property: "highlightedIndex"; value: -1 }
599+ PropertyAction { target: screensAndWorkspaces; property: "activeWorkspace"; value: WMScreen.currentWorkspace }
557600 PropertyAnimation { target: blurLayer; properties: "brightness,blurRadius"; duration: priv.animationDuration }
601+ UbuntuNumberAnimation { target: screensAndWorkspaces; property: "opacity"; duration: priv.animationDuration }
558602 },
559603 Transition {
560604 to: "spread"
605+ PropertyAction { target: screensAndWorkspaces; property: "activeWorkspace"; value: WMScreen.currentWorkspace }
561606 PropertyAction { target: spreadItem; property: "highlightedIndex"; value: appRepeater.count > 1 ? 1 : 0 }
607+ PropertyAction { target: floatingFlickable; property: "contentX"; value: 0 }
608+ UbuntuNumberAnimation { target: screensAndWorkspaces; property: "opacity"; duration: priv.animationDuration }
562609 },
563610 Transition {
564611 from: "spread"
@@ -616,10 +663,20 @@ FocusScope {
616663 visible: false
617664 }
618665
666+ ScreensAndWorkspaces {
667+ id: screensAndWorkspaces
668+ anchors { left: parent.left; top: parent.top; right: parent.right; leftMargin: root.leftMargin }
669+ height: Math.max(units.gu(30), parent.height * .3)
670+ background: root.background
671+ opacity: 0
672+ visible: opacity > 0
673+ onCloseSpread: priv.goneToSpread = false;
674+ }
675+
619676 Spread {
620677 id: spreadItem
621678 objectName: "spreadItem"
622− anchors.fill: appContainer
679+ anchors { left: parent.left; bottom: parent.bottom; right: parent.right; top: screensAndWorkspaces.bottom }
623680 leftMargin: root.availableDesktopArea.x
624681 model: root.topLevelSurfaceList
625682 spreadFlickable: floatingFlickable
@@ -632,6 +689,89 @@ FocusScope {
632689 onCloseCurrentApp: {
633690 appRepeater.itemAt(highlightedIndex).close();
634691 }
692+
693+ FloatingFlickable {
694+ id: floatingFlickable
695+ objectName: "spreadFlickable"
696+ anchors.fill: parent
697+ enabled: false
698+ contentWidth: spreadItem.spreadTotalWidth
699+
700+ function snap(toIndex) {
701+ var delegate = appRepeater.itemAt(toIndex)
702+ var targetContentX = floatingFlickable.contentWidth / spreadItem.totalItemCount * toIndex;
703+ if (targetContentX - floatingFlickable.contentX > spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) {
704+ var offset = (spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) - (targetContentX - floatingFlickable.contentX)
705+ snapAnimation.to = floatingFlickable.contentX - offset;
706+ snapAnimation.start();
707+ } else if (targetContentX - floatingFlickable.contentX < spreadItem.leftStackXPos + units.gu(1)) {
708+ var offset = (spreadItem.leftStackXPos + units.gu(1)) - (targetContentX - floatingFlickable.contentX);
709+ snapAnimation.to = floatingFlickable.contentX - offset;
710+ snapAnimation.start();
711+ }
712+ }
713+ UbuntuNumberAnimation {id: snapAnimation; target: floatingFlickable; property: "contentX"}
714+ }
715+
716+ MouseArea {
717+ id: hoverMouseArea
718+ objectName: "hoverMouseArea"
719+ anchors.fill: parent
720+ propagateComposedEvents: true
721+ hoverEnabled: true
722+ enabled: false
723+ visible: enabled
724+ property bool wasTouchPress: false
725+
726+ property int scrollAreaWidth: width / 3
727+ property bool progressiveScrollingEnabled: false
728+
729+ onMouseXChanged: {
730+ mouse.accepted = false
731+
732+ if (hoverMouseArea.pressed || wasTouchPress) {
733+ return;
734+ }
735+
736+ // Find the hovered item and mark it active
737+ for (var i = appRepeater.count - 1; i >= 0; i--) {
738+ var appDelegate = appRepeater.itemAt(i);
739+ var mapped = mapToItem(appDelegate, hoverMouseArea.mouseX, hoverMouseArea.mouseY)
740+ var itemUnder = appDelegate.childAt(mapped.x, mapped.y);
741+ if (itemUnder && (itemUnder.objectName === "dragArea" || itemUnder.objectName === "windowInfoItem" || itemUnder.objectName == "closeMouseArea")) {
742+ spreadItem.highlightedIndex = i;
743+ break;
744+ }
745+ }
746+
747+ if (floatingFlickable.contentWidth > floatingFlickable.width) {
748+ var margins = floatingFlickable.width * 0.05;
749+
750+ if (!progressiveScrollingEnabled && mouseX < floatingFlickable.width - scrollAreaWidth) {
751+ progressiveScrollingEnabled = true
752+ }
753+
754+ // do we need to scroll?
755+ if (mouseX < scrollAreaWidth + margins) {
756+ var progress = Math.min(1, (scrollAreaWidth + margins - mouseX) / (scrollAreaWidth - margins));
757+ var contentX = (1 - progress) * (floatingFlickable.contentWidth - floatingFlickable.width)
758+ floatingFlickable.contentX = Math.max(0, Math.min(floatingFlickable.contentX, contentX))
759+ }
760+ if (mouseX > floatingFlickable.width - scrollAreaWidth && progressiveScrollingEnabled) {
761+ var progress = Math.min(1, (mouseX - (floatingFlickable.width - scrollAreaWidth)) / (scrollAreaWidth - margins))
762+ var contentX = progress * (floatingFlickable.contentWidth - floatingFlickable.width)
763+ floatingFlickable.contentX = Math.min(floatingFlickable.contentWidth - floatingFlickable.width, Math.max(floatingFlickable.contentX, contentX))
764+ }
765+ }
766+ }
767+
768+ onPressed: {
769+ mouse.accepted = false;
770+ wasTouchPress = mouse.source === Qt.MouseEventSynthesizedByQt;
771+ }
772+
773+ onExited: wasTouchPress = false;
774+ }
635775 }
636776
637777 Label {
@@ -739,6 +879,24 @@ FocusScope {
739879 }
740880 }
741881
882+ MirSurfaceItem {
883+ id: fakeDragItem
884+ property real previewScale: .5
885+ height: (screensAndWorkspaces.height - units.gu(8)) / 2
886+ // w : h = iw : ih
887+ width: implicitWidth * height / implicitHeight
888+ surfaceWidth: -1
889+ surfaceHeight: -1
890+ opacity: surface != null ? 1 : 0
891+ Behavior on opacity { UbuntuNumberAnimation {} }
892+ visible: opacity > 0
893+
894+ Drag.active: surface != null
895+ Drag.keys: ["application"]
896+
897+ z: 1000
898+ }
899+
742900 Repeater {
743901 id: appRepeater
744902 model: topLevelSurfaceList
@@ -767,6 +925,9 @@ FocusScope {
767925 }
768926 z: normalZ
769927
928+ opacity: fakeDragItem.surface == model.window.surface && fakeDragItem.Drag.active ? 0 : 1
929+ Behavior on opacity { UbuntuNumberAnimation {} }
930+
770931 // Normally we want x/y where the surface thinks it is. Width/height of our delegate will
771932 // match what the actual surface size is.
772933 // Don't write to those, they will be set by states
@@ -946,7 +1107,6 @@ FocusScope {
9461107 function claimFocus() {
9471108 if (root.state == "spread") {
9481109 spreadItem.highlightedIndex = index
949− priv.goneToSpread = false;
9501110 }
9511111 if (root.mode == "stagedWithSideStage") {
9521112 if (appDelegate.stage == ApplicationInfoInterface.SideStage && !sideStage.shown) {
@@ -1280,8 +1440,6 @@ FocusScope {
12801440 y: spreadMaths.targetY
12811441 z: index
12821442 height: spreadItem.spreadItemHeight
1283− requestedWidth: decoratedWindow.oldRequestedWidth
1284− requestedHeight: decoratedWindow.oldRequestedHeight
12851443 visible: spreadMaths.itemVisible
12861444 }
12871445 PropertyChanges { target: dragArea; enabled: true }
@@ -1301,8 +1459,6 @@ FocusScope {
13011459 y: stagedRightEdgeMaths.animatedY
13021460 z: stagedRightEdgeMaths.animatedZ
13031461 height: stagedRightEdgeMaths.animatedHeight
1304− requestedWidth: decoratedWindow.oldRequestedWidth
1305− requestedHeight: decoratedWindow.oldRequestedHeight
13061462 visible: appDelegate.x < root.width
13071463 }
13081464 PropertyChanges {
@@ -1332,8 +1488,6 @@ FocusScope {
13321488 y: windowedRightEdgeMaths.animatedY
13331489 z: windowedRightEdgeMaths.animatedZ
13341490 height: stagedRightEdgeMaths.animatedHeight
1335− requestedWidth: decoratedWindow.oldRequestedWidth
1336− requestedHeight: decoratedWindow.oldRequestedHeight
13371491 }
13381492 PropertyChanges {
13391493 target: decoratedWindow
@@ -1356,11 +1510,15 @@ FocusScope {
13561510 target: appDelegate
13571511 x: stageMaths.itemX
13581512 y: root.availableDesktopArea.y
1359− requestedWidth: appContainer.width
1360− requestedHeight: root.availableDesktopArea.height
13611513 visuallyMaximized: true
13621514 visible: appDelegate.x < root.width
13631515 }
1516+ PropertyChanges {
1517+ target: appDelegate
1518+ requestedWidth: appContainer.width
1519+ requestedHeight: root.availableDesktopArea.height
1520+ restoreEntryValues: false
1521+ }
13641522 PropertyChanges {
13651523 target: decoratedWindow
13661524 hasDecoration: false
@@ -1389,11 +1547,15 @@ FocusScope {
13891547 x: stageMaths.itemX
13901548 y: root.availableDesktopArea.y
13911549 z: stageMaths.itemZ
1392− requestedWidth: stageMaths.itemWidth
1393− requestedHeight: root.availableDesktopArea.height
13941550 visuallyMaximized: true
13951551 visible: appDelegate.x < root.width
13961552 }
1553+ PropertyChanges {
1554+ target: appDelegate
1555+ requestedWidth: stageMaths.itemWidth
1556+ requestedHeight: root.availableDesktopArea.height
1557+ restoreEntryValues: false
1558+ }
13971559 PropertyChanges {
13981560 target: decoratedWindow
13991561 hasDecoration: false
@@ -1414,8 +1576,13 @@ FocusScope {
14141576 requestedX: root.availableDesktopArea.x;
14151577 requestedY: 0;
14161578 visuallyMinimized: false;
1579+ visuallyMaximized: true
1580+ }
1581+ PropertyChanges {
1582+ target: appDelegate
14171583 requestedWidth: root.availableDesktopArea.width;
14181584 requestedHeight: appContainer.height;
1585+ restoreEntryValues: false
14191586 }
14201587 PropertyChanges { target: touchControls; enabled: true }
14211588 PropertyChanges { target: decoratedWindow; windowControlButtonsVisible: false }
@@ -1426,8 +1593,12 @@ FocusScope {
14261593 target: appDelegate;
14271594 requestedX: 0
14281595 requestedY: 0
1429− requestedWidth: appContainer.width;
1430− requestedHeight: appContainer.height;
1596+ }
1597+ PropertyChanges {
1598+ target: appDelegate
1599+ requestedWidth: appContainer.width
1600+ requestedHeight: appContainer.height
1601+ restoreEntryValues: false
14311602 }
14321603 PropertyChanges { target: decoratedWindow; hasDecoration: false }
14331604 },
@@ -1441,6 +1612,12 @@ FocusScope {
14411612 PropertyChanges { target: touchControls; enabled: true }
14421613 PropertyChanges { target: resizeArea; enabled: true }
14431614 PropertyChanges { target: decoratedWindow; shadowOpacity: .3; windowControlButtonsVisible: true}
1615+ PropertyChanges {
1616+ target: appDelegate
1617+ requestedWidth: windowedWidth
1618+ requestedHeight: windowedHeight
1619+ restoreEntryValues: false
1620+ }
14441621 },
14451622 State {
14461623 name: "restored";
@@ -1541,6 +1718,7 @@ FocusScope {
15411718 }
15421719 }
15431720 ]
1721+
15441722 transitions: [
15451723 Transition {
15461724 from: "staged,stagedWithSideStage"
@@ -1554,6 +1732,7 @@ FocusScope {
15541732 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,requestedX,requestedY,requestedWidth,requestedHeight"; duration: priv.animationDuration}
15551733 },
15561734 Transition {
1735+ from: "normal,restored,maximized,maximizedHorizontally,maximizedVertically,maximizedLeft,maximizedRight,maximizedTopLeft,maximizedBottomLeft,maximizedTopRight,maximizedBottomRight,staged,stagedWithSideStage,windowedRightEdge,stagedRightEdge";
15571736 to: "spread"
15581737 // DecoratedWindow wants the scaleToPreviewSize set before enabling scaleToPreview
15591738 PropertyAction { target: appDelegate; properties: "z,visible" }
@@ -1646,7 +1825,7 @@ FocusScope {
16461825 ]
16471826
16481827 Binding {
1649− target: PanelState
1828+ target: panelState
16501829 property: "decorationsAlwaysVisible"
16511830 value: appDelegate && appDelegate.maximized && touchControls.overlayShown
16521831 }
@@ -1667,6 +1846,7 @@ FocusScope {
16671846 borderThickness: units.gu(2)
16681847 enabled: false
16691848 visible: enabled
1849+ readyToAssesBounds: !appDelegate._constructing
16701850
16711851 onPressed: {
16721852 appDelegate.activate();
@@ -1690,18 +1870,13 @@ FocusScope {
16901870 width: implicitWidth
16911871 height: implicitHeight
16921872 highlightSize: windowInfoItem.iconMargin / 2
1693− altDragEnabled: root.mode == "windowed"
16941873 boundsItem: root.availableDesktopArea
1874+ panelState: root.panelState
1875+ altDragEnabled: root.mode == "windowed"
16951876
16961877 requestedWidth: appDelegate.requestedWidth
16971878 requestedHeight: appDelegate.requestedHeight
16981879
1699− property int oldRequestedWidth: -1
1700− property int oldRequestedHeight: -1
1701−
1702− onRequestedWidthChanged: oldRequestedWidth = requestedWidth
1703− onRequestedHeightChanged: oldRequestedHeight = requestedHeight
1704−
17051880 onCloseClicked: { appDelegate.close(); }
17061881 onMaximizeClicked: {
17071882 if (appDelegate.canBeMaximized) {
@@ -1782,6 +1957,8 @@ FocusScope {
17821957 anchors.fill: decoratedWindow
17831958 enabled: false
17841959 closeable: true
1960+ stage: root
1961+ dragDelegate: fakeDragItem
17851962
17861963 onClicked: {
17871964 spreadItem.highlightedIndex = index;
@@ -1824,12 +2001,15 @@ FocusScope {
18242001 objectName: "closeMouseArea"
18252002 anchors { left: parent.left; top: parent.top; leftMargin: -height / 2; topMargin: -height / 2 + spreadMaths.closeIconOffset }
18262003 readonly property var mousePos: hoverMouseArea.mapToItem(appDelegate, hoverMouseArea.mouseX, hoverMouseArea.mouseY)
1827− visible: dragArea.distance == 0
2004+ readonly property bool shown: dragArea.distance == 0
18282005 && index == spreadItem.highlightedIndex
18292006 && mousePos.y < (decoratedWindow.height / 3)
18302007 && mousePos.y > -units.gu(4)
18312008 && mousePos.x > -units.gu(4)
18322009 && mousePos.x < (decoratedWindow.width * 2 / 3)
2010+ opacity: shown ? 1 : 0
2011+ visible: opacity > 0
2012+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
18332013 height: units.gu(6)
18342014 width: height
18352015
@@ -1900,89 +2080,20 @@ FocusScope {
19002080 leftMargin: root.availableDesktopArea.x
19012081 appContainerWidth: appContainer.width
19022082 appContainerHeight: appContainer.height
2083+ panelState: root.panelState
19032084 }
19042085
1905− MouseArea {
1906− id: hoverMouseArea
1907− objectName: "hoverMouseArea"
1908− anchors.fill: appContainer
1909− propagateComposedEvents: true
1910− hoverEnabled: true
1911− enabled: false
1912− visible: enabled
1913−
1914− property int scrollAreaWidth: width / 3
1915− property bool progressiveScrollingEnabled: false
1916− property bool wasTouchPress: false
1917−
1918− onMouseXChanged: {
1919− mouse.accepted = false
1920−
1921− if (hoverMouseArea.pressed || wasTouchPress) {
1922− return;
1923− }
1924−
1925− // Find the hovered item and mark it active
1926− for (var i = appRepeater.count - 1; i >= 0; i--) {
1927− var appDelegate = appRepeater.itemAt(i);
1928− var mapped = mapToItem(appDelegate, hoverMouseArea.mouseX, hoverMouseArea.mouseY)
1929− var itemUnder = appDelegate.childAt(mapped.x, mapped.y);
1930− if (itemUnder && (itemUnder.objectName === "dragArea" || itemUnder.objectName === "windowInfoItem" || itemUnder.objectName == "closeMouseArea")) {
1931− spreadItem.highlightedIndex = i;
1932− break;
1933− }
1934− }
1935−
1936− if (floatingFlickable.contentWidth > floatingFlickable.width) {
1937− var margins = floatingFlickable.width * 0.05;
1938−
1939− if (!progressiveScrollingEnabled && mouseX < floatingFlickable.width - scrollAreaWidth) {
1940− progressiveScrollingEnabled = true
1941− }
1942−
1943− // do we need to scroll?
1944− if (mouseX < scrollAreaWidth + margins) {
1945− var progress = Math.min(1, (scrollAreaWidth + margins - mouseX) / (scrollAreaWidth - margins));
1946− var contentX = (1 - progress) * (floatingFlickable.contentWidth - floatingFlickable.width)
1947− floatingFlickable.contentX = Math.max(0, Math.min(floatingFlickable.contentX, contentX))
1948− }
1949− if (mouseX > floatingFlickable.width - scrollAreaWidth && progressiveScrollingEnabled) {
1950− var progress = Math.min(1, (mouseX - (floatingFlickable.width - scrollAreaWidth)) / (scrollAreaWidth - margins))
1951− var contentX = progress * (floatingFlickable.contentWidth - floatingFlickable.width)
1952− floatingFlickable.contentX = Math.min(floatingFlickable.contentWidth - floatingFlickable.width, Math.max(floatingFlickable.contentX, contentX))
1953− }
1954− }
1955− }
1956−
1957− onPressed: {
1958− mouse.accepted = false;
1959− wasTouchPress = mouse.source === Qt.MouseEventSynthesizedByQt;
1960− }
1961−
1962− onExited: wasTouchPress = false;
1963− }
1964−
1965− FloatingFlickable {
1966− id: floatingFlickable
1967− objectName: "spreadFlickable"
1968− anchors.fill: appContainer
1969− enabled: false
1970− contentWidth: spreadItem.spreadTotalWidth
1971−
1972− function snap(toIndex) {
1973− var delegate = appRepeater.itemAt(toIndex)
1974− var targetContentX = floatingFlickable.contentWidth / spreadItem.totalItemCount * toIndex;
1975− if (targetContentX - floatingFlickable.contentX > spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) {
1976− var offset = (spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) - (targetContentX - floatingFlickable.contentX)
1977− snapAnimation.to = Math.max(0, floatingFlickable.contentX - offset);
1978− snapAnimation.start();
1979− } else if (targetContentX - floatingFlickable.contentX < spreadItem.leftStackXPos + units.gu(1)) {
1980− var offset = (spreadItem.leftStackXPos + units.gu(1)) - (targetContentX - floatingFlickable.contentX);
1981− snapAnimation.to = Math.max(0, floatingFlickable.contentX - offset);
1982− snapAnimation.start();
2086+ WorkspaceSwitcher {
2087+ id: workspaceSwitcher
2088+ anchors.centerIn: parent
2089+ height: units.gu(20)
2090+ width: root.width - units.gu(8)
2091+ background: root.background
2092+ onActiveChanged: {
2093+ if (!active) {
2094+ appContainer.focus = true;
19832095 }
19842096 }
1985− UbuntuNumberAnimation {id: snapAnimation; target: floatingFlickable; property: "contentX"}
19862097 }
19872098
19882099 PropertyAnimation {