Merge lp:~nick-dedekind/unity8/shell_chrome into lp:unity8

Proposed by Nick Dedekind
Status: Superseded
Proposed branch: lp:~nick-dedekind/unity8/shell_chrome
Merge into: lp:unity8
Diff against target: 835 lines (+341/-27)
20 files modified
CMakeLists.txt (+1/-1)
debian/control (+3/-3)
qml/Shell.qml (+5/-1)
qml/Stages/AbstractStage.qml (+2/-0)
qml/Stages/DesktopFullscreenPolicy.qml (+40/-0)
qml/Stages/DesktopStage.qml (+61/-9)
qml/Stages/PhoneFullscreenPolicy.qml (+53/-0)
qml/Stages/PhoneStage.qml (+10/-0)
qml/Stages/TabletStage.qml (+10/-0)
qml/Stages/WindowResizeArea.qml (+1/-1)
tests/mocks/Unity/Application/ApplicationInfo.cpp (+21/-3)
tests/mocks/Unity/Application/ApplicationInfo.h (+5/-1)
tests/mocks/Unity/Application/ApplicationManager.cpp (+3/-4)
tests/mocks/Unity/Application/MirSurface.cpp (+16/-0)
tests/mocks/Unity/Application/MirSurface.h (+5/-3)
tests/mocks/Unity/Application/MirSurfaceItem.cpp (+9/-0)
tests/mocks/Unity/Application/MirSurfaceItem.h (+1/-0)
tests/mocks/Unity/Application/Session.cpp (+26/-1)
tests/mocks/Unity/Application/Session.h (+7/-0)
tests/qmltests/tst_Shell.qml (+62/-0)
To merge this branch: bzr merge lp:~nick-dedekind/unity8/shell_chrome
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Unity8 CI Bot continuous-integration Needs Fixing
Unity Team Pending
Review via email: mp+286306@code.launchpad.net

This proposal has been superseded by a proposal from 2016-02-17.

Commit message

Add support for low shell chrome.

Description of the change

* Are there any related MPs required for this MP to build/function as expected? Please list.
https://code.launchpad.net/~nick-dedekind/unity-api/shell_chrome/+merge/286309
https://code.launchpad.net/~nick-dedekind/qtmir/shell_chrome/+merge/286307
https://code.launchpad.net/~nick-dedekind/qtubuntu/shell_chrome/+merge/286308

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * Did you make sure that your branch does not contain spurious tags?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

 * If you changed the UI, has there been a design review?
No

To post a comment you must log in.
2208. By Nick Dedekind

whitespace

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

+++ qml/Shell.qml
+ property string qmlComponent: {
could be readonly.

+++ qml/Stages/AbstractStage.qml
+ signal stageUnloaded
Why can you not depend on the already-existing Component.onDestruction signal? Is it happening too late?

Also when this is fired, the stage as not yet been unloaded. stageAboutToBeUnloaded would be a more accurate name :)

So I see you use it here:
+ property bool saveStateOnDestruction: true
+ Connections {
+ target: root
+ onStageUnloaded: {
+ resizeArea.saveWindowState();
+ resizeArea.saveStateOnDestruction = false;
+ fullscreenPolicy.active = false;
+ }
+ }
+ Component.onDestruction: {
+ if (saveStateOnDestruction) {
+ saveWindowState();
+ }
+ }
this is strange code. It looks like you are waiting for 2 events to save the windowState, and save on the first event. This is really strange looking, you need to justify it, and why Component.onDestruction is not enough. I do know that object destruction order is not guaranteed, is that it? If so, then why use it at all?

+++ qml/Stages/DesktopFullscreenPolicy.qml
this doesn't need to be an item, it doesn't contain anything visual. This can just be a single QtObject. You might be able to import QtQml instead of QtQuick too. lastSurface can be readonly too. Indent of the 'if" statement not clear.

I don't understand why it doesn't apply on the first surface. Could you also write a comment to explain the policy?

+++ qml/Stages/PhoneFullscreenPolicy.qml
I also suspect this could be a QtObject (am not sure if Connections will work inside QtObject though). It is odd to see "PhoneFullscreenPolicy" mentioned in TabletStage - would there be a better name? I'd also like a textual comment explaining what the policy is doing.

Why does this not have the first surface branch the Desktop policy has?

=== modified file 'qml/Stages/DesktopStage.qml'
- property alias requestedWidth: decoratedWindow.requestedWidth
- property alias requestedHeight: decoratedWindow.requestedHeight
+ property int requestedWidth: -1
+ property int requestedHeight: -1
why? You overriding the requested width/height? Or just because you animate them?

