@@ -46,6 +46,7 @@ FocusScope {
4646 property int leftMargin: 0
4747 property bool oskEnabled: false
4848 property rect inputMethodRect
49+ property PanelState panelState
4950
5051 // Configuration
5152 property string mode: "staged"
@@ -345,23 +346,23 @@ FocusScope {
345346 readonly property real virtualKeyboardHeight: root.inputMethodRect.height
346347 }
347348
348− Component.onCompleted: priv.updateMainAndSideStageIndexes();
349+ Component.onCompleted: {priv.updateMainAndSideStageIndexes(); print("size", root.width, root.height)}
349350
350351 Connections {
351− target: PanelState
352+ target: panelState
352353 onCloseClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } }
353354 onMinimizeClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.requestMinimize(); } }
354355 onRestoreClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.requestRestore(); } }
355356 }
356357
357358 Binding {
358− target: PanelState
359+ target: panelState
359360 property: "decorationsVisible"
360361 value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized // FIXME for Locally integrated menus
361362 }
362363
363364 Binding {
364− target: PanelState
365+ target: panelState
365366 property: "title"
366367 value: {
367368 if (priv.focusedAppDelegate !== null) {
@@ -376,7 +377,7 @@ FocusScope {
376377 }
377378
378379 Binding {
379− target: PanelState
380+ target: panelState
380381 property: "focusedPersistentSurfaceId"
381382 value: {
382383 if (priv.focusedAppDelegate !== null) {
@@ -390,21 +391,21 @@ FocusScope {
390391 }
391392
392393 Binding {
393− target: PanelState
394+ target: panelState
394395 property: "dropShadow"
395396 value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppDelegate !== null && mode == "windowed"
396397 }
397398
398399 Binding {
399− target: PanelState
400+ target: panelState
400401 property: "closeButtonShown"
401402 value: priv.focusedAppDelegate && priv.focusedAppDelegate.maximized && !priv.focusedAppDelegate.isDash
402403 }
403404
404405 Component.onDestruction: {
405− PanelState.title = "";
406− PanelState.decorationsVisible = false;
407− PanelState.dropShadow = false;
406+ panelState.title = "";
407+ panelState.decorationsVisible = false;
408+ panelState.dropShadow = false;
408409 }
409410
410411 Instantiator {
@@ -450,6 +451,7 @@ FocusScope {
450451 PropertyChanges { target: cancelSpreadMouseArea; enabled: true }
451452 PropertyChanges { target: blurLayer; visible: true; blurRadius: 32; brightness: .65; opacity: 1 }
452453 PropertyChanges { target: wallpaper; visible: false }
454+ PropertyChanges { target: screensAndWorkspaces; opacity: 1 }
453455 },
454456 State {
455457 name: "stagedRightEdge"; when: (rightEdgeDragArea.dragging || edgeBarrier.progress > 0) && root.mode == "staged"
@@ -482,7 +484,7 @@ FocusScope {
482484 },
483485 State {
484486 name: "staged"; when: root.mode === "staged"
485− PropertyChanges { target: wallpaper; visible: false }
487+ PropertyChanges { target: wallpaper; visible: priv.focusedAppDelegate && priv.focusedAppDelegate.x === 0 }
486488 },
487489 State {
488490 name: "stagedWithSideStage"; when: root.mode === "stagedWithSideStage"
@@ -498,11 +500,13 @@ FocusScope {
498500 from: "stagedRightEdge,sideStagedRightEdge,windowedRightEdge"; to: "spread"
499501 PropertyAction { target: spreadItem; property: "highlightedIndex"; value: -1 }
500502 PropertyAnimation { target: blurLayer; properties: "brightness,blurRadius"; duration: priv.animationDuration }
503+ UbuntuNumberAnimation { target: screensAndWorkspaces; property: "opacity"; duration: priv.animationDuration }
501504 },
502505 Transition {
503506 to: "spread"
504507 PropertyAction { target: spreadItem; property: "highlightedIndex"; value: appRepeater.count > 1 ? 1 : 0 }
505508 PropertyAction { target: floatingFlickable; property: "contentX"; value: 0 }
509+ UbuntuNumberAnimation { target: screensAndWorkspaces; property: "opacity"; duration: priv.animationDuration }
506510 },
507511 Transition {
508512 from: "spread"
@@ -559,10 +563,19 @@ FocusScope {
559563 visible: false
560564 }
561565
566+ ScreensAndWorkspaces {
567+ id: screensAndWorkspaces
568+ anchors { left: parent.left; top: parent.top; right: parent.right; leftMargin: root.leftMargin }
569+ height: parent.height / 3
570+ background: root.background
571+ opacity: 0
572+ visible: opacity > 0
573+ }
574+
562575 Spread {
563576 id: spreadItem
564577 objectName: "spreadItem"
565− anchors.fill: appContainer
578+ anchors { left: parent.left; bottom: parent.bottom; right: parent.right; top: screensAndWorkspaces.bottom }
566579 leftMargin: root.leftMargin
567580 model: root.topLevelSurfaceList
568581 spreadFlickable: floatingFlickable
@@ -571,6 +584,83 @@ FocusScope {
571584 onLeaveSpread: {
572585 priv.goneToSpread = false;
573586 }
587+
588+ FloatingFlickable {
589+ id: floatingFlickable
590+ objectName: "spreadFlickable"
591+ anchors.fill: parent
592+ enabled: false
593+ contentWidth: spreadItem.spreadTotalWidth
594+
595+ function snap(toIndex) {
596+ var delegate = appRepeater.itemAt(toIndex)
597+ var targetContentX = floatingFlickable.contentWidth / spreadItem.totalItemCount * toIndex;
598+ if (targetContentX - floatingFlickable.contentX > spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) {
599+ var offset = (spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) - (targetContentX - floatingFlickable.contentX)
600+ snapAnimation.to = floatingFlickable.contentX - offset;
601+ snapAnimation.start();
602+ } else if (targetContentX - floatingFlickable.contentX < spreadItem.leftStackXPos + units.gu(1)) {
603+ var offset = (spreadItem.leftStackXPos + units.gu(1)) - (targetContentX - floatingFlickable.contentX);
604+ snapAnimation.to = floatingFlickable.contentX - offset;
605+ snapAnimation.start();
606+ }
607+ }
608+ UbuntuNumberAnimation {id: snapAnimation; target: floatingFlickable; property: "contentX"}
609+ }
610+
611+ MouseArea {
612+ id: hoverMouseArea
613+ objectName: "hoverMouseArea"
614+ anchors.fill: parent
615+ propagateComposedEvents: true
616+ hoverEnabled: true
617+ enabled: false
618+ visible: enabled
619+
620+ property int scrollAreaWidth: width / 3
621+ property bool progressiveScrollingEnabled: false
622+
623+ onPressed: mouse.accepted = false
624+
625+ onMouseXChanged: {
626+ mouse.accepted = false
627+
628+ if (hoverMouseArea.pressed) {
629+ return;
630+ }
631+
632+ // Find the hovered item and mark it active
633+ for (var i = appRepeater.count - 1; i >= 0; i--) {
634+ var appDelegate = appRepeater.itemAt(i);
635+ var mapped = mapToItem(appDelegate, hoverMouseArea.mouseX, hoverMouseArea.mouseY)
636+ var itemUnder = appDelegate.childAt(mapped.x, mapped.y);
637+ if (itemUnder && (itemUnder.objectName === "dragArea" || itemUnder.objectName === "windowInfoItem" || itemUnder.objectName == "closeMouseArea")) {
638+ spreadItem.highlightedIndex = i;
639+ break;
640+ }
641+ }
642+
643+ if (floatingFlickable.contentWidth > floatingFlickable.width) {
644+ var margins = floatingFlickable.width * 0.05;
645+
646+ if (!progressiveScrollingEnabled && mouseX < floatingFlickable.width - scrollAreaWidth) {
647+ progressiveScrollingEnabled = true
648+ }
649+
650+ // do we need to scroll?
651+ if (mouseX < scrollAreaWidth + margins) {
652+ var progress = Math.min(1, (scrollAreaWidth + margins - mouseX) / (scrollAreaWidth - margins));
653+ var contentX = (1 - progress) * (floatingFlickable.contentWidth - floatingFlickable.width)
654+ floatingFlickable.contentX = Math.max(0, Math.min(floatingFlickable.contentX, contentX))
655+ }
656+ if (mouseX > floatingFlickable.width - scrollAreaWidth && progressiveScrollingEnabled) {
657+ var progress = Math.min(1, (mouseX - (floatingFlickable.width - scrollAreaWidth)) / (scrollAreaWidth - margins))
658+ var contentX = progress * (floatingFlickable.contentWidth - floatingFlickable.width)
659+ floatingFlickable.contentX = Math.min(floatingFlickable.contentWidth - floatingFlickable.width, Math.max(floatingFlickable.contentX, contentX))
660+ }
661+ }
662+ }
663+ }
574664 }
575665
576666 Connections {
@@ -665,6 +755,23 @@ FocusScope {
665755 }
666756 }
667757
758+ MirSurfaceItem {
759+ id: fakeDragItem
760+ property real previewScale: .5
761+ width: implicitWidth * previewScale
762+ height: implicitHeight * previewScale
763+ surfaceWidth: -1
764+ surfaceHeight: -1
765+ opacity: surface != null ? 1 : 0
766+ Behavior on opacity { UbuntuNumberAnimation {} }
767+ visible: opacity > 0
768+
769+ Drag.active: surface != null
770+ Drag.keys: ["application"]
771+
772+ z: 1000
773+ }
774+
668775 Item {
669776 id: boundariesForWindowPlacement
670777 anchors.fill: parent
@@ -700,6 +807,9 @@ FocusScope {
700807 }
701808 z: normalZ
702809
810+ opacity: fakeDragItem.surface == model.window.surface && fakeDragItem.Drag.active ? 0 : 1
811+ Behavior on opacity { UbuntuNumberAnimation {} }
812+
703813 // Normally we want x/y where the surface thinks it is. Width/height of our delegate will
704814 // match what the actual surface size is.
705815 // Don't write to those, they will be set by states
@@ -760,7 +870,7 @@ FocusScope {
760870 target: appDelegate
761871 property: "y"
762872 value: appDelegate.requestedY -
763− Math.min(appDelegate.requestedY - PanelState.panelHeight,
873+ Math.min(appDelegate.requestedY - panelState.panelHeight,
764874 Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
765875 when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored")
766876 && root.inputMethodRect.height > 0
@@ -1136,7 +1246,7 @@ FocusScope {
11361246 progress: 0
11371247 targetHeight: spreadItem.stackHeight
11381248 targetX: spreadMaths.targetX
1139− startY: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1249+ startY: appDelegate.fullscreen ? 0 : panelState.panelHeight
11401250 targetY: spreadMaths.targetY
11411251 targetAngle: spreadMaths.targetAngle
11421252 targetScale: spreadMaths.targetScale
@@ -1255,9 +1365,9 @@ FocusScope {
12551365 PropertyChanges {
12561366 target: appDelegate
12571367 x: stageMaths.itemX
1258− y: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1368+ y: appDelegate.fullscreen ? 0 : panelState.panelHeight
12591369 requestedWidth: appContainer.width
1260− requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - PanelState.panelHeight
1370+ requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - panelState.panelHeight
12611371 visuallyMaximized: true
12621372 visible: appDelegate.x < root.width
12631373 }
@@ -1283,10 +1393,10 @@ FocusScope {
12831393 PropertyChanges {
12841394 target: appDelegate
12851395 x: stageMaths.itemX
1286− y: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1396+ y: appDelegate.fullscreen ? 0 : panelState.panelHeight
12871397 z: stageMaths.itemZ
12881398 requestedWidth: stageMaths.itemWidth
1289− requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - PanelState.panelHeight
1399+ requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - panelState.panelHeight
12901400 visuallyMaximized: true
12911401 visible: appDelegate.x < root.width
12921402 }
@@ -1351,9 +1461,9 @@ FocusScope {
13511461 PropertyChanges {
13521462 target: appDelegate
13531463 windowedX: root.leftMargin
1354− windowedY: PanelState.panelHeight
1464+ windowedY: panelState.panelHeight
13551465 windowedWidth: (appContainer.width - root.leftMargin)/2
1356− windowedHeight: appContainer.height - PanelState.panelHeight
1466+ windowedHeight: appContainer.height - panelState.panelHeight
13571467 }
13581468 },
13591469 State {
@@ -1370,9 +1480,9 @@ FocusScope {
13701480 PropertyChanges {
13711481 target: appDelegate
13721482 windowedX: root.leftMargin
1373− windowedY: PanelState.panelHeight
1483+ windowedY: panelState.panelHeight
13741484 windowedWidth: (appContainer.width - root.leftMargin)/2
1375− windowedHeight: (appContainer.height - PanelState.panelHeight)/2
1485+ windowedHeight: (appContainer.height - panelState.panelHeight)/2
13761486 }
13771487 },
13781488 State {
@@ -1389,7 +1499,7 @@ FocusScope {
13891499 PropertyChanges {
13901500 target: appDelegate
13911501 windowedX: root.leftMargin
1392− windowedY: (appContainer.height + PanelState.panelHeight)/2
1502+ windowedY: (appContainer.height + panelState.panelHeight)/2
13931503 windowedWidth: (appContainer.width - root.leftMargin)/2
13941504 windowedHeight: appContainer.height/2
13951505 }
@@ -1411,8 +1521,8 @@ FocusScope {
14111521 State {
14121522 name: "maximizedVertically"; when: appDelegate.maximizedVertically && !appDelegate.minimized
14131523 extend: "normal"
1414− PropertyChanges { target: appDelegate; windowedX: windowedX; windowedY: PanelState.panelHeight;
1415− windowedWidth: windowedWidth; windowedHeight: appContainer.height - PanelState.panelHeight }
1524+ PropertyChanges { target: appDelegate; windowedX: windowedX; windowedY: panelState.panelHeight;
1525+ windowedWidth: windowedWidth; windowedHeight: appContainer.height - panelState.panelHeight }
14161526 },
14171527 State {
14181528 name: "minimized"; when: appDelegate.minimized
@@ -1511,7 +1621,7 @@ FocusScope {
15111621 ]
15121622
15131623 Binding {
1514− target: PanelState
1624+ target: panelState
15151625 property: "decorationsAlwaysVisible"
15161626 value: appDelegate && appDelegate.maximized && touchControls.overlayShown
15171627 }
@@ -1754,6 +1864,7 @@ FocusScope {
17541864 leftMargin: root.leftMargin
17551865 appContainerWidth: appContainer.width
17561866 appContainerHeight: appContainer.height
1867+ panelState: root.panelState
17571868 }
17581869
17591870 EdgeBarrier {
@@ -1780,83 +1891,6 @@ FocusScope {
17801891 }
17811892 }
17821893
1783− MouseArea {
1784− id: hoverMouseArea
1785− objectName: "hoverMouseArea"
1786− anchors.fill: appContainer
1787− propagateComposedEvents: true
1788− hoverEnabled: true
1789− enabled: false
1790− visible: enabled
1791−
1792− property int scrollAreaWidth: width / 3
1793− property bool progressiveScrollingEnabled: false
1794−
1795− onMouseXChanged: {
1796− mouse.accepted = false
1797−
1798− if (hoverMouseArea.pressed) {
1799− return;
1800− }
1801−
1802− // Find the hovered item and mark it active
1803− for (var i = appRepeater.count - 1; i >= 0; i--) {
1804− var appDelegate = appRepeater.itemAt(i);
1805− var mapped = mapToItem(appDelegate, hoverMouseArea.mouseX, hoverMouseArea.mouseY)
1806− var itemUnder = appDelegate.childAt(mapped.x, mapped.y);
1807− if (itemUnder && (itemUnder.objectName === "dragArea" || itemUnder.objectName === "windowInfoItem" || itemUnder.objectName == "closeMouseArea")) {
1808− spreadItem.highlightedIndex = i;
1809− break;
1810− }
1811− }
1812−
1813− if (floatingFlickable.contentWidth > floatingFlickable.width) {
1814− var margins = floatingFlickable.width * 0.05;
1815−
1816− if (!progressiveScrollingEnabled && mouseX < floatingFlickable.width - scrollAreaWidth) {
1817− progressiveScrollingEnabled = true
1818− }
1819−
1820− // do we need to scroll?
1821− if (mouseX < scrollAreaWidth + margins) {
1822− var progress = Math.min(1, (scrollAreaWidth + margins - mouseX) / (scrollAreaWidth - margins));
1823− var contentX = (1 - progress) * (floatingFlickable.contentWidth - floatingFlickable.width)
1824− floatingFlickable.contentX = Math.max(0, Math.min(floatingFlickable.contentX, contentX))
1825− }
1826− if (mouseX > floatingFlickable.width - scrollAreaWidth && progressiveScrollingEnabled) {
1827− var progress = Math.min(1, (mouseX - (floatingFlickable.width - scrollAreaWidth)) / (scrollAreaWidth - margins))
1828− var contentX = progress * (floatingFlickable.contentWidth - floatingFlickable.width)
1829− floatingFlickable.contentX = Math.min(floatingFlickable.contentWidth - floatingFlickable.width, Math.max(floatingFlickable.contentX, contentX))
1830− }
1831− }
1832− }
1833−
1834− onPressed: mouse.accepted = false
1835− }
1836−
1837− FloatingFlickable {
1838− id: floatingFlickable
1839− objectName: "spreadFlickable"
1840− anchors.fill: appContainer
1841− enabled: false
1842− contentWidth: spreadItem.spreadTotalWidth
1843−
1844− function snap(toIndex) {
1845− var delegate = appRepeater.itemAt(toIndex)
1846− var targetContentX = floatingFlickable.contentWidth / spreadItem.totalItemCount * toIndex;
1847− if (targetContentX - floatingFlickable.contentX > spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) {
1848− var offset = (spreadItem.rightStackXPos - (spreadItem.spreadItemWidth / 2)) - (targetContentX - floatingFlickable.contentX)
1849− snapAnimation.to = floatingFlickable.contentX - offset;
1850− snapAnimation.start();
1851− } else if (targetContentX - floatingFlickable.contentX < spreadItem.leftStackXPos + units.gu(1)) {
1852− var offset = (spreadItem.leftStackXPos + units.gu(1)) - (targetContentX - floatingFlickable.contentX);
1853− snapAnimation.to = floatingFlickable.contentX - offset;
1854− snapAnimation.start();
1855− }
1856− }
1857− UbuntuNumberAnimation {id: snapAnimation; target: floatingFlickable; property: "contentX"}
1858− }
1859−
18601894 PropertyAnimation {
18611895 id: shortRightEdgeSwipeAnimation
18621896 property: "x"