on xenial help sign in
rework/simplify how stages are revealed in Shell.qml.
8df8725Michael Zanetti
qml/Shell.qml+80−83
@@ -56,11 +56,13 @@ FocusScope {
56 if (ApplicationManager.findApplication(appId)) {
56 if (ApplicationManager.findApplication(appId)) {
57 print("Shell.qml: activating app", appId);
57 print("Shell.qml: activating app", appId);
58 ApplicationManager.activateApplication(appId);
58 ApplicationManager.activateApplication(appId);
59+ stages.show();
59 } else {
60 } else {
60 print("starting app", appId);
61 print("starting app", appId);
61
62
62 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
63 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
63 ApplicationManager.startApplication(appId, execFlags);
64 ApplicationManager.startApplication(appId, execFlags);
65+ stages.show();
64 }
66 }
65 }
67 }
66
68
@@ -122,7 +124,7 @@ FocusScope {
122 readonly property bool applicationRunning: ApplicationManager.focusedApplicationId.length > 0
124 readonly property bool applicationRunning: ApplicationManager.focusedApplicationId.length > 0
123
125
124 // Whether the user should see the topmost application surface (if there's one at all).
126 // Whether the user should see the topmost application surface (if there's one at all).
125− readonly property bool applicationSurfaceShouldBeSeen: applicationRunning && !stages.painting
127+ readonly property bool applicationSurfaceShouldBeSeen: stages.shown && !stages.painting
126
128
127 // NB! Application surfaces are stacked behind the shell one. So they can only be seen by the user
129 // NB! Application surfaces are stacked behind the shell one. So they can only be seen by the user
128 // through the translucent parts of the shell surface.
130 // through the translucent parts of the shell surface.
@@ -163,115 +165,111 @@ FocusScope {
163 if (greeter.shown) {
165 if (greeter.shown) {
164 return greeter.showProgress;
166 return greeter.showProgress;
165 } else {
167 } else {
166− return stagesOuterContainer.showProgress;
168+ return stages.showProgress;
167 }
169 }
168 }
170 }
169
171
170− // FIXME: only necessary because stagesOuterContainer.showProgress and
172+ // FIXME: only necessary because stages.showProgress and
171 // greeterRevealer.animatedProgress are not animated
173 // greeterRevealer.animatedProgress are not animated
172 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
174 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
173 }
175 }
174 }
176 }
175
177
176− Item {
178+ EdgeDragArea {
177− id: stagesOuterContainer
179+ id: stagesDragHandle
180+ direction: Direction.LeftWards
181+
182+ anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
183+ width: shell.edgeSize
184+
185+ property real progress: stages.width
186+
187+ onTouchXChanged: {
188+ if (status == DirectionalDragArea.Recognized) {
189+ if (ApplicationManager.count == 0) {
190+ progress = Math.max(stages.width + touchX * 2, stages.width * .7)
191+ } else {
192+ progress = stages.width + touchX
193+ }
194+ }
195+ }
178
196
197+ onDraggingChanged: {
198+ if (!dragging) {
199+ if (ApplicationManager.count > 0 && progress < stages.width - units.gu(10)) {
200+ stages.show()
201+ }
202+ stagesDragHandle.progress = stages.width;
203+ }
204+ }
205+ }
206+
207+ Item {
208+ id: stages
209+ objectName: "stages"
179 width: parent.width
210 width: parent.width
180 height: parent.height
211 height: parent.height
181− x: launcher.progress
182− Behavior on x {SmoothedAnimation{velocity: 600}}
183
212
184− property real showProgress: MathUtils.clamp(1 - (x + stages.x) / shell.width, 0, 1)
213+ x: shown ? launcher.progress : stagesDragHandle.progress
185
214
186− Showable {
215+ Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.SlowDuration } }
187− id: stages
188− objectName: "stages"
189
216
190− x: width
217+ property bool shown: false
191
218
192− property bool fullyShown: shown && x == 0 && parent.x == 0
219+ property real showProgress: MathUtils.clamp(1 - x / shell.width, 0, 1)
193− property bool fullyHidden: !shown && x == width
194
220
195− property bool painting: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.painting : false
221+ property bool fullyShown: x == 0
196− property bool fullscreen: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.fullscreen : false
222+ property bool fullyHidden: x == width
197
223
198− available: !greeter.shown
224+ property bool painting: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.painting : false
199− hides: [panel.indicators]
225+ property bool fullscreen: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.fullscreen : false
200− shown: false
201− opacity: 1.0
202− showAnimation: StandardAnimation { property: "x"; duration: 350; to: 0; easing.type: Easing.OutCubic }
203− hideAnimation: StandardAnimation { property: "x"; duration: 350; to: width; easing.type: Easing.OutCubic }
204−
205− width: parent.width
206− height: parent.height
207
226
208− property string lastFocusedAppId
227+ function show() {
209− onShownChanged: {
228+ shown = true;
210− print("stages shown", shown)
229+ panel.indicators.hide();
211− if (shown) {
212− if (!ApplicationManager.focusedApplicationId && lastFocusedAppId) {
230+ if (!ApplicationManager.focusedApplicationId && ApplicationManager.count > 0) {
213− ApplicationManager.focusApplication(lastFocusedAppId);
231+ ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
214− }
215− } else {
216− lastFocusedAppId = ApplicationManager.focusedApplicationId;
217− ApplicationManager.unfocusCurrentApplication();
218− }
219 }
232 }
233+ }
220
234
221− Connections {
235+ function hide() {
222− target: ApplicationManager
236+ shown = false;
223− onFocusedApplicationIdChanged: {
237+ ApplicationManager.unfocusCurrentApplication();
224− if (ApplicationManager.focusedApplicationId.length > 0) {
225− print("should show stages")
226− stages.show();
227− } else {
228− stages.hide();
229− }
230− }
238+ }
231
239
232− onApplicationAdded: {
240+ Connections {
241+ target: ApplicationManager
242+ onFocusedApplicationIdChanged: {
243+ if (ApplicationManager.focusedApplicationId.length > 0) {
233 stages.show();
244 stages.show();
234 }
245 }
235 }
246 }
236
247
237− Loader {
248+ onApplicationAdded: {
238− id: applicationsDisplayLoader
239− anchors.fill: parent
240−
241− source: shell.sideStageEnabled ? "Stages/StageWithSideStage.qml" : "Stages/PhoneStage.qml"
242−
243− Binding {
244− target: applicationsDisplayLoader.item
245− property: "moving"
246− value: !stages.fullyShown
247− }
248− Binding {
249− target: applicationsDisplayLoader.item
250− property: "shown"
251− value: stages.shown
249+ stages.show();
252− }
253− Binding {
254− target: applicationsDisplayLoader.item
255− property: "dragAreaWidth"
256− value: shell.edgeSize
257− }
258 }
250 }
251+ }
259
252
260− DragHandle {
253+ Loader {
261− id: stagesDragHandle
254+ id: applicationsDisplayLoader
262−
263− anchors.top: parent.top
264− anchors.bottom: parent.bottom
265− anchors.right: parent.left
255+ anchors.fill: parent
266
256
267− width: shell.edgeSize
257+ source: shell.sideStageEnabled ? "Stages/StageWithSideStage.qml" : "Stages/PhoneStage.qml"
268− direction: Direction.Leftwards
269− enabled: greeter.showProgress == 0 && edgeDemo.dashEnabled
270− property bool haveApps: ApplicationManager.count > 0
271
258
272− maxTotalDragDistance: haveApps ? parent.width : parent.width * 0.7
259+ Binding {
273− // Make autocompletion impossible when !haveApps
260+ target: applicationsDisplayLoader.item
274− edgeDragEvaluator.minDragDistance: haveApps ? maxTotalDragDistance * 0.1 : Number.MAX_VALUE
261+ property: "moving"
262+ value: !stages.fullyShown
263+ }
264+ Binding {
265+ target: applicationsDisplayLoader.item
266+ property: "shown"
267+ value: stages.shown
268+ }
269+ Binding {
270+ target: applicationsDisplayLoader.item
271+ property: "dragAreaWidth"
272+ value: shell.edgeSize
275 }
273 }
276 }
274 }
277 }
275 }
@@ -433,8 +431,7 @@ FocusScope {
433 }
431 }
434 property string focusedAppId: ApplicationManager.focusedApplicationId
432 property string focusedAppId: ApplicationManager.focusedApplicationId
435 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
433 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
436− fullscreenMode: stages.painting ? stages.fullscreen :
437− focusedApplication && focusedApplication.fullscreen && !greeter.shown && !lockscreen.shown
434+ fullscreenMode: focusedApplication && stages.fullscreen && !greeter.shown && !lockscreen.shown
438 searchVisible: !greeter.shown && !lockscreen.shown && dash.shown
435 searchVisible: !greeter.shown && !lockscreen.shown && dash.shown
439
436
440 InputFilterArea {
437 InputFilterArea {
qml/Stages/PhoneStage.qml+17−2
@@ -23,7 +23,13 @@ Item {
23
23
24 onMovingChanged: {
24 onMovingChanged: {
25 if (moving) {
25 if (moving) {
26+ if (ApplicationManager.focusedApplicationId) {
26− priv.requestNewScreenshot();
27+ priv.requestNewScreenshot();
28+ } else {
29+ mainScreenshotImage.anchors.leftMargin = 0;
30+ mainScreenshotImage.src = ApplicationManager.get(0).screenshot
31+ mainScreenshotImage.visible = true;
32+ }
27 } else {
33 } else {
28 mainScreenshotImage.visible = false;
34 mainScreenshotImage.visible = false;
29 }
35 }
@@ -52,12 +58,21 @@ Item {
52 mainScreenshotImage.visible = false;
58 mainScreenshotImage.visible = false;
53 priv.applicationStarting = true;
59 priv.applicationStarting = true;
54 } else {
60 } else {
55− mainScreenshotImage.src = "foobar";
61+ mainScreenshotImage.src = "";
56 priv.newFocusedAppId = appId;
62 priv.newFocusedAppId = appId;
57 priv.secondApplicationStarting = true;
63 priv.secondApplicationStarting = true;
58 priv.requestNewScreenshot();
64 priv.requestNewScreenshot();
59 }
65 }
60 }
66 }
67+
68+ onApplicationRemoved: {
69+ if (ApplicationManager.count == 0) {
70+ mainScreenshotImage.src = ""
71+ mainScreenshotImage.visible = false;
72+ } else {
73+ mainScreenshotImage.src = ApplicationManager.get(0).screenshot
74+ }
75+ }
61 }
76 }
62
77
63 QtObject {
78 QtObject {
tests/mocks/Unity/Application/ApplicationManager.cpp+2
@@ -97,6 +97,7 @@ void ApplicationManager::add(ApplicationInfo *application) {
97 beginInsertRows(QModelIndex(), m_runningApplications.size(), m_runningApplications.size());
97 beginInsertRows(QModelIndex(), m_runningApplications.size(), m_runningApplications.size());
98 m_runningApplications.append(application);
98 m_runningApplications.append(application);
99 endInsertRows();
99 endInsertRows();
100+ Q_EMIT applicationAdded(application->appId());
100 Q_EMIT countChanged();
101 Q_EMIT countChanged();
101}
102}
102
103
@@ -106,6 +107,7 @@ void ApplicationManager::remove(ApplicationInfo *application) {
106 beginRemoveRows(QModelIndex(), i, i);
107 beginRemoveRows(QModelIndex(), i, i);
107 m_runningApplications.removeAt(i);
108 m_runningApplications.removeAt(i);
108 endRemoveRows();
109 endRemoveRows();
110+ Q_EMIT applicationRemoved(application->appId());
109 Q_EMIT countChanged();
111 Q_EMIT countChanged();
110 }
112 }
111}
113}