@@ -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,25 @@ 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+// surface: model.window.surface
766+ onSurfaceChanged: print("surface changed", surface)
767+ opacity: surface != null ? 1 : 0
768+ Behavior on opacity { UbuntuNumberAnimation {} }
769+ visible: opacity > 0
770+
771+ Drag.active: surface != null
772+ Drag.keys: ["application"]
773+
774+ z: 1000
775+ }
776+
668777 Item {
669778 id: boundariesForWindowPlacement
670779 anchors.fill: parent
@@ -700,6 +809,9 @@ FocusScope {
700809 }
701810 z: normalZ
702811
812+ opacity: fakeDragItem.surface == model.window.surface && fakeDragItem.Drag.active ? 0 : 1
813+ Behavior on opacity { UbuntuNumberAnimation {} }
814+
703815 // Normally we want x/y where the surface thinks it is. Width/height of our delegate will
704816 // match what the actual surface size is.
705817 // Don't write to those, they will be set by states
@@ -760,7 +872,7 @@ FocusScope {
760872 target: appDelegate
761873 property: "y"
762874 value: appDelegate.requestedY -
763− Math.min(appDelegate.requestedY - PanelState.panelHeight,
875+ Math.min(appDelegate.requestedY - panelState.panelHeight,
764876 Math.max(0, priv.virtualKeyboardHeight - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
765877 when: root.oskEnabled && appDelegate.focus && (appDelegate.state == "normal" || appDelegate.state == "restored")
766878 && root.inputMethodRect.height > 0
@@ -1136,7 +1248,7 @@ FocusScope {
11361248 progress: 0
11371249 targetHeight: spreadItem.stackHeight
11381250 targetX: spreadMaths.targetX
1139− startY: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1251+ startY: appDelegate.fullscreen ? 0 : panelState.panelHeight
11401252 targetY: spreadMaths.targetY
11411253 targetAngle: spreadMaths.targetAngle
11421254 targetScale: spreadMaths.targetScale
@@ -1255,9 +1367,9 @@ FocusScope {
12551367 PropertyChanges {
12561368 target: appDelegate
12571369 x: stageMaths.itemX
1258− y: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1370+ y: appDelegate.fullscreen ? 0 : panelState.panelHeight
12591371 requestedWidth: appContainer.width
1260− requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - PanelState.panelHeight
1372+ requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - panelState.panelHeight
12611373 visuallyMaximized: true
12621374 visible: appDelegate.x < root.width
12631375 }
@@ -1283,10 +1395,10 @@ FocusScope {
12831395 PropertyChanges {
12841396 target: appDelegate
12851397 x: stageMaths.itemX
1286− y: appDelegate.fullscreen ? 0 : PanelState.panelHeight
1398+ y: appDelegate.fullscreen ? 0 : panelState.panelHeight
12871399 z: stageMaths.itemZ
12881400 requestedWidth: stageMaths.itemWidth
1289− requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - PanelState.panelHeight
1401+ requestedHeight: appDelegate.fullscreen ? appContainer.height : appContainer.height - panelState.panelHeight
12901402 visuallyMaximized: true
12911403 visible: appDelegate.x < root.width
12921404 }
@@ -1351,9 +1463,9 @@ FocusScope {
13511463 PropertyChanges {
13521464 target: appDelegate
13531465 windowedX: root.leftMargin
1354− windowedY: PanelState.panelHeight
1466+ windowedY: panelState.panelHeight
13551467 windowedWidth: (appContainer.width - root.leftMargin)/2
1356− windowedHeight: appContainer.height - PanelState.panelHeight
1468+ windowedHeight: appContainer.height - panelState.panelHeight
13571469 }
13581470 },
13591471 State {
@@ -1370,9 +1482,9 @@ FocusScope {
13701482 PropertyChanges {
13711483 target: appDelegate
13721484 windowedX: root.leftMargin
1373− windowedY: PanelState.panelHeight
1485+ windowedY: panelState.panelHeight
13741486 windowedWidth: (appContainer.width - root.leftMargin)/2
1375− windowedHeight: (appContainer.height - PanelState.panelHeight)/2
1487+ windowedHeight: (appContainer.height - panelState.panelHeight)/2
13761488 }
13771489 },
13781490 State {
@@ -1389,7 +1501,7 @@ FocusScope {
13891501 PropertyChanges {
13901502 target: appDelegate
13911503 windowedX: root.leftMargin
1392− windowedY: (appContainer.height + PanelState.panelHeight)/2
1504+ windowedY: (appContainer.height + panelState.panelHeight)/2
13931505 windowedWidth: (appContainer.width - root.leftMargin)/2
13941506 windowedHeight: appContainer.height/2
13951507 }
@@ -1411,8 +1523,8 @@ FocusScope {
14111523 State {
14121524 name: "maximizedVertically"; when: appDelegate.maximizedVertically && !appDelegate.minimized
14131525 extend: "normal"
1414− PropertyChanges { target: appDelegate; windowedX: windowedX; windowedY: PanelState.panelHeight;
1415− windowedWidth: windowedWidth; windowedHeight: appContainer.height - PanelState.panelHeight }
1526+ PropertyChanges { target: appDelegate; windowedX: windowedX; windowedY: panelState.panelHeight;
1527+ windowedWidth: windowedWidth; windowedHeight: appContainer.height - panelState.panelHeight }
14161528 },
14171529 State {
14181530 name: "minimized"; when: appDelegate.minimized
@@ -1511,7 +1623,7 @@ FocusScope {
15111623 ]
15121624
15131625 Binding {
1514− target: PanelState
1626+ target: panelState
15151627 property: "decorationsAlwaysVisible"
15161628 value: appDelegate && appDelegate.maximized && touchControls.overlayShown
15171629 }
@@ -1754,6 +1866,7 @@ FocusScope {
17541866 leftMargin: root.leftMargin
17551867 appContainerWidth: appContainer.width
17561868 appContainerHeight: appContainer.height
1869+ panelState: root.panelState
17571870 }
17581871
17591872 EdgeBarrier {
@@ -1780,83 +1893,6 @@ FocusScope {
17801893 }
17811894 }
17821895
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−
18601896 PropertyAnimation {
18611897 id: shortRightEdgeSwipeAnimation
18621898 property: "x"