@@ -172,21 +172,23 @@ AbstractStage {
172172 property string sideStageAppId: ""
173173
174174 function updateMainAndSideStageIndexes() {
175+ print("updating stage indexes, sideStage shown:", sideStage.shown)
175176 var choseMainStage = false;
176177 var choseSideStage = false;
177178
178179 if (!root.topLevelSurfaceList)
179180 return;
180181
181− for (var i = 0; i < topLevelSurfaceRepeater.count && (!choseMainStage || !choseSideStage); ++i) {
182− var appDelegate = topLevelSurfaceRepeater.itemAt(i);
183− if (sideStage.shown && spreadDelegate.stage == ApplicationInfoInterface.SideStage
182+ for (var i = 0; i < appRepeater.count && (!choseMainStage || !choseSideStage); ++i) {
183+ var appDelegate = appRepeater.itemAt(i);
184+ print("have app on stage", appDelegate.applicationId, appDelegate.stage)
185+ if (sideStage.shown && appDelegate.stage == ApplicationInfoInterface.SideStage
184186 && !choseSideStage) {
185187 priv.sideStageDelegate = appDelegate
186188 priv.sideStageItemId = root.topLevelSurfaceList.idAt(i);
187189 priv.sideStageAppId = root.topLevelSurfaceList.applicationAt(i).appId;
188190 choseSideStage = true;
189− } else if (!choseMainStage && spreadDelegate.stage == ApplicationInfoInterface.MainStage) {
191+ } else if (!choseMainStage && appDelegate.stage == ApplicationInfoInterface.MainStage) {
190192 priv.mainStageDelegate = appDelegate;
191193 priv.mainStageItemId = root.topLevelSurfaceList.idAt(i);
192194 priv.mainStageAppId = root.topLevelSurfaceList.applicationAt(i).appId;
@@ -203,6 +205,8 @@ AbstractStage {
203205 priv.sideStageItemId = 0;
204206 priv.sideStageAppId = "";
205207 }
208+
209+ print("*** updated! MainStage:", priv.mainStageAppId, "SideStage:", priv.sideStageAppId)
206210 }
207211 }
208212
@@ -297,6 +301,7 @@ AbstractStage {
297301 },
298302 State {
299303 name: "stagedWithSideStage"; when: root.mode === "stagedWithSideStage"
304+ PropertyChanges { target: triGestureArea; enabled: true }
300305 },
301306 State {
302307 name: "windowed"; when: root.mode === "windowed"
@@ -304,6 +309,7 @@ AbstractStage {
304309 ]
305310 onStateChanged: print("spread going to state:", state)
306311
312+
307313 FocusScope {
308314 id: appContainer
309315 objectName: "appContainer"
@@ -318,6 +324,65 @@ AbstractStage {
318324 fillMode: Image.PreserveAspectCrop
319325 }
320326
327+ Connections {
328+ target: root.topLevelSurfaceList
329+ onListChanged: priv.updateMainAndSideStageIndexes()
330+ }
331+
332+
333+ DropArea {
334+ objectName: "MainStageDropArea"
335+ anchors {
336+ left: parent.left
337+ top: parent.top
338+ bottom: parent.bottom
339+ }
340+ width: appContainer.width - sideStage.width
341+ enabled: sideStage.enabled
342+
343+ onDropped: {
344+ print("dropped on main stage drop area")
345+ drop.source.appDelegate.saveStage(ApplicationInfoInterface.MainStage);
346+ drop.source.appDelegate.focus = true;
347+ }
348+ keys: "SideStage"
349+ }
350+
351+ SideStage {
352+ id: sideStage
353+ shown: false
354+ height: appContainer.height
355+ x: appContainer.width - width
356+
357+ DropArea {
358+ id: sideStageDropArea
359+ objectName: "SideStageDropArea"
360+ anchors.fill: parent
361+
362+ property bool dropAllowed: true
363+
364+ onEntered: {
365+ dropAllowed = drag.keys != "Disabled";
366+ }
367+ onExited: {
368+ dropAllowed = true;
369+ }
370+ onDropped: {
371+ if (drop.keys == "MainStage") {
372+ drop.source.appDelegate.saveStage(ApplicationInfoInterface.SideStage);
373+ drop.source.appDelegate.focus = true;
374+ }
375+ }
376+ drag {
377+ onSourceChanged: {
378+ if (!sideStageDropArea.drag.source) {
379+ dropAllowed = true;
380+ }
381+ }
382+ }
383+ }
384+ }
385+
321386 TopLevelSurfaceRepeater {
322387 id: appRepeater
323388 model: topLevelSurfaceList
@@ -404,6 +469,10 @@ AbstractStage {
404469 property bool visuallyMinimized: false
405470
406471 property int stage: ApplicationInfoInterface.MainStage
472+ function saveStage(stage) {
473+ appDelegate.stage = stage;
474+ WindowStateStorage.saveStage(application.appId, newStage);
475+ }
407476
408477 readonly property var surface: model.surface
409478 readonly property alias resizeArea: resizeArea
@@ -723,19 +792,13 @@ AbstractStage {
723792 requestedWidth: appContainer.width;
724793 requestedHeight: appContainer.height;
725794 }
726− PropertyChanges {
727− target: decoratedWindow
728− hasDecoration: false
729− }
795+ PropertyChanges { target: decoratedWindow; hasDecoration: false }
730796 },
731797 State {
732798 name: "normal";
733799 when: appDelegate.windowState == WindowStateStorage.WindowStateNormal
734− PropertyChanges {
735− target: appDelegate;
736− visuallyMinimized: false;
737− visuallyMaximized: false;
738− }
800+ PropertyChanges { target: appDelegate; visuallyMinimized: false; visuallyMaximized: false; }
801+ PropertyChanges { target: touchControls; enabled: true }
739802 },
740803 State {
741804 name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized
@@ -842,8 +905,12 @@ AbstractStage {
842905 to: "staged"
843906 UbuntuNumberAnimation { target: appDelegate; properties: "x,y"; duration: priv.animationDuration }
844907 UbuntuNumberAnimation { target: appDelegate; properties: "requestedWidth,requestedHeight"; duration: priv.animationDuration }
908+ },
909+ Transition {
910+ to: "stagedWithSideStage"
911+ UbuntuNumberAnimation { target: appDelegate; properties: "x,y"; duration: priv.animationDuration }
912+ UbuntuNumberAnimation { target: appDelegate; properties: "requestedWidth,requestedHeight"; duration: priv.animationDuration }
845913 }
846−
847914 ]
848915
849916// Binding {
@@ -966,6 +1033,7 @@ AbstractStage {
9661033 id: touchControls
9671034 anchors.fill: appDelegate
9681035 target: appDelegate
1036+ enabled: false
9691037 }
9701038
9711039 WindowedFullscreenPolicy {
@@ -1112,16 +1180,75 @@ AbstractStage {
11121180 }
11131181 }
11141182
1115−// DesktopSpread {
1116−// id: spread
1117−// objectName: "spread"
1118−// anchors.fill: appContainer
1119−// workspace: appContainer
1120−// focus: state == "altTab"
1121−// altTabPressed: root.altTabPressed
1122−
1123−// onPlayFocusAnimation: {
1124−// appRepeater.itemAt(index).playFocusAnimation();
1125−// }
1126−// }
1183+ TabletSideStageTouchGesture {
1184+ id: triGestureArea
1185+ anchors.fill: parent
1186+ enabled: false
1187+ property Item appDelegate
1188+
1189+ dragComponent: dragComponent
1190+ dragComponentProperties: { "appDelegate": appDelegate }
1191+
1192+ onPressed: {
1193+ print("********* triGestureArea pressed!")
1194+ function matchDelegate(obj) { return String(obj.objectName).indexOf("appDelegate") >= 0; }
1195+
1196+ var delegateAtCenter = Functions.itemAt(appContainer, x, y, matchDelegate);
1197+ print("dragging delegate", delegateAtCenter)
1198+ if (!delegateAtCenter) return;
1199+
1200+ appDelegate = delegateAtCenter;
1201+ }
1202+
1203+ onClicked: {
1204+ if (sideStage.shown) {
1205+ sideStage.hide();
1206+ } else {
1207+ sideStage.show();
1208+ }
1209+ }
1210+
1211+ onDragStarted: {
1212+ // If we're dragging to the sidestage.
1213+ if (!sideStage.shown) {
1214+ sideStage.show();
1215+ }
1216+ }
1217+
1218+ Component {
1219+ id: dragComponent
1220+ SurfaceContainer {
1221+ property Item appDelegate
1222+
1223+ surface: appDelegate ? appDelegate.surface : null
1224+
1225+ consumesInput: false
1226+ interactive: false
1227+// resizeSurface: false
1228+ focus: false
1229+ requestedWidth: appDelegate.requestedWidth
1230+ requestedHeight: appDelegate.requestedHeight
1231+
1232+ width: units.gu(40)
1233+ height: units.gu(40)
1234+
1235+ Drag.hotSpot.x: width/2
1236+ Drag.hotSpot.y: height/2
1237+ // only accept opposite stage.
1238+ Drag.keys: {
1239+ if (!surface) return "Disabled";
1240+ if (appDelegate.isDash) return "Disabled";
1241+
1242+ if (appDelegate.stage === ApplicationInfo.MainStage) {
1243+ if (appDelegate.application.supportedOrientations
1244+ & (Qt.PortraitOrientation|Qt.InvertedPortraitOrientation)) {
1245+ return "MainStage";
1246+ }
1247+ return "Disabled";
1248+ }
1249+ return "SideStage";
1250+ }
1251+ }
1252+ }
1253+ }
11271254}