+++ tests/qmltests/tst_Shell.qml
just to confirm you mean to return the bool result of the comparison:
+ controls.focusedSurface.state === Mir.FullscreenState
Do we all know that JS returns the result of the last statement, if nothing is explicitly returned?

Revision history for this message
Gerry Boland (gerboland) wrote :

I still need to test on devices

Unmerged revisions

2200. By Launchpad Translations on behalf of unity-team

Launchpad automatic translations update.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-02-12 00:12:30 +0000
3+++ CMakeLists.txt 2016-02-17 14:46:08 +0000
4@@ -57,7 +57,7 @@
5 find_package(Qt5Concurrent 5.4 REQUIRED)
6 find_package(Qt5Sql 5.4 REQUIRED)
7
8-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=13)
9+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=14)
10 pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
11 pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
12 pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
13
14=== modified file 'debian/control'
15--- debian/control 2016-02-12 00:12:30 +0000
16+++ debian/control 2016-02-17 14:46:08 +0000
17@@ -29,7 +29,7 @@
18 libqt5xmlpatterns5-dev,
19 libsystemsettings-dev,
20 libudev-dev,
21- libunity-api-dev (>= 7.106),
22+ libunity-api-dev (>= 7.107),
23 libusermetricsoutput1-dev,
24 # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
25 libx11-dev[!armhf],
26@@ -131,7 +131,7 @@
27 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
28 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
29 ubuntu-thumbnailer-impl-0,
30- unity-application-impl-13,
31+ unity-application-impl-14,
32 unity-notifications-impl-3,
33 unity-plugin-scopes | unity-scopes-impl,
34 unity-scopes-impl-9,
35@@ -177,7 +177,7 @@
36 Depends: ${misc:Depends},
37 ${shlibs:Depends},
38 Provides: unity-application-impl,
39- unity-application-impl-13,
40+ unity-application-impl-14,
41 Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
42 Description: Fake environment for running Unity 8 shell
43 Provides fake implementations of some QML modules used by Unity 8 shell
44
45=== modified file 'qml/Shell.qml'
46--- qml/Shell.qml 2016-01-28 18:25:14 +0000
47+++ qml/Shell.qml 2016-02-17 14:46:08 +0000
48@@ -242,7 +242,7 @@
49 property string usageScenario: shell.usageScenario === "phone" || greeter.hasLockedApp
50 ? "phone"
51 : shell.usageScenario
52- source: {
53+ property string qmlComponent: {
54 if(shell.mode === "greeter") {
55 return "Stages/ShimStage.qml"
56 } else if (applicationsDisplayLoader.usageScenario === "phone") {
57@@ -253,6 +253,10 @@
58 return "Stages/DesktopStage.qml";
59 }
60 }
61+ onQmlComponentChanged: {
62+ if (item) item.stageUnloaded();
63+ source = qmlComponent;
64+ }
65
66 property bool interactive: tutorial.spreadEnabled
67 && (!greeter || !greeter.shown)
68
69=== modified file 'qml/Stages/AbstractStage.qml'
70--- qml/Stages/AbstractStage.qml 2016-01-14 13:03:20 +0000
71+++ qml/Stages/AbstractStage.qml 2016-02-17 14:46:08 +0000
72@@ -49,6 +49,8 @@
73 | Qt.InvertedPortraitOrientation
74 | Qt.InvertedLandscapeOrientation
75
76+ signal stageUnloaded
77+
78 // Shared code for use in stage implementations
79 GSettings {
80 id: lifecycleExceptions
81
82=== added file 'qml/Stages/DesktopFullscreenPolicy.qml'
83--- qml/Stages/DesktopFullscreenPolicy.qml 1970-01-01 00:00:00 +0000
84+++ qml/Stages/DesktopFullscreenPolicy.qml 2016-02-17 14:46:08 +0000
85@@ -0,0 +1,40 @@
86+/*
87+ * Copyright (C) 2016 Canonical, Ltd.
88+ *
89+ * This program is free software; you can redistribute it and/or modify
90+ * it under the terms of the GNU General Public License as published by
91+ * the Free Software Foundation; version 3.
92+ *
93+ * This program is distributed in the hope that it will be useful,
94+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
95+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
96+ * GNU General Public License for more details.
97+ *
98+ * You should have received a copy of the GNU General Public License
99+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
100+ */
101+
102+import QtQuick 2.4
103+import Unity.Application 0.1
104+
105+Item {
106+ property bool active: true
107+ property QtObject application: null
108+
109+ QtObject {
110+ id: priv
111+ property bool firstTimeSurface: true
112+ property var lastSurface: application && application.session ?
113+ application.session.lastSurface : null
114+ onLastSurfaceChanged: {
115+ if (!active || !lastSurface) return;
116+ if (!firstTimeSurface) return;
117+ firstTimeSurface = false;
118+
119+ if (lastSurface.state === Mir.FullscreenState &&
120+ lastSurface.shellChrome === Mir.LowChrome) {
121+ lastSurface.state = Mir.RestoredState;
122+ }
123+ }
124+ }
125+}
126
127=== modified file 'qml/Stages/DesktopStage.qml'
128--- qml/Stages/DesktopStage.qml 2016-02-03 14:00:47 +0000
129+++ qml/Stages/DesktopStage.qml 2016-02-17 14:46:08 +0000
130@@ -254,8 +254,8 @@
131 focus: appId === priv.focusedAppId
132 width: decoratedWindow.width
133 height: decoratedWindow.height
134- property alias requestedWidth: decoratedWindow.requestedWidth
135- property alias requestedHeight: decoratedWindow.requestedHeight
136+ property int requestedWidth: -1
137+ property int requestedHeight: -1
138 property alias minimumWidth: decoratedWindow.minimumWidth
139 property alias minimumHeight: decoratedWindow.minimumHeight
140 property alias maximumWidth: decoratedWindow.maximumWidth
141@@ -372,20 +372,40 @@
142 PropertyChanges {
143 target: appDelegate;
144 x: 0; y: 0;
145- requestedWidth: root.width; requestedHeight: root.height;
146 visuallyMinimized: false;
147 visuallyMaximized: true
148 }
149+ PropertyChanges {
150+ target: decoratedWindow
151+ requestedWidth: root.width;
152+ requestedHeight: root.height;
153+ }
154 },
155 State {
156 name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized
157- PropertyChanges { target: appDelegate; x: 0; y: PanelState.panelHeight;
158- requestedWidth: root.width/2; requestedHeight: root.height - PanelState.panelHeight }
159+ PropertyChanges {
160+ target: appDelegate;
161+ x: 0;
162+ y: PanelState.panelHeight;
163+ }
164+ PropertyChanges {
165+ target: decoratedWindow
166+ requestedWidth: root.width/2
167+ requestedHeight: root.height - PanelState.panelHeight
168+ }
169 },
170 State {
171 name: "maximizedRight"; when: appDelegate.maximizedRight && !appDelegate.minimized
172- PropertyChanges { target: appDelegate; x: root.width/2; y: PanelState.panelHeight;
173- requestedWidth: root.width/2; requestedHeight: root.height - PanelState.panelHeight }
174+ PropertyChanges {
175+ target: appDelegate;
176+ x: root.width/2;
177+ y: PanelState.panelHeight
178+ }
179+ PropertyChanges {
180+ target: decoratedWindow
181+ requestedWidth: root.width/2;
182+ requestedHeight: root.height - PanelState.panelHeight
183+ }
184 },
185 State {
186 name: "minimized"; when: appDelegate.minimized
187@@ -405,13 +425,17 @@
188 enabled: appDelegate.animationsEnabled
189 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
190 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration }
191+ UbuntuNumberAnimation { target: decoratedWindow; properties: "requestedWidth,requestedHeight"; duration: UbuntuAnimation.FastDuration }
192 },
193 Transition {
194 to: "minimized"
195 enabled: appDelegate.animationsEnabled
196 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
197 SequentialAnimation {
198- UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration }
199+ ParallelAnimation {
200+ UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,scale"; duration: UbuntuAnimation.FastDuration }
201+ UbuntuNumberAnimation { target: decoratedWindow; properties: "requestedWidth,requestedHeight"; duration: UbuntuAnimation.FastDuration }
202+ }
203 PropertyAction { target: appDelegate; property: "visuallyMinimized" }
204 ScriptAction {
205 script: {
206@@ -427,7 +451,10 @@
207 enabled: appDelegate.animationsEnabled
208 PropertyAction { target: appDelegate; property: "visuallyMinimized" }
209 SequentialAnimation {
210- UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration }
211+ ParallelAnimation {
212+ UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,scale"; duration: UbuntuAnimation.FastDuration }
213+ UbuntuNumberAnimation { target: decoratedWindow; properties: "requestedWidth,requestedHeight"; duration: UbuntuAnimation.FastDuration }
214+ }
215 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
216 }
217 }
218@@ -442,6 +469,7 @@
219 }
220
221 WindowResizeArea {
222+ id: resizeArea
223 objectName: "windowResizeArea"
224 target: appDelegate
225 minWidth: units.gu(10)
226@@ -452,6 +480,21 @@
227 screenHeight: root.height
228
229 onPressed: { ApplicationManager.focusApplication(model.appId) }
230+
231+ property bool saveStateOnDestruction: true
232+ Connections {
233+ target: root
234+ onStageUnloaded: {
235+ resizeArea.saveWindowState();
236+ resizeArea.saveStateOnDestruction = false;
237+ fullscreenPolicy.active = false;
238+ }
239+ }
240+ Component.onDestruction: {
241+ if (saveStateOnDestruction) {
242+ saveWindowState();
243+ }
244+ }
245 }
246
247 DecoratedWindow {
248@@ -463,12 +506,21 @@
249 active: ApplicationManager.focusedApplicationId === model.appId
250 focus: true
251
252+ requestedWidth: appDelegate.requestedWidth
253+ requestedHeight: appDelegate.requestedHeight
254+
255 onClose: ApplicationManager.stopApplication(model.appId)
256 onMaximize: appDelegate.maximized || appDelegate.maximizedLeft || appDelegate.maximizedRight
257 ? appDelegate.restoreFromMaximized() : appDelegate.maximize()
258 onMinimize: appDelegate.minimize()
259 onDecorationPressed: { ApplicationManager.focusApplication(model.appId) }
260 }
261+
262+ DesktopFullscreenPolicy {
263+ id: fullscreenPolicy
264+ active: true
265+ application: decoratedWindow.application
266+ }
267 }
268 }
269 }
270
271=== added file 'qml/Stages/PhoneFullscreenPolicy.qml'
272--- qml/Stages/PhoneFullscreenPolicy.qml 1970-01-01 00:00:00 +0000
273+++ qml/Stages/PhoneFullscreenPolicy.qml 2016-02-17 14:46:08 +0000
274@@ -0,0 +1,53 @@
275+/*
276+ * Copyright (C) 2016 Canonical, Ltd.
277+ *
278+ * This program is free software; you can redistribute it and/or modify
279+ * it under the terms of the GNU General Public License as published by
280+ * the Free Software Foundation; version 3.
281+ *
282+ * This program is distributed in the hope that it will be useful,
283+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
284+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
285+ * GNU General Public License for more details.
286+ *
287+ * You should have received a copy of the GNU General Public License
288+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
289+ */
290+
291+import QtQuick 2.4
292+import Unity.Application 0.1
293+
294+Item {
295+ property bool active: true
296+ property QtObject application: null
297+
298+ QtObject {
299+ id: priv
300+ property var lastSurface: application && application.session ?
301+ application.session.lastSurface : null
302+ onLastSurfaceChanged: {
303+ if (!active || !lastSurface) return;
304+ if (lastSurface.shellChrome === Mir.LowChrome) {
305+ lastSurface.state = Mir.FullscreenState;
306+ }
307+ }
308+ }
309+
310+ Connections {
311+ target: priv.lastSurface
312+ onShellChromeChanged: {
313+ if (!active || !priv.lastSurface) return;
314+ if (priv.lastSurface.shellChrome === Mir.LowChrome || priv.lastSurface.state == Mir.FullscreenState) {
315+ priv.lastSurface.state = Mir.FullscreenState;
316+ } else {
317+ priv.lastSurface.state = Mir.RestoredState;
318+ }
319+ }
320+ onStateChanged: {
321+ if (!active) return;
322+ if (priv.lastSurface.state === Mir.RestoredState && priv.lastSurface.shellChrome === Mir.LowChrome) {
323+ priv.lastSurface.state = Mir.FullscreenState;
324+ }
325+ }
326+ }
327+}
328
329=== modified file 'qml/Stages/PhoneStage.qml'
330--- qml/Stages/PhoneStage.qml 2016-01-14 13:03:20 +0000
331+++ qml/Stages/PhoneStage.qml 2016-02-17 14:46:08 +0000
332@@ -580,6 +580,16 @@
333 property: "focusedAppOrientationChangesEnabled"
334 value: orientationChangesEnabled
335 }
336+
337+ PhoneFullscreenPolicy {
338+ id: fullscreenPolicy
339+ application: appDelegate.application
340+
341+ Connections {
342+ target: root
343+ onStageUnloaded: fullscreenPolicy.active = false
344+ }
345+ }
346 }
347 }
348 }
349
350=== modified file 'qml/Stages/TabletStage.qml'
351--- qml/Stages/TabletStage.qml 2016-01-14 13:03:20 +0000
352+++ qml/Stages/TabletStage.qml 2016-02-17 14:46:08 +0000
353@@ -743,6 +743,16 @@
354 period: (spreadView.positionMarker2 - spreadView.positionMarker1) / 3
355 progress: spreadTile.progress - spreadView.positionMarker1
356 }
357+
358+ PhoneFullscreenPolicy {
359+ id: fullscreenPolicy
360+ application: spreadTile.application
361+
362+ Connections {
363+ target: root
364+ onStageUnloaded: fullscreenPolicy.active = false
365+ }
366+ }
367 }
368 }
369 }
370
371=== modified file 'qml/Stages/WindowResizeArea.qml'
372--- qml/Stages/WindowResizeArea.qml 2016-02-03 14:00:47 +0000
373+++ qml/Stages/WindowResizeArea.qml 2016-02-17 14:46:08 +0000
374@@ -84,7 +84,7 @@
375 priv.updateNormalGeometry();
376 }
377
378- Component.onDestruction: {
379+ function saveWindowState() {
380 windowStateStorage.saveState(root.windowId, target.state == "maximized" ? WindowStateStorage.WindowStateMaximized : WindowStateStorage.WindowStateNormal)
381 windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight))
382 }
383
384=== modified file 'tests/mocks/Unity/Application/ApplicationInfo.cpp'
385--- tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-01-22 19:44:56 +0000
386+++ tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-02-17 14:46:08 +0000
387@@ -44,6 +44,7 @@
388 , m_isTouchApp(true)
389 , m_exemptFromLifecycle(false)
390 , m_manualSurfaceCreation(false)
391+ , m_shellChrome(Mir::NormalChrome)
392 {
393 }
394
395@@ -63,6 +64,7 @@
396 , m_isTouchApp(true)
397 , m_exemptFromLifecycle(false)
398 , m_manualSurfaceCreation(false)
399+ , m_shellChrome(Mir::NormalChrome)
400 {
401 }
402
403@@ -102,9 +104,11 @@
404 if (m_session) {
405 m_session->setApplication(this);
406 m_session->setParent(this);
407+ m_session->setFullscreen(m_fullscreen);
408 SessionManager::singleton()->registerSession(m_session);
409 connect(m_session, &Session::surfaceAdded,
410 this, &ApplicationInfo::onSessionSurfaceAdded);
411+ connect(m_session, &Session::fullscreenChanged, this, &ApplicationInfo::fullscreenChanged);
412
413 if (!m_manualSurfaceCreation) {
414 QTimer::singleShot(500, m_session, &Session::createSurface);
415@@ -191,12 +195,17 @@
416
417 void ApplicationInfo::setFullscreen(bool value)
418 {
419- if (value != m_fullscreen) {
420- m_fullscreen = value;
421- Q_EMIT fullscreenChanged(value);
422+ m_fullscreen = value;
423+ if (m_session) {
424+ m_session->setFullscreen(value);
425 }
426 }
427
428+bool ApplicationInfo::fullscreen() const
429+{
430+ return m_session ? m_session->fullscreen() : false;
431+}
432+
433 void ApplicationInfo::setManualSurfaceCreation(bool value)
434 {
435 if (value != m_manualSurfaceCreation) {
436@@ -262,6 +271,7 @@
437 } else {
438 setState(Suspended);
439 }
440+ surface->setShellChrome(m_shellChrome);
441 }
442 }
443
444@@ -291,3 +301,11 @@
445 Q_EMIT initialSurfaceSizeChanged(m_initialSurfaceSize);
446 }
447 }
448+
449+void ApplicationInfo::setShellChrome(Mir::ShellChrome shellChrome)
450+{
451+ m_shellChrome = shellChrome;
452+ if (m_session && m_session->lastSurface()) {
453+ m_session->lastSurface()->setShellChrome(shellChrome);
454+ }
455+}
456
457=== modified file 'tests/mocks/Unity/Application/ApplicationInfo.h'
458--- tests/mocks/Unity/Application/ApplicationInfo.h 2016-01-19 21:41:34 +0000
459+++ tests/mocks/Unity/Application/ApplicationInfo.h 2016-02-17 14:46:08 +0000
460@@ -24,6 +24,7 @@
461
462 // unity-api
463 #include <unity/shell/application/ApplicationInfoInterface.h>
464+#include <unity/shell/application/Mir.h>
465
466 using namespace unity::shell::application;
467
468@@ -78,7 +79,7 @@
469 QString screenshot() const { return m_screenshotFileName; }
470
471 void setFullscreen(bool value);
472- bool fullscreen() const { return m_fullscreen; }
473+ bool fullscreen() const;
474
475 Qt::ScreenOrientations supportedOrientations() const override;
476 void setSupportedOrientations(Qt::ScreenOrientations orientations);
477@@ -97,6 +98,8 @@
478
479 QSize initialSurfaceSize() const override;
480 void setInitialSurfaceSize(const QSize &size) override;
481+
482+ Q_INVOKABLE void setShellChrome(Mir::ShellChrome shellChrome);
483 public:
484 void setSession(Session* session);
485 Session* session() const { return m_session; }
486@@ -134,6 +137,7 @@
487 QSize m_initialSurfaceSize;
488
489 bool m_manualSurfaceCreation;
490+ Mir::ShellChrome m_shellChrome;
491 };
492
493 Q_DECLARE_METATYPE(ApplicationInfo*)
494
495=== modified file 'tests/mocks/Unity/Application/ApplicationManager.cpp'
496--- tests/mocks/Unity/Application/ApplicationManager.cpp 2015-12-03 18:10:39 +0000
497+++ tests/mocks/Unity/Application/ApplicationManager.cpp 2016-02-17 14:46:08 +0000
498@@ -336,6 +336,7 @@
499 application->setName("Camera");
500 application->setScreenshotId("camera");
501 application->setIconId("camera");
502+ application->setShellChrome(Mir::LowChrome);
503 application->setFullscreen(true);
504 application->setSupportedOrientations(Qt::PortraitOrientation
505 | Qt::LandscapeOrientation
506@@ -349,7 +350,7 @@
507 application->setName("Gallery");
508 application->setScreenshotId("gallery");
509 application->setIconId("gallery");
510- application->setFullscreen(true);
511+ application->setShellChrome(Mir::LowChrome);
512 application->setStage(ApplicationInfo::MainStage);
513 m_availableApplications.append(application);
514
515@@ -363,7 +364,7 @@
516
517 application = new ApplicationInfo(this);
518 application->setAppId("webbrowser-app");
519- application->setFullscreen(true);
520+ application->setShellChrome(Mir::LowChrome);
521 application->setName("Browser");
522 application->setScreenshotId("browser");
523 application->setIconId("browser");
524@@ -389,7 +390,6 @@
525 application->setName("GMail");
526 application->setIconId("gmail");
527 application->setScreenshotId("gmail-webapp.svg");
528- application->setFullscreen(false);
529 application->setStage(ApplicationInfo::MainStage);
530 application->setSupportedOrientations(Qt::PortraitOrientation
531 | Qt::LandscapeOrientation
532@@ -402,7 +402,6 @@
533 application->setName("Music");
534 application->setIconId("soundcloud");
535 application->setScreenshotId("music");
536- application->setFullscreen(false);
537 application->setStage(ApplicationInfo::MainStage);
538 application->setSupportedOrientations(Qt::PortraitOrientation
539 | Qt::LandscapeOrientation
540
541=== modified file 'tests/mocks/Unity/Application/MirSurface.cpp'
542--- tests/mocks/Unity/Application/MirSurface.cpp 2015-11-30 18:25:47 +0000
543+++ tests/mocks/Unity/Application/MirSurface.cpp 2016-02-17 14:46:08 +0000
544@@ -36,6 +36,7 @@
545 , m_width(-1)
546 , m_height(-1)
547 , m_slowToResize(false)
548+ , m_shellChrome(Mir::NormalChrome)
549 {
550 // qDebug() << "MirSurface::MirSurface() " << name;
551 m_delayedResizeTimer.setInterval(600);
552@@ -130,6 +131,21 @@
553 }
554
555
556+Mir::ShellChrome MirSurface::shellChrome() const
557+{
558+ return m_shellChrome;
559+}
560+
561+void MirSurface::setShellChrome(Mir::ShellChrome shellChrome)
562+{
563+ if (shellChrome == m_shellChrome)
564+ return;
565+
566+ m_shellChrome = shellChrome;
567+ Q_EMIT shellChromeChanged(shellChrome);
568+}
569+
570+
571
572 void MirSurface::registerView(qintptr viewId)
573 {
574
575=== modified file 'tests/mocks/Unity/Application/MirSurface.h'
576--- tests/mocks/Unity/Application/MirSurface.h 2015-11-30 18:25:47 +0000
577+++ tests/mocks/Unity/Application/MirSurface.h 2016-02-17 14:46:08 +0000
578@@ -73,10 +73,13 @@
579 int widthIncrement() const override { return m_widthIncrement; }
580 int heightIncrement() const override { return m_heightIncrement; }
581
582+ Mir::ShellChrome shellChrome() const override;
583+
584 ////
585 // API for tests
586
587 Q_INVOKABLE void setLive(bool live);
588+ Q_INVOKABLE void setShellChrome(Mir::ShellChrome shellChrome);
589
590 void registerView(qintptr viewId);
591 void unregisterView(qintptr viewId);
592@@ -108,9 +111,6 @@
593 void setActiveFocus(bool);
594
595 Q_SIGNALS:
596- void stateChanged(Mir::State);
597- void liveChanged(bool live);
598- void orientationAngleChanged(Mir::OrientationAngle angle);
599 void widthChanged();
600 void heightChanged();
601 void slowToResizeChanged();
602@@ -151,6 +151,8 @@
603 QSize m_delayedResize;
604 QSize m_pendingResize;
605
606+ Mir::ShellChrome m_shellChrome;
607+
608 struct View {
609 bool visible;
610 };
611
612=== modified file 'tests/mocks/Unity/Application/MirSurfaceItem.cpp'
613--- tests/mocks/Unity/Application/MirSurfaceItem.cpp 2016-01-25 15:00:31 +0000
614+++ tests/mocks/Unity/Application/MirSurfaceItem.cpp 2016-02-17 14:46:08 +0000
615@@ -100,6 +100,15 @@
616 }
617 }
618
619+Mir::ShellChrome MirSurfaceItem::shellChrome() const
620+{
621+ if (m_qmlSurface) {
622+ return m_qmlSurface->shellChrome();
623+ } else {
624+ return Mir::NormalChrome;
625+ }
626+}
627+
628 Mir::OrientationAngle MirSurfaceItem::orientationAngle() const
629 {
630 if (m_qmlSurface) {
631
632=== modified file 'tests/mocks/Unity/Application/MirSurfaceItem.h'
633--- tests/mocks/Unity/Application/MirSurfaceItem.h 2016-01-25 15:00:31 +0000
634+++ tests/mocks/Unity/Application/MirSurfaceItem.h 2016-02-17 14:46:08 +0000
635@@ -47,6 +47,7 @@
636 Mir::Type type() const override;
637 QString name() const override;
638 bool live() const override;
639+ Mir::ShellChrome shellChrome() const override;
640
641 Mir::State surfaceState() const override;
642 void setSurfaceState(Mir::State) override {}
643
644=== modified file 'tests/mocks/Unity/Application/Session.cpp'
645--- tests/mocks/Unity/Application/Session.cpp 2015-12-01 12:17:24 +0000
646+++ tests/mocks/Unity/Application/Session.cpp 2016-02-17 14:46:08 +0000
647@@ -34,6 +34,7 @@
648 , m_surface(nullptr)
649 , m_parentSession(nullptr)
650 , m_children(new SessionModel(this))
651+ , m_fullscreen(false)
652 {
653 // qDebug() << "Session::Session() " << this->name();
654
655@@ -71,6 +72,25 @@
656 deleteLater();
657 }
658
659+void Session::updateFullscreenProperty()
660+{
661+ if (m_surfaces.rowCount() > 0) {
662+ // TODO: Figure out something better
663+ setFullscreen(lastSurface()->state() == Mir::FullscreenState);
664+ } else {
665+ // Keep the current value of the fullscreen property until we get a new
666+ // surface
667+ }
668+}
669+
670+void Session::setFullscreen(bool fullscreen)
671+{
672+ if (m_fullscreen != fullscreen) {
673+ m_fullscreen = fullscreen;
674+ Q_EMIT fullscreenChanged(m_fullscreen);
675+ }
676+}
677+
678 void Session::setApplication(ApplicationInfo* application)
679 {
680 if (m_application == application)
681@@ -82,15 +102,18 @@
682
683 void Session::appendSurface(MirSurface* surface)
684 {
685- // qDebug() << "Session::appendSurface - session=" << name() << "surface=" << surface;
686+ qDebug() << "Session::appendSurface - session=" << name() << "surface=" << surface;
687
688 m_surfaces.insert(m_surfaces.rowCount(), surface);
689
690+ connect(surface, &MirSurfaceInterface::stateChanged, this, &Session::updateFullscreenProperty);
691 connect(surface, &QObject::destroyed,
692 this, [this, surface]() { this->removeSurface(surface); });
693
694 Q_EMIT lastSurfaceChanged(surface);
695 Q_EMIT surfaceAdded(surface);
696+
697+ updateFullscreenProperty();
698 }
699
700 void Session::removeSurface(MirSurface* surface)
701@@ -99,6 +122,8 @@
702 if (m_surfaces.contains(surface)) {
703 m_surfaces.remove(surface);
704 }
705+
706+ updateFullscreenProperty();
707 }
708
709 void Session::setScreenshot(const QUrl& screenshot)
710
711=== modified file 'tests/mocks/Unity/Application/Session.h'
712--- tests/mocks/Unity/Application/Session.h 2015-12-01 12:17:24 +0000
713+++ tests/mocks/Unity/Application/Session.h 2016-02-17 14:46:08 +0000
714@@ -47,6 +47,7 @@
715 //getters
716 QString name() const { return m_name; }
717 bool live() const { return m_live; }
718+ bool fullscreen() const { return m_fullscreen; }
719 ApplicationInfo* application() const { return m_application; }
720 MirSurface *lastSurface() const;
721 ObjectListModel<MirSurface>* surfaces() const;
722@@ -57,6 +58,7 @@
723 void removeSurface(MirSurface* surface);
724 void setScreenshot(const QUrl& m_screenshot);
725 void setLive(bool live);
726+ void setFullscreen(bool fullscreen);
727
728 Q_INVOKABLE void addChildSession(Session* session);
729 void insertChildSession(uint index, Session* session);
730@@ -68,6 +70,7 @@
731 void liveChanged(bool live);
732 void surfaceAdded(MirSurface *surface);
733 void lastSurfaceChanged(MirSurface *surface);
734+ void fullscreenChanged(bool fullscreen);
735
736 // internal mock use
737 void deregister();
738@@ -75,6 +78,9 @@
739 public Q_SLOTS:
740 Q_INVOKABLE void createSurface();
741
742+private Q_SLOTS:
743+ void updateFullscreenProperty();
744+
745 private:
746 SessionModel* childSessions() const;
747 void setParentSession(Session* session);
748@@ -87,6 +93,7 @@
749 Session* m_parentSession;
750 SessionModel* m_children;
751 ObjectListModel<MirSurface> m_surfaces;
752+ bool m_fullscreen;
753
754 friend class ApplicationTestInterface;
755 };
756
757=== modified file 'tests/qmltests/tst_Shell.qml'
758--- tests/qmltests/tst_Shell.qml 2016-02-12 00:11:28 +0000
759+++ tests/qmltests/tst_Shell.qml 2016-02-17 14:46:08 +0000
760@@ -139,6 +139,9 @@
761 anchors.right: root.right
762 width: units.gu(30)
763
764+ property var focusedApp: ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
765+ property var focusedSurface: focusedApp && focusedApp.session ? focusedApp.session.lastSurface : null
766+
767 Rectangle {
768 id: controlRect
769 anchors { left: parent.left; right: parent.right }
770@@ -234,6 +237,65 @@
771 appId: modelData
772 }
773 }
774+
775+ Label { text: "Focused Application"; font.bold: true }
776+
777+ Row {
778+ CheckBox {
779+ id: fullscreeAppCheck
780+
781+ onTriggered: {
782+ if (!controls.focusedSurface) return;
783+ if (controls.focusedSurface.state == Mir.FullscreenState) {
784+ controls.focusedSurface.state = Mir.RestoredState;
785+ } else {
786+ controls.focusedSurface.state = Mir.FullscreenState;
787+ }
788+ }
789+
790+ Binding {
791+ target: fullscreeAppCheck
792+ when: controls.focusedSurface
793+ property: "checked"
794+ value: {
795+ if (!controls.focusedSurface) return false;
796+ controls.focusedSurface.state === Mir.FullscreenState
797+ }
798+ }
799+ }
800+ Label {
801+ text: "Fullscreen"
802+ }
803+ }
804+
805+ Row {
806+ CheckBox {
807+ id: chromeAppCheck
808+
809+ onTriggered: {
810+ if (!controls.focusedSurface) return;
811+ if (controls.focusedSurface.shellChrome == Mir.LowChrome) {
812+ controls.focusedSurface.setShellChrome(Mir.NormalChrome);
813+ } else {
814+ controls.focusedSurface.setShellChrome(Mir.LowChrome);
815+ }
816+ }
817+
818+ Binding {
819+ target: chromeAppCheck
820+ when: controls.focusedSurface !== null
821+ property: "checked"
822+ value: {
823+ if (!controls.focusedSurface) return false;
824+ controls.focusedSurface.shellChrome === Mir.LowChrome
825+ }
826+ }
827+ }
828+ Label {
829+ text: "Low Chrome"
830+ }
831+ }
832+
833 }
834 }
835 }

Subscribers

People subscribed via source and target branches