Merge lp:~dandrader/unity8/detachPromptSurfaces into lp:unity8
- detachPromptSurfaces
- Merge into trunk
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~dandrader/unity8/detachPromptSurfaces | ||||
Merge into: | lp:unity8 | ||||
Diff against target: |
975 lines (+241/-376) 14 files modified
debian/control (+3/-3) qml/Stages/ApplicationWindow.qml (+31/-1) qml/Stages/SurfaceContainer.qml (+4/-63) tests/mocks/Unity/Application/ApplicationInfo.cpp (+8/-0) tests/mocks/Unity/Application/ApplicationInfo.h (+2/-0) tests/mocks/Unity/Application/MirSurface.cpp (+1/-21) tests/mocks/Unity/Application/MirSurface.h (+0/-5) tests/mocks/Unity/Application/MirSurfaceListModel.cpp (+28/-0) tests/mocks/Unity/Application/MirSurfaceListModel.h (+5/-0) tests/plugins/Unity/Launcher/launchermodeltest.cpp (+1/-0) tests/qmltests/Stages/ApplicationCheckBox.qml (+33/-3) tests/qmltests/Stages/RecursingChildSessionControl.qml (+0/-94) tests/qmltests/Stages/tst_ApplicationWindow.qml (+91/-25) tests/qmltests/Stages/tst_SurfaceContainer.qml (+34/-161) |
||||
To merge this branch: | bzr merge lp:~dandrader/unity8/detachPromptSurfaces | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nick Dedekind (community) | Needs Fixing | ||
Unity8 CI Bot | continuous-integration | Needs Fixing | |
Review via email: mp+294959@code.launchpad.net |
This proposal has been superseded by a proposal from 2016-05-18.
Commit message
Move prompt surfaces from MirSurface to Application
prompt surfaces can show up even before an application creates its first surface
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
https:/
https:/
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Not applicable
* If you changed the UI, has there been a design review?
Not applicable
- 2397. By Daniel d'Andrada
-
Update unity-api versions
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
- 2398. By Daniel d'Andrada
-
Simplify code
- 2399. By Daniel d'Andrada
-
fix issues
- 2400. By Daniel d'Andrada
-
Disable debug messages
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2399
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2400
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Nick Dedekind (nick-dedekind) : | # |
Daniel d'Andrada (dandrader) wrote : | # |
On 18/05/2016 07:40, Nick Dedekind wrote:
>> + if (root.application && root.surface === root.applicatio
> uh. I dont actually think this is right. If we're have a multisurface app, we may end up missing the prompt because we're looking at the wrong surface. So the app may just seem like it's not starting up.
>
The surface list is ordered by focus recency. Ie, when a surface is
focused it's raise to the top of the list. So
surfaceList.first will always point to the currently (or most recently) focused surface of this application.
Please run "make tryDesktopStage" and play with multiple surface applications and prompts.
Unmerged revisions
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2016-05-04 18:09:25 +0000 |
3 | +++ debian/control 2016-05-17 20:00:40 +0000 |
4 | @@ -30,7 +30,7 @@ |
5 | libqt5xmlpatterns5-dev, |
6 | libsystemsettings-dev, |
7 | libudev-dev, |
8 | - libunity-api-dev (>= 7.111), |
9 | + libunity-api-dev (>= 7.112), |
10 | libusermetricsoutput1-dev, |
11 | # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop |
12 | libx11-dev[!armhf], |
13 | @@ -133,7 +133,7 @@ |
14 | qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845), |
15 | qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl, |
16 | ubuntu-thumbnailer-impl-0, |
17 | - unity-application-impl-15, |
18 | + unity-application-impl-16, |
19 | unity-notifications-impl-3, |
20 | unity-plugin-scopes | unity-scopes-impl, |
21 | unity-scopes-impl-12, |
22 | @@ -179,7 +179,7 @@ |
23 | Depends: ${misc:Depends}, |
24 | ${shlibs:Depends}, |
25 | Provides: unity-application-impl, |
26 | - unity-application-impl-15, |
27 | + unity-application-impl-16, |
28 | Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1) |
29 | Description: Fake environment for running Unity 8 shell |
30 | Provides fake implementations of some QML modules used by Unity 8 shell |
31 | |
32 | === modified file 'qml/Stages/ApplicationWindow.qml' |
33 | --- qml/Stages/ApplicationWindow.qml 2016-04-27 15:01:10 +0000 |
34 | +++ qml/Stages/ApplicationWindow.qml 2016-05-17 20:00:40 +0000 |
35 | @@ -120,6 +120,17 @@ |
36 | || (application.supportedOrientations & Qt.InvertedLandscapeOrientation)) |
37 | |
38 | property bool surfaceOldEnoughToBeResized: false |
39 | + |
40 | + property var focusedSurface: { |
41 | + if (promptSurfacesRepeater.count == 0) { |
42 | + return surfaceContainer; |
43 | + } else { |
44 | + return promptSurfacesRepeater.itemAt(promptSurfacesRepeater.count - 1); |
45 | + } |
46 | + } |
47 | + onFocusedSurfaceChanged: { |
48 | + focusedSurface.focus = true; |
49 | + } |
50 | } |
51 | |
52 | Binding { |
53 | @@ -183,7 +194,26 @@ |
54 | requestedWidth: root.requestedWidth |
55 | requestedHeight: root.requestedHeight |
56 | surfaceOrientationAngle: application && application.rotatesWindowContents ? root.surfaceOrientationAngle : 0 |
57 | - focus: true |
58 | + } |
59 | + |
60 | + Repeater { |
61 | + id: promptSurfacesRepeater |
62 | + objectName: "promptSurfacesRepeater" |
63 | + // show only along with the top-most application surface |
64 | + model: { |
65 | + if (root.application && root.surface === root.application.surfaceList.first) { |
66 | + return root.application.promptSurfaceList; |
67 | + } else { |
68 | + return null; |
69 | + } |
70 | + } |
71 | + delegate: SurfaceContainer { |
72 | + interactive: index == (promptSurfacesRepeater.count - 1) && root.interactive |
73 | + surface: model.surface |
74 | + width: root.width |
75 | + height: root.height |
76 | + isPromptSurface: true |
77 | + } |
78 | } |
79 | |
80 | // SurfaceContainer size drives ApplicationWindow size |
81 | |
82 | === modified file 'qml/Stages/SurfaceContainer.qml' |
83 | --- qml/Stages/SurfaceContainer.qml 2016-04-04 13:38:56 +0000 |
84 | +++ qml/Stages/SurfaceContainer.qml 2016-05-17 20:00:40 +0000 |
85 | @@ -33,7 +33,7 @@ |
86 | property bool interactive |
87 | property int surfaceOrientationAngle: 0 |
88 | property bool resizeSurface: true |
89 | - property bool inPromptSession: false |
90 | + property bool isPromptSurface: false |
91 | |
92 | onSurfaceChanged: { |
93 | // Not a binding because animations might remove the surface from the surfaceItem |
94 | @@ -56,6 +56,8 @@ |
95 | id: surfaceItem |
96 | objectName: "surfaceItem" |
97 | |
98 | + focus: true |
99 | + |
100 | fillMode: MirSurfaceItem.PadOrCrop |
101 | consumesInput: true |
102 | |
103 | @@ -122,59 +124,12 @@ |
104 | when: root.requestedHeight < 0 |
105 | } |
106 | |
107 | - Repeater { |
108 | - id: childSurfacesRepeater |
109 | - objectName: "childSurfacesRepeater" |
110 | - model: root.surface ? root.surface.promptSurfaceList : null |
111 | - |
112 | - delegate: Loader { |
113 | - objectName: "childDelegate" + index |
114 | - anchors.fill: root |
115 | - |
116 | - // Only way to do recursive qml items. |
117 | - source: Qt.resolvedUrl("SurfaceContainer.qml") |
118 | - |
119 | - z: index |
120 | - |
121 | - // Since a Loader is a FocusScope, propagate its focus to the loaded Item |
122 | - Binding { |
123 | - target: item; when: item |
124 | - property: "focus"; value: focus |
125 | - } |
126 | - |
127 | - Binding { |
128 | - target: item; when: item |
129 | - property: "interactive"; value: index == (childSurfacesRepeater.count - 1) && root.interactive |
130 | - } |
131 | - |
132 | - Binding { |
133 | - target: item; when: item |
134 | - property: "surface"; value: model.surface |
135 | - } |
136 | - |
137 | - Binding { |
138 | - target: item; when: item |
139 | - property: "width"; value: root.width |
140 | - } |
141 | - |
142 | - Binding { |
143 | - target: item; when: item |
144 | - property: "height"; value: root.height |
145 | - } |
146 | - |
147 | - Binding { |
148 | - target: item; when: item |
149 | - property: "inPromptSession"; value: true |
150 | - } |
151 | - } |
152 | - } |
153 | - |
154 | Loader { |
155 | id: animationsLoader |
156 | objectName: "animationsLoader" |
157 | active: root.surface |
158 | source: { |
159 | - if (root.inPromptSession) { |
160 | + if (root.isPromptSurface) { |
161 | return "PromptSurfaceAnimations.qml"; |
162 | } else { |
163 | // Let ApplicationWindow do the animations |
164 | @@ -194,18 +149,4 @@ |
165 | value: root |
166 | } |
167 | } |
168 | - |
169 | - QtObject { |
170 | - id: d |
171 | - property var focusedChild: { |
172 | - if (childSurfacesRepeater.count == 0) { |
173 | - return surfaceItem; |
174 | - } else { |
175 | - return childSurfacesRepeater.itemAt(childSurfacesRepeater.count - 1); |
176 | - } |
177 | - } |
178 | - onFocusedChildChanged: { |
179 | - focusedChild.focus = true; |
180 | - } |
181 | - } |
182 | } |
183 | |
184 | === modified file 'tests/mocks/Unity/Application/ApplicationInfo.cpp' |
185 | --- tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-04-27 15:01:10 +0000 |
186 | +++ tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-05-17 20:00:40 +0000 |
187 | @@ -194,6 +194,10 @@ |
188 | MirSurface *surface = static_cast<MirSurface*>(m_surfaceList.get(i)); |
189 | surface->setLive(false); |
190 | } |
191 | + for (int i = 0; i < m_promptSurfaceList.count(); ++i) { |
192 | + auto surface = static_cast<MirSurface*>(m_promptSurfaceList.get(i)); |
193 | + surface->setLive(false); |
194 | + } |
195 | } |
196 | |
197 | m_state = value; |
198 | @@ -238,6 +242,10 @@ |
199 | if (value != m_manualSurfaceCreation) { |
200 | m_manualSurfaceCreation = value; |
201 | Q_EMIT manualSurfaceCreationChanged(value); |
202 | + |
203 | + if (m_manualSurfaceCreation && m_surfaceCreationTimer.isActive()) { |
204 | + m_surfaceCreationTimer.stop(); |
205 | + } |
206 | } |
207 | } |
208 | |
209 | |
210 | === modified file 'tests/mocks/Unity/Application/ApplicationInfo.h' |
211 | --- tests/mocks/Unity/Application/ApplicationInfo.h 2016-04-27 15:01:10 +0000 |
212 | +++ tests/mocks/Unity/Application/ApplicationInfo.h 2016-05-17 20:00:40 +0000 |
213 | @@ -108,6 +108,7 @@ |
214 | Q_INVOKABLE void setShellChrome(Mir::ShellChrome shellChrome); |
215 | |
216 | MirSurfaceListInterface* surfaceList() override { return &m_surfaceList; } |
217 | + MirSurfaceListInterface* promptSurfaceList() override { return &m_promptSurfaceList; } |
218 | |
219 | void setFocused(bool value); |
220 | |
221 | @@ -148,6 +149,7 @@ |
222 | bool m_exemptFromLifecycle{false}; |
223 | QSize m_initialSurfaceSize; |
224 | MirSurfaceListModel m_surfaceList; |
225 | + MirSurfaceListModel m_promptSurfaceList; |
226 | int m_liveSurfaceCount{0}; |
227 | QTimer m_surfaceCreationTimer; |
228 | QList<MirSurface*> m_closingSurfaces; |
229 | |
230 | === modified file 'tests/mocks/Unity/Application/MirSurface.cpp' |
231 | --- tests/mocks/Unity/Application/MirSurface.cpp 2016-04-27 15:01:10 +0000 |
232 | +++ tests/mocks/Unity/Application/MirSurface.cpp 2016-05-17 20:00:40 +0000 |
233 | @@ -408,27 +408,6 @@ |
234 | } |
235 | } |
236 | |
237 | -void MirSurface::createPromptSurface() |
238 | -{ |
239 | - QStringList screenshotIds = {"gallery", "map", "facebook", "camera", "browser", "music", "twitter"}; |
240 | - int i = rand() % screenshotIds.count(); |
241 | - |
242 | - QUrl screenshotUrl = QString("qrc:///Unity/Application/screenshots/%1@12.png") |
243 | - .arg(screenshotIds[i]); |
244 | - |
245 | - auto surface = new MirSurface(QString("prompt foo"), |
246 | - Mir::NormalType, |
247 | - Mir::RestoredState, |
248 | - screenshotUrl); |
249 | - |
250 | - m_promptSurfaceList.appendSurface(surface); |
251 | -} |
252 | - |
253 | -MirSurfaceListInterface* MirSurface::promptSurfaceList() |
254 | -{ |
255 | - return &m_promptSurfaceList; |
256 | -} |
257 | - |
258 | void MirSurface::requestFocus() |
259 | { |
260 | DEBUG_MSG(""); |
261 | @@ -485,6 +464,7 @@ |
262 | |
263 | if (m_focusedSurface) { |
264 | Q_EMIT m_focusedSurface->focusedChanged(true); |
265 | + m_focusedSurface->raise(); |
266 | } |
267 | } |
268 | |
269 | |
270 | === modified file 'tests/mocks/Unity/Application/MirSurface.h' |
271 | --- tests/mocks/Unity/Application/MirSurface.h 2016-04-27 15:01:10 +0000 |
272 | +++ tests/mocks/Unity/Application/MirSurface.h 2016-05-17 20:00:40 +0000 |
273 | @@ -107,8 +107,6 @@ |
274 | |
275 | Q_INVOKABLE void close() override; |
276 | |
277 | - unity::shell::application::MirSurfaceListInterface* promptSurfaceList() override; |
278 | - |
279 | Q_INVOKABLE void raise() override; |
280 | |
281 | //// |
282 | @@ -130,8 +128,6 @@ |
283 | Q_INVOKABLE void setWidthIncrement(int); |
284 | Q_INVOKABLE void setHeightIncrement(int); |
285 | |
286 | - Q_INVOKABLE void createPromptSurface(); |
287 | - |
288 | ///// |
289 | // internal mock stuff |
290 | |
291 | @@ -199,7 +195,6 @@ |
292 | QSize m_pendingResize; |
293 | |
294 | Mir::ShellChrome m_shellChrome; |
295 | - MirSurfaceListModel m_promptSurfaceList; |
296 | |
297 | struct View { |
298 | bool visible; |
299 | |
300 | === modified file 'tests/mocks/Unity/Application/MirSurfaceListModel.cpp' |
301 | --- tests/mocks/Unity/Application/MirSurfaceListModel.cpp 2016-04-04 13:37:49 +0000 |
302 | +++ tests/mocks/Unity/Application/MirSurfaceListModel.cpp 2016-05-17 20:00:40 +0000 |
303 | @@ -67,6 +67,9 @@ |
304 | connectSurface(surface); |
305 | endInsertRows(); |
306 | Q_EMIT countChanged(); |
307 | + if (m_surfaceList.count() == 1) { |
308 | + Q_EMIT firstChanged(); |
309 | + } |
310 | } |
311 | |
312 | void MirSurfaceListModel::connectSurface(MirSurface *surface) |
313 | @@ -83,6 +86,9 @@ |
314 | m_surfaceList.removeAt(i); |
315 | endRemoveRows(); |
316 | Q_EMIT countChanged(); |
317 | + if (m_surfaceList.count() == 0 || i == 0) { |
318 | + Q_EMIT firstChanged(); |
319 | + } |
320 | } |
321 | } |
322 | |
323 | @@ -100,6 +106,10 @@ |
324 | m_surfaceList.move(from, to); |
325 | endMoveRows(); |
326 | } |
327 | + |
328 | + if ((from == 0 || to == 0) && m_surfaceList.count() > 1) { |
329 | + Q_EMIT firstChanged(); |
330 | + } |
331 | } |
332 | |
333 | MirSurfaceInterface *MirSurfaceListModel::get(int index) |
334 | @@ -119,3 +129,21 @@ |
335 | return nullptr; |
336 | } |
337 | } |
338 | + |
339 | +MirSurfaceInterface *MirSurfaceListModel::createSurface() |
340 | +{ |
341 | + QStringList screenshotIds = {"gallery", "map", "facebook", "camera", "browser", "music", "twitter"}; |
342 | + int i = rand() % screenshotIds.count(); |
343 | + |
344 | + QUrl screenshotUrl = QString("qrc:///Unity/Application/screenshots/%1@12.png") |
345 | + .arg(screenshotIds[i]); |
346 | + |
347 | + auto surface = new MirSurface(QString("prompt foo"), |
348 | + Mir::NormalType, |
349 | + Mir::RestoredState, |
350 | + screenshotUrl); |
351 | + |
352 | + appendSurface(surface); |
353 | + |
354 | + return surface; |
355 | +} |
356 | |
357 | === modified file 'tests/mocks/Unity/Application/MirSurfaceListModel.h' |
358 | --- tests/mocks/Unity/Application/MirSurfaceListModel.h 2016-04-04 13:37:49 +0000 |
359 | +++ tests/mocks/Unity/Application/MirSurfaceListModel.h 2016-05-17 20:00:40 +0000 |
360 | @@ -43,6 +43,11 @@ |
361 | |
362 | bool contains(MirSurface *surface) const { return m_surfaceList.contains(surface); } |
363 | |
364 | + //// |
365 | + // API for tests |
366 | + |
367 | + Q_INVOKABLE unity::shell::application::MirSurfaceInterface *createSurface(); |
368 | + |
369 | private: |
370 | void raise(MirSurface *surface); |
371 | void moveSurface(int from, int to); |
372 | |
373 | === modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp' |
374 | --- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2016-04-27 15:01:10 +0000 |
375 | +++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2016-05-17 20:00:40 +0000 |
376 | @@ -67,6 +67,7 @@ |
377 | QSize initialSurfaceSize() const override { return QSize(); } |
378 | void setInitialSurfaceSize(const QSize &) override {} |
379 | MirSurfaceListInterface* surfaceList() override { return nullptr; } |
380 | + MirSurfaceListInterface* promptSurfaceList() override { return nullptr; } |
381 | |
382 | // Methods used for mocking (not in the interface) |
383 | void setFocused(bool focused) { m_focused = focused; Q_EMIT focusedChanged(focused); } |
384 | |
385 | === modified file 'tests/qmltests/Stages/ApplicationCheckBox.qml' |
386 | --- tests/qmltests/Stages/ApplicationCheckBox.qml 2016-04-26 10:29:25 +0000 |
387 | +++ tests/qmltests/Stages/ApplicationCheckBox.qml 2016-05-17 20:00:40 +0000 |
388 | @@ -44,6 +44,7 @@ |
389 | d.bindGuard = false; |
390 | } |
391 | |
392 | + // Application checkbox row |
393 | RowLayout { |
394 | |
395 | QtObject { |
396 | @@ -128,17 +129,47 @@ |
397 | visible: enabled |
398 | Label { |
399 | text: "âž•" |
400 | - color: "white" |
401 | anchors.centerIn: parent |
402 | } |
403 | } |
404 | } |
405 | + |
406 | + // Prompts controls row |
407 | + RowLayout { |
408 | + anchors.left: root.left |
409 | + anchors.leftMargin: units.gu(2) |
410 | + visible: root.checked === true && d.application !== null && root.enabled |
411 | + spacing: units.gu(1) |
412 | + Label { |
413 | + property int promptCount: d.application ? d.application.promptSurfaceList.count : 0 |
414 | + id: promptsLabel |
415 | + text: promptCount + " prompts" |
416 | + } |
417 | + MouseArea { |
418 | + width: height |
419 | + height: promptsLabel.height * 0.7 |
420 | + anchors.verticalCenter: parent.verticalCenter |
421 | + onClicked: d.application.promptSurfaceList.createSurface() |
422 | + Label { text: "âž•"; anchors.centerIn: parent } |
423 | + } |
424 | + MouseArea { |
425 | + width: height |
426 | + height: promptsLabel.height * 0.7 |
427 | + anchors.verticalCenter: parent.verticalCenter |
428 | + onClicked: d.application.promptSurfaceList.get(d.application.promptSurfaceList.count - 1).close() |
429 | + enabled: d.application && d.application.promptSurfaceList.count > 0 |
430 | + Label { text: "âž–"; anchors.centerIn: parent; enabled: parent.enabled } |
431 | + } |
432 | + } |
433 | + |
434 | + // Rows of application surfaces |
435 | Repeater { |
436 | model: d.application ? d.application.surfaceList : null |
437 | RowLayout { |
438 | + anchors.left: root.left |
439 | + anchors.leftMargin: units.gu(2) |
440 | spacing: units.gu(1) |
441 | Label { |
442 | - color: "white" |
443 | text: "- " + model.surface.name |
444 | } |
445 | MouseArea { |
446 | @@ -150,7 +181,6 @@ |
447 | onClicked: model.surface.setLive(false); |
448 | Label { |
449 | text: "â›’" |
450 | - color: "white" |
451 | anchors.centerIn: parent |
452 | } |
453 | } |
454 | |
455 | === removed file 'tests/qmltests/Stages/RecursingChildSessionControl.qml' |
456 | --- tests/qmltests/Stages/RecursingChildSessionControl.qml 2016-04-04 13:37:49 +0000 |
457 | +++ tests/qmltests/Stages/RecursingChildSessionControl.qml 1970-01-01 00:00:00 +0000 |
458 | @@ -1,94 +0,0 @@ |
459 | -/* |
460 | - * Copyright 2014,2016 Canonical Ltd. |
461 | - * |
462 | - * This program is free software; you can redistribute it and/or modify |
463 | - * it under the terms of the GNU General Public License as published by |
464 | - * the Free Software Foundation; version 3. |
465 | - * |
466 | - * This program is distributed in the hope that it will be useful, |
467 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
468 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
469 | - * GNU General Public License for more details. |
470 | - * |
471 | - * You should have received a copy of the GNU General Public License |
472 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
473 | - */ |
474 | - |
475 | -import QtQuick 2.4 |
476 | -import QtQuick.Layouts 1.1 |
477 | -import Ubuntu.Components 1.3 |
478 | -import Unity.Application 0.1 |
479 | - |
480 | -ColumnLayout { |
481 | - id: root |
482 | - |
483 | - property var surface |
484 | - |
485 | - Column { |
486 | - id: column |
487 | - Layout.fillWidth: true |
488 | - visible: repeater.count |
489 | - spacing: units.gu(1) |
490 | - |
491 | - Repeater { |
492 | - id: repeater |
493 | - model: root.surface ? root.surface.promptSurfaceList : null |
494 | - delegate: Rectangle { |
495 | - border { |
496 | - color: "black" |
497 | - width: 1 |
498 | - } |
499 | - anchors { |
500 | - left: column.left |
501 | - right: column.right |
502 | - leftMargin: units.gu(1) |
503 | - rightMargin: units.gu(1) |
504 | - } |
505 | - height: loader.height |
506 | - |
507 | - Rectangle { |
508 | - anchors.fill: parent |
509 | - color: Qt.rgba(Math.random(), Math.random(), Math.random(), 0.4 ) |
510 | - } |
511 | - |
512 | - Loader { |
513 | - id: loader |
514 | - visible: status == Loader.Ready |
515 | - source: Qt.resolvedUrl("RecursingChildSessionControl.qml") |
516 | - |
517 | - anchors { |
518 | - left: parent.left |
519 | - right: parent.right |
520 | - } |
521 | - |
522 | - onLoaded: { |
523 | - item.surface = model.surface; |
524 | - } |
525 | - } |
526 | - } |
527 | - } |
528 | - } |
529 | - |
530 | - ColumnLayout { |
531 | - Layout.fillWidth: true |
532 | - spacing: units.gu(1) |
533 | - |
534 | - RowLayout { |
535 | - id: buttonLayout |
536 | - |
537 | - Button { |
538 | - enabled: root.surface |
539 | - activeFocusOnPress: false |
540 | - text: "Remove" |
541 | - onClicked: { root.surface.close(); } |
542 | - } |
543 | - |
544 | - Button { |
545 | - enabled: root.surface !== null |
546 | - activeFocusOnPress: false |
547 | - text: "Add Prompt Surface" |
548 | - onClicked: { root.surface.createPromptSurface(); } |
549 | - } |
550 | - } |
551 | - } |
552 | -} |
553 | |
554 | === modified file 'tests/qmltests/Stages/tst_ApplicationWindow.qml' |
555 | --- tests/qmltests/Stages/tst_ApplicationWindow.qml 2016-04-04 13:37:49 +0000 |
556 | +++ tests/qmltests/Stages/tst_ApplicationWindow.qml 2016-05-17 20:00:40 +0000 |
557 | @@ -33,7 +33,6 @@ |
558 | Component.onCompleted: { |
559 | root.fakeApplication = ApplicationManager.add("gallery-app"); |
560 | root.fakeApplication.manualSurfaceCreation = true; |
561 | - root.fakeApplication.setState(ApplicationInfoInterface.Starting); |
562 | applicationWindowLoader.item.application = root.fakeApplication; |
563 | } |
564 | property QtObject fakeApplication: null |
565 | @@ -78,7 +77,7 @@ |
566 | Layout.fillWidth: true |
567 | |
568 | CheckBox { |
569 | - id: surfaceCheckbox; |
570 | + id: surfaceCheckbox |
571 | checked: false; |
572 | activeFocusOnPress: false |
573 | onCheckedChanged: { |
574 | @@ -86,10 +85,8 @@ |
575 | return; |
576 | |
577 | if (checked) { |
578 | - applicationWindowLoader.item.surface = SurfaceManager.createSurface("foo", |
579 | - Mir.NormalType, Mir.MaximizedState, root.fakeApplication); |
580 | - |
581 | - root.fakeApplication.setState(ApplicationInfoInterface.Running); |
582 | + root.fakeApplication.createSurface(); |
583 | + applicationWindowLoader.item.surface = root.fakeApplication.surfaceList.get(0); |
584 | } else { |
585 | if (applicationWindowLoader.item.surface) { |
586 | applicationWindowLoader.item.surface.setLive(false); |
587 | @@ -103,22 +100,20 @@ |
588 | } |
589 | } |
590 | |
591 | - Rectangle { |
592 | - border { |
593 | - color: "black" |
594 | - width: 1 |
595 | - } |
596 | - anchors { |
597 | - left: parent.left |
598 | - right: parent.right |
599 | - } |
600 | - Layout.preferredHeight: sessionControl.height |
601 | - |
602 | - RecursingChildSessionControl { |
603 | - id: sessionControl |
604 | - anchors { left: parent.left; right: parent.right; } |
605 | - |
606 | - surface: applicationWindowLoader.item ? applicationWindowLoader.item.surface : null |
607 | + RowLayout { |
608 | + property var promptSurfaceList: root.fakeApplication ? root.fakeApplication.promptSurfaceList : null |
609 | + Button { |
610 | + enabled: parent.promptSurfaceList !== null && parent.promptSurfaceList.count > 0 |
611 | + activeFocusOnPress: false |
612 | + text: "Remove" |
613 | + onClicked: { parent.promptSurfaceList.get(parent.promptSurfaceList.count - 1).close(); } |
614 | + } |
615 | + |
616 | + Button { |
617 | + enabled: parent.promptSurfaceList !== null |
618 | + activeFocusOnPress: false |
619 | + text: "Add Prompt Surface" |
620 | + onClicked: { parent.promptSurfaceList.createSurface(); } |
621 | } |
622 | } |
623 | |
624 | @@ -244,19 +239,29 @@ |
625 | // deleted, so you end up with two instances in memory. |
626 | tryCompare(applicationWindowLoader, "itemDestroyed", true); |
627 | |
628 | - setApplicationState(appStarting); |
629 | surfaceCheckbox.checked = false; |
630 | |
631 | - ApplicationManager.stopApplication("gallery-app"); |
632 | + console.log("killApps() start"); |
633 | + killApps(); |
634 | + console.log("killApps() end"); |
635 | + |
636 | root.fakeApplication = ApplicationManager.add("gallery-app"); |
637 | root.fakeApplication.manualSurfaceCreation = true; |
638 | - root.fakeApplication.setState(ApplicationInfoInterface.Starting); |
639 | |
640 | applicationWindowLoader.active = true; |
641 | |
642 | applicationWindowLoader.item.application = root.fakeApplication; |
643 | } |
644 | |
645 | + function waitUntilSurfaceContainerStopsAnimating(container) { |
646 | + var animationsLoader = findChild(container, "animationsLoader"); |
647 | + verify(animationsLoader); |
648 | + tryCompare(animationsLoader, "status", Loader.Ready) |
649 | + |
650 | + var animation = animationsLoader.item; |
651 | + waitUntilTransitionsEnd(animation); |
652 | + } |
653 | + |
654 | function test_showSplashUntilAppFullyInit_data() { |
655 | return [ |
656 | {tag: "state=Running then create surface", swapInitOrder: false}, |
657 | @@ -432,5 +437,66 @@ |
658 | applicationWindow.interactive = true; |
659 | compare(applicationWindow.surface.activeFocus, true); |
660 | } |
661 | + |
662 | + function test_promptSurfaceDestructionReturnsFocusToPreviousSurface() { |
663 | + surfaceCheckbox.checked = true; |
664 | + var promptSurfaces = testCase.findChild(applicationWindow, "promptSurfacesRepeater"); |
665 | + var promptSurfaceList = root.fakeApplication.promptSurfaceList; |
666 | + compare(promptSurfaces.count, 0); |
667 | + |
668 | + var i; |
669 | + // 3 surfaces should cover all edge cases |
670 | + for (i = 0; i < 3; i++) { |
671 | + promptSurfaceList.createSurface(); |
672 | + compare(promptSurfaces.count, i+1); |
673 | + waitUntilSurfaceContainerStopsAnimating(promptSurfaces.itemAt(promptSurfaces.count - 1)); |
674 | + } |
675 | + |
676 | + for (i = 2; i >= 0; --i) { |
677 | + var promptSurface = promptSurfaceList.get(i); |
678 | + compare(promptSurface.activeFocus, true); |
679 | + |
680 | + promptSurface.close(); |
681 | + tryCompareFunction(function() { return promptSurfaces.count; }, i); |
682 | + |
683 | + if (i > 0) { |
684 | + // active focus should have gone to the yongest remaining sibling |
685 | + var previousPromptSurface = promptSurfaceList.get(i-1); |
686 | + tryCompare(previousPromptSurface, "activeFocus", true); |
687 | + } else { |
688 | + // active focus should have gone to the application surface |
689 | + tryCompare(applicationWindow.surface, "activeFocus", true); |
690 | + } |
691 | + } |
692 | + } |
693 | + |
694 | + function test_promptSurfaceAdjustsForParentSize() { |
695 | + var promptSurfaceList = root.fakeApplication.promptSurfaceList; |
696 | + |
697 | + promptSurfaceList.createSurface(); |
698 | + |
699 | + var promptSurfaces = testCase.findChild(applicationWindow, "promptSurfacesRepeater"); |
700 | + |
701 | + var delegate = promptSurfaces.itemAt(0); |
702 | + waitUntilSurfaceContainerStopsAnimating(delegate); |
703 | + |
704 | + var promptSurfaceContainer = findChild(delegate, "surfaceContainer"); |
705 | + |
706 | + tryCompareFunction(function() { return promptSurfaceContainer.height === applicationWindow.height; }, true); |
707 | + tryCompareFunction(function() { return promptSurfaceContainer.width === applicationWindow.width; }, true); |
708 | + tryCompareFunction(function() { return promptSurfaceContainer.x === 0; }, true); |
709 | + tryCompareFunction(function() { return promptSurfaceContainer.y === 0; }, true); |
710 | + |
711 | + applicationWindow.anchors.margins = units.gu(2); |
712 | + |
713 | + tryCompareFunction(function() { return promptSurfaceContainer.height === applicationWindow.height; }, true); |
714 | + tryCompareFunction(function() { return promptSurfaceContainer.width === applicationWindow.width; }, true); |
715 | + tryCompareFunction(function() { return promptSurfaceContainer.x === 0; }, true); |
716 | + tryCompareFunction(function() { return promptSurfaceContainer.y === 0; }, true); |
717 | + |
718 | + // clean up |
719 | + delegate.surface.close(); |
720 | + tryCompare(promptSurfaces, "count", 0); |
721 | + } |
722 | } |
723 | } |
724 | |
725 | === modified file 'tests/qmltests/Stages/tst_SurfaceContainer.qml' |
726 | --- tests/qmltests/Stages/tst_SurfaceContainer.qml 2016-04-07 13:54:29 +0000 |
727 | +++ tests/qmltests/Stages/tst_SurfaceContainer.qml 2016-05-17 20:00:40 +0000 |
728 | @@ -42,6 +42,7 @@ |
729 | anchors.fill: parent |
730 | focus: true |
731 | interactive: interactiveCheckbox.checked |
732 | + isPromptSurface: promptCheckbox.checked |
733 | Component.onDestruction: { |
734 | surfaceContainerLoader.itemDestroyed = true; |
735 | } |
736 | @@ -75,17 +76,19 @@ |
737 | anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) } |
738 | spacing: units.gu(1) |
739 | |
740 | - RowLayout { |
741 | - Layout.fillWidth: true |
742 | |
743 | - Row { |
744 | - CheckBox {id: fullscreenCheckbox; checked: true; activeFocusOnPress: false } |
745 | - Label { text: "fullscreen" } |
746 | - } |
747 | - Row { |
748 | - CheckBox {id: interactiveCheckbox; checked: true; activeFocusOnPress: false } |
749 | - Label { text: "interactive" } |
750 | - } |
751 | + Row { |
752 | + CheckBox {id: fullscreenCheckbox; checked: true; activeFocusOnPress: false } |
753 | + Label { text: "fullscreen" } |
754 | + } |
755 | + Row { |
756 | + CheckBox {id: interactiveCheckbox; checked: true; activeFocusOnPress: false } |
757 | + Label { text: "interactive" } |
758 | + } |
759 | + Row { |
760 | + CheckBox {id: promptCheckbox; checked: false; activeFocusOnPress: false |
761 | + enabled: surfaceContainerLoader.item.surface === null } |
762 | + Label { text: "isPromptSurface" } |
763 | } |
764 | |
765 | RowLayout { |
766 | @@ -102,10 +105,9 @@ |
767 | if (checked) { |
768 | var application = ApplicationManager.add("music-app"); |
769 | application.manualSurfaceCreation = true; |
770 | - application.setState(ApplicationInfoInterface.Starting); |
771 | |
772 | - surfaceContainerLoader.item.surface = SurfaceManager.createSurface("foo", |
773 | - Mir.NormalType, Mir.MaximizedState, application.screenshot); |
774 | + application.createSurface(); |
775 | + surfaceContainerLoader.item.surface = application.surfaceList.get(0); |
776 | |
777 | application.setState(ApplicationInfoInterface.Running); |
778 | } else { |
779 | @@ -123,22 +125,11 @@ |
780 | } |
781 | } |
782 | |
783 | - Rectangle { |
784 | - border { |
785 | - color: "black" |
786 | - width: 1 |
787 | - } |
788 | - anchors { |
789 | - left: parent.left |
790 | - right: parent.right |
791 | - } |
792 | - Layout.preferredHeight: surfaceChildrenControl.height |
793 | - |
794 | - RecursingChildSessionControl { |
795 | - id: surfaceChildrenControl |
796 | - anchors { left: parent.left; right: parent.right; } |
797 | - |
798 | - surface: surfaceContainerLoader.item ? surfaceContainerLoader.item.surface : null |
799 | + Button { |
800 | + text: "Reload" |
801 | + enabled: !surfaceCheckbox.checked |
802 | + onClicked: { |
803 | + testCase.cleanup(); |
804 | } |
805 | } |
806 | } |
807 | @@ -164,6 +155,7 @@ |
808 | |
809 | surfaceCheckbox.checked = false; |
810 | interactiveCheckbox.checked = true; |
811 | + promptCheckbox.checked = false; |
812 | |
813 | surfaceContainerLoader.active = true; |
814 | tryCompare(surfaceContainerLoader, "status", Loader.Ready); |
815 | @@ -171,121 +163,6 @@ |
816 | |
817 | when: windowShown |
818 | |
819 | - function test_addChildSession_data() { |
820 | - return [ { tag: "count=1", count: 1 }, |
821 | - { tag: "count=4", count: 4 } ]; |
822 | - } |
823 | - |
824 | - function test_addChildSession(data) { |
825 | - surfaceCheckbox.checked = true; |
826 | - var childSurfaces = testCase.findChild(surfaceContainer, "childSurfacesRepeater"); |
827 | - compare(childSurfaces.count, 0); |
828 | - |
829 | - var i; |
830 | - for (i = 0; i < data.count; i++) { |
831 | - surfaceContainer.surface.createPromptSurface(); |
832 | - compare(childSurfaces.count, i+1); |
833 | - } |
834 | - |
835 | - for (i = data.count-1; i >= 0; i--) { |
836 | - { |
837 | - var childPromptSurface = surfaceContainer.surface.promptSurfaceList.get(i); |
838 | - childPromptSurface.close(); |
839 | - } |
840 | - tryCompareFunction(function() { return childSurfaces.count; }, i); |
841 | - } |
842 | - } |
843 | - |
844 | - function test_childSessionDestructionReturnsFocusToSiblingOrParent() { |
845 | - surfaceCheckbox.checked = true; |
846 | - var childSurfaces = testCase.findChild(surfaceContainer, "childSurfacesRepeater"); |
847 | - compare(childSurfaces.count, 0); |
848 | - |
849 | - var i; |
850 | - // 3 surfaces should cover all edge cases |
851 | - for (i = 0; i < 3; i++) { |
852 | - surfaceContainer.surface.createPromptSurface(); |
853 | - compare(childSurfaces.count, i+1); |
854 | - } |
855 | - |
856 | - for (i = 2; i >= 0; --i) { |
857 | - var childPromptSurface = surfaceContainer.surface.promptSurfaceList.get(i); |
858 | - compare(childPromptSurface.activeFocus, true); |
859 | - |
860 | - childPromptSurface.close(); |
861 | - tryCompareFunction(function() { return childSurfaces.count; }, i); |
862 | - |
863 | - if (i > 0) { |
864 | - // active focus should have gone to the yongest remaining sibling |
865 | - var previousSiblingSurface = surfaceContainer.surface.promptSurfaceList.get(i-1); |
866 | - tryCompare(previousSiblingSurface, "activeFocus", true); |
867 | - } else { |
868 | - // active focus should have gone to the parent surface |
869 | - tryCompare(surfaceContainer.surface, "activeFocus", true); |
870 | - } |
871 | - } |
872 | - } |
873 | - |
874 | - function test_nestedChildSessions_data() { |
875 | - return [ { tag: "depth=2", depth: 2 }, |
876 | - { tag: "depth=8", depth: 8 } |
877 | - ]; |
878 | - } |
879 | - function test_nestedChildSessions(data) { |
880 | - surfaceCheckbox.checked = true; |
881 | - |
882 | - var i; |
883 | - var container = surfaceContainer; |
884 | - var surface = container.surface; |
885 | - var surfaces = [surface]; |
886 | - var parent_childSurfaces = [null]; |
887 | - for (i = 0; i < data.depth; i++) { |
888 | - surface.createPromptSurface(); |
889 | - var childSurfaces = testCase.findChild(container, "childSurfacesRepeater"); |
890 | - compare(childSurfaces.count, 1); |
891 | - |
892 | - var childDelegate = childSurfaces.itemAt(0); |
893 | - container = findChild(childDelegate, "surfaceContainer"); |
894 | - { |
895 | - var animationsLoader = findChild(container, "animationsLoader"); |
896 | - tryCompare(animationsLoader, "status", Loader.Ready); |
897 | - waitUntilTransitionsEnd(animationsLoader.item); |
898 | - } |
899 | - surface = container.surface; |
900 | - |
901 | - surfaces.push(surface); |
902 | - parent_childSurfaces.push(childSurfaces); |
903 | - } |
904 | - |
905 | - for (i = surfaces.length-1; i >= 0; i--) { |
906 | - surfaces[i].close(); |
907 | - if (parent_childSurfaces[i]) { |
908 | - tryCompareFunction(function() { return parent_childSurfaces[i].count; }, 0); |
909 | - } |
910 | - } |
911 | - } |
912 | - |
913 | - function test_childrenAdjustForParentSize() { |
914 | - surfaceCheckbox.checked = true; |
915 | - |
916 | - surfaceContainer.surface.createPromptSurface(); |
917 | - |
918 | - var delegate = findChild(surfaceContainer, "childDelegate0"); |
919 | - var childContainer = findChild(delegate, "surfaceContainer"); |
920 | - |
921 | - tryCompareFunction(function() { return childContainer.height === surfaceContainer.height; }, true); |
922 | - tryCompareFunction(function() { return childContainer.width === surfaceContainer.width; }, true); |
923 | - tryCompareFunction(function() { return childContainer.x === 0; }, true); |
924 | - tryCompareFunction(function() { return childContainer.y === 0; }, true); |
925 | - |
926 | - surfaceContainer.anchors.margins = units.gu(2); |
927 | - |
928 | - tryCompareFunction(function() { return childContainer.height === surfaceContainer.height; }, true); |
929 | - tryCompareFunction(function() { return childContainer.width === surfaceContainer.width; }, true); |
930 | - tryCompareFunction(function() { return childContainer.x === 0; }, true); |
931 | - tryCompareFunction(function() { return childContainer.y === 0; }, true); |
932 | - } |
933 | - |
934 | function isContainerAnimating(container) { |
935 | var animationsLoader = findChild(container, "animationsLoader"); |
936 | if (!animationsLoader || animationsLoader.status != Loader.Ready) { |
937 | @@ -303,25 +180,21 @@ |
938 | return false; |
939 | } |
940 | |
941 | - function test_childrenAnimate() { |
942 | + function test_promptSurfaceAnimates() { |
943 | + promptCheckbox.checked = true; |
944 | surfaceCheckbox.checked = true; |
945 | |
946 | - surfaceContainer.surface.createPromptSurface(); |
947 | - |
948 | - var delegate = findChild(surfaceContainer, "childDelegate0"); |
949 | - var childContainer = findChild(delegate, "surfaceContainer"); |
950 | - |
951 | - // wait for animation to begin |
952 | - tryCompareFunction(function() { return isContainerAnimating(childContainer); }, true); |
953 | - // wait for animation to end |
954 | - tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false); |
955 | - |
956 | - surfaceContainer.surface.promptSurfaceList.get(0).close(); |
957 | - |
958 | - // wait for animation to begin |
959 | - tryCompareFunction(function() { return isContainerAnimating(childContainer); }, true); |
960 | - // wait for animation to end |
961 | - tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false); |
962 | + // wait for animation to begin |
963 | + tryCompareFunction(function() { return isContainerAnimating(surfaceContainer); }, true); |
964 | + // wait for animation to end |
965 | + tryCompareFunction(function() { return isContainerAnimating(surfaceContainer); }, false); |
966 | + |
967 | + surfaceContainer.surface.close(); |
968 | + |
969 | + // wait for animation to begin |
970 | + tryCompareFunction(function() { return isContainerAnimating(surfaceContainer); }, true); |
971 | + // wait for animation to end |
972 | + tryCompareFunction(function() { return isContainerAnimating(surfaceContainer); }, false); |
973 | } |
974 | |
975 | function test_surfaceItemGetsNoTouchesWhenContainerNotInteractive() { |
FAILED: Continuous integration, rev:2396 /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/1229/ /unity8- jenkins. ubuntu. com/job/ build-0- fetch/1652 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 1604 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial+ overlay/ 1604 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 1597/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1597/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 1597/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1597/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 1597/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1597/console
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/1229/ rebuild
https:/