on xenial help sign in
addressing review comments
d4c3c6dDaniel d'Andrada
qml/Stages/ApplicationWindow.qml+40−35
@@ -28,45 +28,50 @@ Item {
28 property bool interactive: true
28 property bool interactive: true
29 property QtObject application
29 property QtObject application
30
30
31+ QtObject {
32+ id: d
33+
31− // helpers so that we don't have to check for the existence of an application everywhere
34+ // helpers so that we don't have to check for the existence of an application everywhere
32− // (in order to avoid breaking qml binding due to a javascript exception)
35+ // (in order to avoid breaking qml binding due to a javascript exception)
33− readonly property string name: application ? application.name : ""
36+ readonly property string name: root.application ? root.application.name : ""
34− readonly property url icon: application ? application.icon : ""
37+ readonly property url icon: root.application ? root.application.icon : ""
35− readonly property Item surface: application ? application.surface : null
38+ readonly property Item surface: root.application ? root.application.surface : null
36− readonly property int applicationState: application ? application.state : -1
39+ readonly property int applicationState: root.application ? root.application.state : -1
37− readonly property var promptSurfaces: application ? application.promptSurfaces : null
40+ readonly property var promptSurfaces: root.application ? root.application.promptSurfaces : null
38−
41+
39− property bool _needToTakeScreenshot:
42+ property bool needToTakeScreenshot:
40− root.surface && root._surfaceInitialized && screenshotImage.status === Image.Null
43+ d.surface && d.surfaceInitialized && screenshotImage.status === Image.Null
41− && root.applicationState === ApplicationInfo.Stopped
44+ && d.applicationState === ApplicationInfo.Stopped
42− on_NeedToTakeScreenshotChanged: {
45+ onNeedToTakeScreenshotChanged: {
43− if (_needToTakeScreenshot) {
46+ if (needToTakeScreenshot) {
44− screenshotImage.take();
47+ screenshotImage.take();
48+ }
45 }
49 }
46− }
47
50
48− //FIXME - this is a hack to avoid the first few rendered frames as they
51+ //FIXME - this is a hack to avoid the first few rendered frames as they
49− // might show the UI accommodating due to surface resizes on startup.
52+ // might show the UI accommodating due to surface resizes on startup.
50− // Remove this when possible
53+ // Remove this when possible
51− property bool _surfaceInitialized: false
54+ property bool surfaceInitialized: false
52− onSurfaceChanged: {
55+ onSurfaceChanged: {
53− if (surface) {
56+ if (surface) {
54− _surfaceInitTimer.start();
57+ surfaceInitTimer.start();
55− } else {
58+ } else {
56− _surfaceInitialized = false;
59+ surfaceInitialized = false;
60+ }
57 }
61 }
58 }
62 }
63+
59 Timer {
64 Timer {
60− id: _surfaceInitTimer
65+ id: surfaceInitTimer
61 interval: 100
66 interval: 100
62− onTriggered: { if (root.surface) {root._surfaceInitialized = true;} }
67+ onTriggered: { if (d.surface) {d.surfaceInitialized = true;} }
63 }
68 }
64
69
65 SurfaceContainer {
70 SurfaceContainer {
66 id: surfaceContainer
71 id: surfaceContainer
67 objectName: "surfaceContainer"
72 objectName: "surfaceContainer"
68 anchors.fill: parent
73 anchors.fill: parent
69− surface: root.surface
74+ surface: d.surface
70
75
71 Binding {
76 Binding {
72 target: surface
77 target: surface
@@ -116,12 +121,12 @@ Item {
116 active: false
121 active: false
117 anchors.fill: surfaceContainer
122 anchors.fill: surfaceContainer
118 sourceComponent: Component {
123 sourceComponent: Component {
119− Splash { name: root.name; image: root.icon }
124+ Splash { name: d.name; image: d.icon }
120 }
125 }
121 }
126 }
122
127
123 Repeater {
128 Repeater {
124− model: root.promptSurfaces
129+ model: d.promptSurfaces
125
130
126 delegate: SurfaceContainer {
131 delegate: SurfaceContainer {
127 anchors {
132 anchors {
@@ -142,16 +147,16 @@ Item {
142 State {
147 State {
143 name: "splashScreen"
148 name: "splashScreen"
144 when:
149 when:
145− (!root.surface || !root._surfaceInitialized)
150+ (!d.surface || !d.surfaceInitialized)
146 &&
151 &&
147 screenshotImage.status !== Image.Ready
152 screenshotImage.status !== Image.Ready
148 },
153 },
149 State {
154 State {
150 name: "surface"
155 name: "surface"
151 when:
156 when:
152− (root.surface && root._surfaceInitialized)
157+ (d.surface && d.surfaceInitialized)
153 &&
158 &&
154− (root.applicationState !== ApplicationInfo.Stopped
159+ (d.applicationState !== ApplicationInfo.Stopped
155 || screenshotImage.status !== Image.Ready)
160 || screenshotImage.status !== Image.Ready)
156 },
161 },
157 State {
162 State {
@@ -160,8 +165,8 @@ Item {
160 screenshotImage.status === Image.Ready
165 screenshotImage.status === Image.Ready
161 &&
166 &&
162 (
167 (
163− root.applicationState === ApplicationInfo.Stopped
168+ d.applicationState === ApplicationInfo.Stopped
164− || !root.surface || !root._surfaceInitialized
169+ || !d.surface || !d.surfaceInitialized
165 )
170 )
166 }
171 }
167 ]
172 ]
@@ -214,7 +219,7 @@ Item {
214 duration: UbuntuAnimation.BriskDuration }
219 duration: UbuntuAnimation.BriskDuration }
215 PropertyAction { target: surfaceContainer
220 PropertyAction { target: surfaceContainer
216 property: "visible"; value: false }
221 property: "visible"; value: false }
217− ScriptAction { script: { if (root.surface) { root.surface.release(); } } }
222+ ScriptAction { script: { if (d.surface) { d.surface.release(); } } }
218 }
223 }
219 },
224 },
220 Transition {
225 Transition {
qml/Stages/PhoneStage.qml+4−4
@@ -111,7 +111,7 @@ Rectangle {
111 objectName: "spreadView"
111 objectName: "spreadView"
112 anchors.fill: parent
112 anchors.fill: parent
113 interactive: (spreadDragArea.status == DirectionalDragArea.Recognized || phase > 1)
113 interactive: (spreadDragArea.status == DirectionalDragArea.Recognized || phase > 1)
114− && numDelegatesBeingDragged === 0
114+ && draggedDelegateCount === 0
115 contentWidth: spreadRow.width - shift
115 contentWidth: spreadRow.width - shift
116 contentX: -shift
116 contentX: -shift
117
117
@@ -149,7 +149,7 @@ Rectangle {
149 property int phase: 0
149 property int phase: 0
150
150
151 property int selectedIndex: -1
151 property int selectedIndex: -1
152− property int numDelegatesBeingDragged: 0
152+ property int draggedDelegateCount: 0
153 property int closingIndex: -1
153 property int closingIndex: -1
154
154
155 property bool focusChanging: false
155 property bool focusChanging: false
@@ -379,9 +379,9 @@ Rectangle {
379
379
380 onDraggedChanged: {
380 onDraggedChanged: {
381 if (dragged) {
381 if (dragged) {
382− spreadView.numDelegatesBeingDragged++;
382+ spreadView.draggedDelegateCount++;
383 } else {
383 } else {
384− spreadView.numDelegatesBeingDragged--;
384+ spreadView.draggedDelegateCount--;
385 }
385 }
386 }
386 }
387
387
qml/Stages/SpreadDelegate.qml+1−2
@@ -40,7 +40,6 @@ Item {
40 Item {
40 Item {
41 objectName: "appWindowWithShadow"
41 objectName: "appWindowWithShadow"
42
42
43− x: 0
44 y: dragArea.distance
43 y: dragArea.distance
45 width: parent.width
44 width: parent.width
46 height: parent.height
45 height: parent.height
@@ -55,7 +54,7 @@ Item {
55 }
54 }
56 source: "graphics/dropshadow.png"
55 source: "graphics/dropshadow.png"
57 border { left: 50; right: 50; top: 50; bottom: 50 }
56 border { left: 50; right: 50; top: 50; bottom: 50 }
58− opacity: root.dropShadow ? 1 : 0
57+ opacity: root.dropShadow ? .4 : 0
59 Behavior on opacity { UbuntuNumberAnimation {} }
58 Behavior on opacity { UbuntuNumberAnimation {} }
60 }
59 }
61
60
qml/Stages/TabletStage.qml+12−3
@@ -145,7 +145,8 @@ Rectangle {
145 Flickable {
145 Flickable {
146 id: spreadView
146 id: spreadView
147 anchors.fill: parent
147 anchors.fill: parent
148− interactive: (spreadDragArea.status == DirectionalDragArea.Recognized || phase > 1) && draggedIndex == -1
148+ interactive: (spreadDragArea.status == DirectionalDragArea.Recognized || phase > 1)
149+ && draggedDelegateCount === 0
149 contentWidth: spreadRow.width - shift
150 contentWidth: spreadRow.width - shift
150 contentX: -shift
151 contentX: -shift
151
152
@@ -189,7 +190,7 @@ Rectangle {
189 readonly property real snapPosition: 0.75
190 readonly property real snapPosition: 0.75
190
191
191 property int selectedIndex: -1
192 property int selectedIndex: -1
192− property int draggedIndex: -1
193+ property int draggedDelegateCount: 0
193 property int closingIndex: -1
194 property int closingIndex: -1
194
195
195 property bool sideStageDragging: sideStageDragHandle.dragging
196 property bool sideStageDragging: sideStageDragHandle.dragging
@@ -475,6 +476,7 @@ Rectangle {
475 swipeToCloseEnabled: spreadView.interactive
476 swipeToCloseEnabled: spreadView.interactive
476 maximizedAppTopMargin: root.maximizedAppTopMargin
477 maximizedAppTopMargin: root.maximizedAppTopMargin
477 dragOffset: !isDash && model.appId == priv.mainStageAppId && root.inverseProgress > 0 ? root.inverseProgress : 0
478 dragOffset: !isDash && model.appId == priv.mainStageAppId && root.inverseProgress > 0 ? root.inverseProgress : 0
479+ application: ApplicationManager.get(index)
478 closeable: !isDash
480 closeable: !isDash
479
481
480 readonly property bool isDash: model.appId == "unity8-dash"
482 readonly property bool isDash: model.appId == "unity8-dash"
@@ -534,8 +536,15 @@ Rectangle {
534 }
536 }
535 }
537 }
536
538
539+ onDraggedChanged: {
540+ if (dragged) {
541+ spreadView.draggedDelegateCount++;
542+ } else {
543+ spreadView.draggedDelegateCount--;
544+ }
545+ }
546+
537 onClosed: {
547 onClosed: {
538− spreadView.draggedIndex = -1;
539 spreadView.closingIndex = index;
548 spreadView.closingIndex = index;
540 ApplicationManager.stopApplication(ApplicationManager.get(index).appId);
549 ApplicationManager.stopApplication(ApplicationManager.get(index).appId);
541 }
550 }
qml/Stages/TransformedTabletSpreadDelegate.qml+2−2
@@ -137,7 +137,7 @@ SpreadDelegate {
137 Behavior on xTranslate {
137 Behavior on xTranslate {
138 enabled: !spreadView.active &&
138 enabled: !spreadView.active &&
139 !snapAnimation.running &&
139 !snapAnimation.running &&
140− root.closeable &&
140+ model.appId !== "unity8-dash" &&
141 !spreadView.sideStageDragging
141 !spreadView.sideStageDragging
142 UbuntuNumberAnimation {
142 UbuntuNumberAnimation {
143 duration: UbuntuAnimation.FastDuration
143 duration: UbuntuAnimation.FastDuration
@@ -172,7 +172,7 @@ SpreadDelegate {
172 }
172 }
173 newTranslate += root.dragOffset;
173 newTranslate += root.dragOffset;
174 }
174 }
175− if (!spreadView.active && !root.closeable && !root.active) {
175+ if (!spreadView.active && model.appId == "unity8-dash" && !root.active) {
176 newTranslate -= root.width;
176 newTranslate -= root.width;
177 }
177 }
178
178
tests/mocks/Unity/Application/ApplicationInfo.cpp−1
@@ -18,7 +18,6 @@
18#include "MirSurfaceItem.h"
18#include "MirSurfaceItem.h"
19#include "SurfaceManager.h"
19#include "SurfaceManager.h"
20
20
21−// unity8
22#include <paths.h>
21#include <paths.h>
23
22
24#include <QGuiApplication>
23#include <QGuiApplication>
tests/qmltests/Stages/tst_ApplicationWindow.qml+32−24
@@ -158,30 +158,32 @@ Rectangle {
158 applicationWindowLoader.active = true;
158 applicationWindowLoader.active = true;
159 }
159 }
160
160
161− function test_showSplashUntilAppFullyInit1() {
161+ function test_showSplashUntilAppFullyInit_data() {
162− var stateGroup = findInvisibleChild(applicationWindowLoader.item, "applicationWindowStateGroup");
162+ return [
163−
163+ {tag: "state=Running then create surface", swapInitOrder: false},
164− verify(stateGroup.state === "splashScreen");
165−
166− setApplicationState(appRunning);
167−
168− verify(stateGroup.state === "splashScreen");
169
164
170− surfaceCheckbox.checked = true;
165+ {tag: "create surface then state=Running", swapInitOrder: true},
171−
166+ ]
172− tryCompare(stateGroup, "state", "surface");
173 }
167 }
174
168
175− function test_showSplashUntilAppFullyInit2() {
169+ function test_showSplashUntilAppFullyInit() {
176 var stateGroup = findInvisibleChild(applicationWindowLoader.item, "applicationWindowStateGroup");
170 var stateGroup = findInvisibleChild(applicationWindowLoader.item, "applicationWindowStateGroup");
177
171
178 verify(stateGroup.state === "splashScreen");
172 verify(stateGroup.state === "splashScreen");
179
173
174+ if (data.swapInitOrder) {
180− surfaceCheckbox.checked = true;
175+ surfaceCheckbox.checked = true;
176+ } else {
177+ setApplicationState(appRunning);
178+ }
181
179
182 verify(stateGroup.state === "splashScreen");
180 verify(stateGroup.state === "splashScreen");
183
181
182+ if (data.swapInitOrder) {
184− setApplicationState(appRunning);
183+ setApplicationState(appRunning);
184+ } else {
185+ surfaceCheckbox.checked = true;
186+ }
185
187
186 tryCompare(stateGroup, "state", "surface");
188 tryCompare(stateGroup, "state", "surface");
187 }
189 }
@@ -191,14 +193,16 @@ Rectangle {
191
193
192 surfaceCheckbox.checked = true;
194 surfaceCheckbox.checked = true;
193 setApplicationState(appRunning);
195 setApplicationState(appRunning);
196+
194 tryCompare(stateGroup, "state", "surface");
197 tryCompare(stateGroup, "state", "surface");
195
198
199+ // wait until any transition animation has finished
200+ tryCompare(stateGroup, "transitioning", false, 2000);
201+
196 setApplicationState(appSuspended);
202 setApplicationState(appSuspended);
197
203
198− for (var i = 0; i < 10; ++i) {
199− wait(50);
200− verify(stateGroup.state === "surface");
204+ verify(stateGroup.state === "surface");
201− }
205+ verify(stateGroup.transitioning === false);
202 }
206 }
203
207
204 function test_killedAppShowsScreenshot() {
208 function test_killedAppShowsScreenshot() {
@@ -227,6 +231,7 @@ Rectangle {
227 surfaceCheckbox.checked = true;
231 surfaceCheckbox.checked = true;
228 setApplicationState(appRunning);
232 setApplicationState(appRunning);
229 tryCompare(stateGroup, "state", "surface");
233 tryCompare(stateGroup, "state", "surface");
234+ tryCompare(stateGroup, "transitioning", false, 2000);
230
235
231 setApplicationState(appSuspended);
236 setApplicationState(appSuspended);
232
237
@@ -234,19 +239,20 @@ Rectangle {
234 setApplicationState(appStopped);
239 setApplicationState(appStopped);
235
240
236 tryCompare(stateGroup, "state", "screenshot");
241 tryCompare(stateGroup, "state", "screenshot");
242+ tryCompare(stateGroup, "transitioning", false, 2000);
237 tryCompare(fakeApplication, "surface", null);
243 tryCompare(fakeApplication, "surface", null);
238
244
239 // and restart it
245 // and restart it
240 setApplicationState(appStarting);
246 setApplicationState(appStarting);
241
247
242− wait(50);
248+ verify(stateGroup.transitioning === false);
249+ verify(stateGroup.state === "screenshot");
243 verify(fakeApplication.surface === null);
250 verify(fakeApplication.surface === null);
244− tryCompare(stateGroup, "state", "screenshot");
245
251
246 setApplicationState(appRunning);
252 setApplicationState(appRunning);
247
253
248− wait(50);
254+ verify(stateGroup.transitioning === false);
249− tryCompare(stateGroup, "state", "screenshot");
255+ verify(stateGroup.state === "screenshot");
250
256
251 surfaceCheckbox.checked = true;
257 surfaceCheckbox.checked = true;
252
258
@@ -260,6 +266,7 @@ Rectangle {
260 surfaceCheckbox.checked = true;
266 surfaceCheckbox.checked = true;
261 setApplicationState(appRunning);
267 setApplicationState(appRunning);
262 tryCompare(stateGroup, "state", "surface");
268 tryCompare(stateGroup, "state", "surface");
269+ tryCompare(stateGroup, "transitioning", false, 2000);
263
270
264 // oh, it crashed...
271 // oh, it crashed...
265 setApplicationState(appStopped);
272 setApplicationState(appStopped);
@@ -274,17 +281,18 @@ Rectangle {
274 surfaceCheckbox.checked = true;
281 surfaceCheckbox.checked = true;
275 setApplicationState(appRunning);
282 setApplicationState(appRunning);
276 tryCompare(stateGroup, "state", "surface");
283 tryCompare(stateGroup, "state", "surface");
284+ tryCompare(stateGroup, "transitioning", false, 2000);
277 verify(fakeApplication.surface !== null);
285 verify(fakeApplication.surface !== null);
278
286
279 applicationWindowLoader.item.visible = false;
287 applicationWindowLoader.item.visible = false;
280
288
281− wait(50);
289+ verify(stateGroup.transitioning === false);
282 verify(stateGroup.state === "surface");
290 verify(stateGroup.state === "surface");
283 verify(fakeApplication.surface !== null);
291 verify(fakeApplication.surface !== null);
284
292
285 applicationWindowLoader.item.visible = true;
293 applicationWindowLoader.item.visible = true;
286
294
287− wait(50);
295+ verify(stateGroup.transitioning === false);
288 verify(stateGroup.state === "surface");
296 verify(stateGroup.state === "surface");
289 verify(fakeApplication.surface !== null);
297 verify(fakeApplication.surface !== null);
290 }
298 }