on xenial help sign in
Support server->client visibility change to stop rendering (lp:#1475678) Fixes: #1475678

Approved by: Daniel d'Andrada

commit9794345c7cd71c3a5c1baf69634d747f67ab51a9 authorMichał Sawicz <michal.sawicz@canonical.com> dateWed 4 Nov 2015, 14:58 (11 years ago) parent931c63c2ce304c
13 files changed+286−42
debian/control+1−1 qml/Stages/DesktopStage.qml+77−7 qml/Stages/PhoneStage.qml+16−5 qml/Stages/TabletStage.qml+17−1 qml/Stages/TransformedTabletSpreadDelegate.qml+2 tests/mocks/Unity/Application/MirSurface.cpp+41−14 tests/mocks/Unity/Application/MirSurface.h+14−4 tests/mocks/Unity/Application/MirSurfaceItem.cpp+12−2 tests/mocks/Unity/Application/MirSurfaceItem.h+1 tests/qmltests/Stages/tst_DesktopStage.qml+81−5 tests/qmltests/Stages/tst_PhoneStage.qml+4 tests/qmltests/Stages/tst_TabletStage.qml+6−1 tests/qmltests/tst_Shell.qml+14−2
debian/control+1−1
@@ -29,7 +29,7 @@ Build-Depends: cmake,
2929 libqt5xmlpatterns5-dev,
3030 libsystemsettings-dev,
3131 libudev-dev,
32− libunity-api-dev (>= 7.101),
32+ libunity-api-dev (>= 7.102),
3333 libusermetricsoutput1-dev,
3434 libxcb1-dev,
3535 pkg-config,
qml/Stages/DesktopStage.qml+77−7
@@ -68,6 +68,22 @@ AbstractStage {
6868 var index = indexOf(focusedAppId);
6969 return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null
7070 }
71+ property int foregroundMaximizedAppIdIndex: -1
72+
73+ function updateForegroundMaximizedApp() {
74+ for (var i = 0; i < appRepeater.count; i++) {
75+ var item = appRepeater.itemAt(i);
76+
77+ if (item && item.visuallyMaximized) {
78+ var app = ApplicationManager.get(i);
79+ if (app) {
80+ foregroundMaximizedAppIdIndex = i;
81+ return;
82+ }
83+ }
84+ }
85+ foregroundMaximizedAppIdIndex = -1;
86+ }
7187
7288 function indexOf(appId) {
7389 for (var i = 0; i < ApplicationManager.count; i++) {
@@ -114,8 +130,12 @@ AbstractStage {
114130 model: ApplicationManager
115131 objectName: "appRepeater"
116132
133+ onItemAdded: priv.updateForegroundMaximizedApp()
134+ onItemRemoved: priv.updateForegroundMaximizedApp()
135+
117136 delegate: FocusScope {
118137 id: appDelegate
138+ objectName: "stageDelegate_" + model.appId
119139 z: ApplicationManager.count - index
120140 y: units.gu(3)
121141 width: units.gu(60)
@@ -126,12 +146,25 @@ AbstractStage {
126146 property bool minimized: false
127147 property bool animationsEnabled: true
128148
149+ property bool visuallyMaximized: false
150+ property bool visuallyMinimized: false
151+
129152 onFocusChanged: {
130153 if (focus && ApplicationManager.focusedApplicationId !== model.appId) {
131154 ApplicationManager.focusApplication(model.appId);
132155 }
133156 }
134157
158+ onZChanged: priv.updateForegroundMaximizedApp()
159+ onVisuallyMaximizedChanged: priv.updateForegroundMaximizedApp()
160+
161+ visible: !visuallyMinimized &&
162+ !greeter.fullyShown &&
163+ (priv.foregroundMaximizedAppIdIndex === -1 || priv.foregroundMaximizedAppIdIndex >= index) ||
164+ (spread.state == "altTab" && index === spread.highlightedIndex)
165+
166+ onVisibleChanged: console.log("VISIBLE", model.appId, visible)
167+
135168 Binding {
136169 target: ApplicationManager.get(index)
137170 property: "requestedState"
@@ -161,23 +194,60 @@ AbstractStage {
161194
162195 states: [
163196 State {
164− name: "normal"; when: !appDelegate.maximized && !appDelegate.minimized
197+ name: "normal";
198+ when: !appDelegate.maximized && !appDelegate.minimized
199+ PropertyChanges {
200+ target: appDelegate;
201+ visuallyMinimized: false;
202+ visuallyMaximized: false
203+ }
165204 },
166205 State {
167206 name: "maximized"; when: appDelegate.maximized
168− PropertyChanges { target: appDelegate; x: 0; y: 0; width: root.width; height: root.height }
207+ PropertyChanges {
208+ target: appDelegate;
209+ x: 0; y: 0;
210+ width: root.width; height: root.height;
211+ visuallyMinimized: false;
212+ visuallyMaximized: true
213+ }
169214 },
170215 State {
171216 name: "minimized"; when: appDelegate.minimized
172− PropertyChanges { target: appDelegate; x: -appDelegate.width / 2; scale: units.gu(5) / appDelegate.width; opacity: 0 }
217+ PropertyChanges {
218+ target: appDelegate;
219+ x: -appDelegate.width / 2;
220+ scale: units.gu(5) / appDelegate.width;
221+ opacity: 0
222+ visuallyMinimized: true;
223+ visuallyMaximized: false
224+ }
173225 }
174226 ]
175227 transitions: [
176228 Transition {
177− from: "maximized,minimized,normal,"
178− to: "maximized,minimized,normal,"
229+ to: "normal"
230+ enabled: appDelegate.animationsEnabled
231+ PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
232+ PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale,opacity" }
233+ },
234+ Transition {
235+ to: "maximized"
179236 enabled: appDelegate.animationsEnabled
180− PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale" }
237+ PropertyAction { target: appDelegate; property: "visuallyMinimized" }
238+ SequentialAnimation {
239+ PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale,opacity" }
240+ PropertyAction { target: appDelegate; property: "visuallyMaximized" }
241+ }
242+ },
243+ Transition {
244+ to: "minimized"
245+ enabled: appDelegate.animationsEnabled
246+ PropertyAction { target: appDelegate; property: "visuallyMaximized" }
247+ SequentialAnimation {
248+ PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale,opacity" }
249+ PropertyAction { target: appDelegate; property: "visuallyMinimized" }
250+ }
181251 },
182252 Transition {
183253 from: ""
@@ -224,7 +294,7 @@ AbstractStage {
224294 focus: true
225295
226296 onClose: ApplicationManager.stopApplication(model.appId)
227− onMaximize: appDelegate.maximize()
297+ onMaximize: appDelegate.maximized ? appDelegate.unmaximize() : appDelegate.maximize()
228298 onMinimize: appDelegate.minimize()
229299 onDecorationPressed: { ApplicationManager.focusApplication(model.appId) }
230300 }
qml/Stages/PhoneStage.qml+16−5
@@ -20,6 +20,7 @@ import Ubuntu.Gestures 0.1
2020import Unity.Application 0.1
2121import Unity.Session 0.1
2222import Utils 0.1
23+import Powerd 0.1
2324import "../Components"
2425
2526AbstractStage {
@@ -182,7 +183,8 @@ AbstractStage {
182183 }
183184 }
184185
185− property bool focusedAppDelegateIsDislocated: focusedAppDelegate && focusedAppDelegate.x !== 0
186+ property bool focusedAppDelegateIsDislocated: focusedAppDelegate &&
187+ (focusedAppDelegate.x !== 0 || focusedAppDelegate.xBehavior.running)
186188
187189 function indexOf(appId) {
188190 for (var i = 0; i < root.applicationManager.count; i++) {
@@ -473,7 +475,6 @@ AbstractStage {
473475
474476 property var xBehavior: xBehavior
475477 Behavior on x {
476− id: xBehavior
477478 enabled: root.spreadEnabled &&
478479 !spreadView.active &&
479480 !snapAnimation.running &&
@@ -481,6 +482,7 @@ AbstractStage {
481482 priv.animateX &&
482483 !root.beingResized
483484 UbuntuNumberAnimation {
485+ id: xBehavior
484486 duration: UbuntuAnimation.BriskDuration
485487 }
486488 }
@@ -520,9 +522,18 @@ AbstractStage {
520522 return progress;
521523 }
522524
523− // Hiding tiles when their progress is negative or reached the maximum
524− visible: (progress >= 0 && progress < 1.7)
525− || (isDash && priv.focusedAppDelegateIsDislocated)
525+ // Hide tile when progress is such that it will be off screen.
526+ property bool occluded: {
527+ if (spreadView.active && (progress >= 0 && progress < 1.7)) return false;
528+ else if (!spreadView.active && isFocused) return false;
529+ else if (xBehavior.running) return false;
530+ else if (z <= 1 && priv.focusedAppDelegateIsDislocated) return false;
531+ return true;
532+ }
533+
534+ visible: Powerd.status == Powerd.On &&
535+ !greeter.fullyShown &&
536+ !occluded
526537
527538 shellOrientationAngle: root.shellOrientationAngle
528539 shellOrientation: root.shellOrientation
qml/Stages/TabletStage.qml+17−1
@@ -1,4 +1,4 @@
1−/*
1+/*
22 * Copyright (C) 2014-2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@ import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
2020import Unity.Application 0.1
2121import Utils 0.1
22+import Powerd 0.1
2223import "../Components"
2324
2425AbstractStage {
@@ -146,6 +147,8 @@ AbstractStage {
146147 }
147148 }
148149
150+ property bool focusedAppDelegateIsDislocated: focusedAppDelegate &&
151+ (focusedAppDelegate.dragOffset !== 0 || focusedAppDelegate.xTranslateAnimating)
149152 function indexOf(appId) {
150153 for (var i = 0; i < ApplicationManager.count; i++) {
151154 if (ApplicationManager.get(i).appId == appId) {
@@ -659,6 +662,19 @@ AbstractStage {
659662 return tileProgress;
660663 }
661664
665+ // TODO: Hiding tile when progress is such that it will be off screen.
666+ property bool occluded: {
667+ if (spreadView.active) return false;
668+ else if (spreadTile.active) return false;
669+ else if (xTranslateAnimating) return false;
670+ else if (z <= 1 && priv.focusedAppDelegateIsDislocated) return false;
671+ return true;
672+ }
673+
674+ visible: Powerd.status == Powerd.On &&
675+ !greeter.fullyShown &&
676+ !occluded
677+
662678 animatedProgress: {
663679 if (spreadView.phase == 0 && (spreadTile.active || spreadView.nextInStack == index)) {
664680 if (progress < spreadView.positionMarker1) {
qml/Stages/TransformedTabletSpreadDelegate.qml+2
@@ -48,6 +48,7 @@ SpreadDelegate {
4848 property bool isInSideStage: false
4949
5050 property int dragOffset: 0
51+ readonly property alias xTranslateAnimating: xTranslateAnimation.running
5152
5253 dropShadow: spreadView.active ||
5354 (active
@@ -144,6 +145,7 @@ SpreadDelegate {
144145 spreadView.animateX &&
145146 !spreadView.beingResized
146147 UbuntuNumberAnimation {
148+ id: xTranslateAnimation
147149 duration: UbuntuAnimation.FastDuration
148150 }
149151 }
tests/mocks/Unity/Application/MirSurface.cpp+41−14
@@ -31,7 +31,7 @@ MirSurface::MirSurface(const QString& name,
3131 , m_screenshotUrl(screenshot)
3232 , m_qmlFilePath(qmlFilePath)
3333 , m_live(true)
34− , m_viewCount(0)
34+ , m_visible(true)
3535 , m_activeFocus(false)
3636 , m_width(-1)
3737 , m_height(-1)
@@ -73,6 +73,11 @@ bool MirSurface::live() const
7373 return m_live;
7474}
7575
76+bool MirSurface::visible() const
77+{
78+ return m_visible;
79+}
80+
7681void MirSurface::setLive(bool live)
7782{
7883// qDebug().nospace() << "MirSurface::setLive("<<live<<") " << name();
@@ -82,7 +87,7 @@ void MirSurface::setLive(bool live)
8287 m_live = live;
8388 Q_EMIT liveChanged(live);
8489
85− if (!m_live && m_viewCount == 0) {
90+ if (!m_live && m_views.count() == 0) {
8691 deleteLater();
8792 }
8893}
@@ -120,27 +125,49 @@ void MirSurface::setOrientationAngle(Mir::OrientationAngle angle)
120125 Q_EMIT orientationAngleChanged(angle);
121126}
122127
123−void MirSurface::incrementViewCount()
128+
129+
130+void MirSurface::registerView(qintptr viewId)
124131{
125− ++m_viewCount;
126−// qDebug().nospace() << "MirSurface::incrementViewCount() viewCount(after)=" << m_viewCount << " " << name();
132+ m_views.insert(viewId, MirSurface::View{false});
133+// qDebug().nospace() << "MirSurface[" << name() << "]::registerView(" << viewId << ")"
134+// << " after=" << m_views.count();
127135}
128136
129−void MirSurface::decrementViewCount()
137+void MirSurface::unregisterView(qintptr viewId)
130138{
131− --m_viewCount;
132−// qDebug().nospace() << "MirSurface::decrementViewCount() viewCount(after)=" << m_viewCount << " " << name();
133−
134− Q_ASSERT(m_viewCount >= 0);
135−
136− if (!m_live && m_viewCount == 0) {
139+// qDebug().nospace() << "MirSurface[" << name() << "]::unregisterView(" << viewId << ")"
140+// << " after=" << m_views.count() << " live=" << m_live;
141+ m_views.remove(viewId);
142+ if (!m_live && m_views.count() == 0) {
137143 deleteLater();
138144 }
145+ updateVisibility();
139146}
140147
141−int MirSurface::viewCount() const
148+void MirSurface::setViewVisibility(qintptr viewId, bool visible)
142149{
143− return m_viewCount;
150+ if (!m_views.contains(viewId)) return;
151+
152+ m_views[viewId].visible = visible;
153+ updateVisibility();
154+}
155+
156+void MirSurface::updateVisibility()
157+{
158+ bool newVisible = false;
159+ QHashIterator<qintptr, View> i(m_views);
160+ while (i.hasNext()) {
161+ i.next();
162+ newVisible |= i.value().visible;
163+ }
164+
165+ if (newVisible != visible()) {
166+// qDebug().nospace() << "MirSurface[" << name() << "]::updateVisibility(" << newVisible << ")";
167+
168+ m_visible = newVisible;
169+ Q_EMIT visibleChanged(m_visible);
170+ }
144171}
145172
146173bool MirSurface::activeFocus() const
tests/mocks/Unity/Application/MirSurface.h+14−4
@@ -19,6 +19,7 @@
1919
2020#include <QObject>
2121#include <QUrl>
22+#include <QHash>
2223
2324// unity-api
2425#include <unity/shell/application/MirSurfaceInterface.h>
@@ -58,6 +59,8 @@ public:
5859
5960 bool live() const override;
6061
62+ bool visible() const override;
63+
6164 Mir::OrientationAngle orientationAngle() const override;
6265 void setOrientationAngle(Mir::OrientationAngle) override;
6366
@@ -66,9 +69,10 @@ public:
6669
6770 Q_INVOKABLE void setLive(bool live);
6871
69− void incrementViewCount();
70− void decrementViewCount();
71− int viewCount() const;
72+ void registerView(qintptr viewId);
73+ void unregisterView(qintptr viewId);
74+ void setViewVisibility(qintptr viewId, bool visible);
75+ int viewCount() const { return m_views.count(); }
7276
7377 int width() const;
7478 int height() const;
@@ -97,6 +101,8 @@ Q_SIGNALS:
97101 void activeFocusChanged(bool);
98102
99103private:
104+ void updateVisibility();
105+
100106 const QString m_name;
101107 const Mir::Type m_type;
102108 Mir::State m_state;
@@ -104,10 +110,14 @@ private:
104110 QUrl m_screenshotUrl;
105111 QUrl m_qmlFilePath;
106112 bool m_live;
107− int m_viewCount;
113+ bool m_visible;
108114 bool m_activeFocus;
109115 int m_width;
110116 int m_height;
117+ struct View {
118+ bool visible;
119+ };
120+ QHash<qintptr, View> m_views;
111121};
112122
113123#endif // MOCK_MIR_SURFACE_H
tests/mocks/Unity/Application/MirSurfaceItem.cpp+12−2
@@ -44,6 +44,8 @@ MirSurfaceItem::MirSurfaceItem(QQuickItem *parent)
4444 Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 |
4545 Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 |
4646 Qt::ExtraButton12 | Qt::ExtraButton13);
47+
48+ connect(this, &QQuickItem::visibleChanged, this, &MirSurfaceItem::updateMirSurfaceVisibility);
4749}
4850
4951MirSurfaceItem::~MirSurfaceItem()
@@ -194,17 +196,18 @@ void MirSurfaceItem::setSurface(MirSurfaceInterface* surface)
194196 m_qmlContentComponent = nullptr;
195197
196198 disconnect(m_qmlSurface, nullptr, this, nullptr);
197− m_qmlSurface->decrementViewCount();
199+ m_qmlSurface->unregisterView((qintptr)this);
198200 }
199201
200202 m_qmlSurface = static_cast<MirSurface*>(surface);
201203
202204 if (m_qmlSurface) {
203− m_qmlSurface->incrementViewCount();
205+ m_qmlSurface->registerView((qintptr)this);
204206
205207 m_qmlSurface->setActiveFocus(hasActiveFocus());
206208
207209 updateSurfaceSize();
210+ updateMirSurfaceVisibility();
208211
209212 connect(m_qmlSurface, &MirSurface::orientationAngleChanged, this, &MirSurfaceItem::orientationAngleChanged);
210213 connect(m_qmlSurface, &MirSurface::screenshotUrlChanged, this, &MirSurfaceItem::updateScreenshot);
@@ -253,6 +256,13 @@ void MirSurfaceItem::itemChange(ItemChange change, const ItemChangeData & value)
253256 }
254257}
255258
259+void MirSurfaceItem::updateMirSurfaceVisibility()
260+{
261+ if (!m_qmlSurface) return;
262+
263+ m_qmlSurface->setViewVisibility((qintptr)this, isVisible());
264+}
265+
256266void MirSurfaceItem::setConsumesInput(bool value)
257267{
258268 if (m_consumesInput != value) {
tests/mocks/Unity/Application/MirSurfaceItem.h+1
@@ -87,6 +87,7 @@ protected:
8787private Q_SLOTS:
8888 void onComponentStatusChanged(QQmlComponent::Status status);
8989 void updateScreenshot(QUrl screenshot);
90+ void updateMirSurfaceVisibility();
9091
9192private:
9293 void createQmlContentItem();
tests/qmltests/Stages/tst_DesktopStage.qml+81−5
@@ -23,24 +23,31 @@ import Unity.Test 0.1
2323import Utils 0.1
2424
2525import "../../../qml/Stages"
26+import "../../../qml/Components"
2627
2728Item {
2829 id: root
2930 width: desktopStageLoader.width + controls.width
3031 height: desktopStageLoader.height
3132
33+ property var greeter: { fullyShown: true }
34+
3235 Binding {
3336 target: MouseTouchAdaptor
3437 property: "enabled"
3538 value: false
3639 }
3740
38− Component.onCompleted: {
41+ Component.onCompleted: resetGeometry()
42+
43+ function resetGeometry() {
3944 // ensures apps which are tested decorations are in view.
45+ WindowStateStorage.clear();
4046 WindowStateStorage.geometry = {
4147 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)),
4248 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)),
4349 'camera-app': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)),
50+ 'gallery-app': Qt.rect(units.gu(51), units.gu(44), units.gu(50), units.gu(40))
4451 }
4552 }
4653
@@ -61,6 +68,7 @@ Item {
6168 Component.onDestruction: {
6269 desktopStageLoader.itemDestroyed = true;
6370 }
71+ orientations: Orientations {}
6472 }
6573 }
6674 }
@@ -110,14 +118,14 @@ Item {
110118
111119 desktopStageLoader.active = true;
112120 tryCompare(desktopStageLoader, "status", Loader.Ready);
121+ root.resetGeometry();
113122 }
114123
115124 function killAllRunningApps() {
116− while (ApplicationManager.count > 1) {
117− var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
118− ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
125+ while (ApplicationManager.count > 0) {
126+ ApplicationManager.stopApplication(ApplicationManager.get(0).appId);
119127 }
120− compare(ApplicationManager.count, 1)
128+ compare(ApplicationManager.count, 0)
121129 }
122130
123131 function waitUntilAppSurfaceShowsUp(appId) {
@@ -210,5 +218,73 @@ Item {
210218 tap(toAppDecoration);
211219 tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true);
212220 }
221+
222+ function test_minimizeApplicationHidesSurface() {
223+ var dashApp = startApplication("unity8-dash");
224+
225+ var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash");
226+ verify(dashDelegate);
227+
228+ findChild(dashDelegate, "decoratedWindow").minimize();
229+ tryCompare(dashApp.session.surface, "visible", false);
230+ }
231+
232+ function test_maximizeApplicationHidesSurfacesBehindIt() {
233+ var dashApp = startApplication("unity8-dash");
234+ var dialerApp = startApplication("dialer-app");
235+ var cameraApp = startApplication("camera-app");
236+
237+ var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash");
238+ verify(dashDelegate);
239+ var dialerDelegate = findChild(desktopStage, "stageDelegate_dialer-app");
240+ verify(dialerDelegate);
241+ var cameraDelegate = findChild(desktopStage, "stageDelegate_camera-app");
242+ verify(cameraDelegate);
243+
244+ // maximize
245+ findChild(dialerDelegate, "decoratedWindow").maximize();
246+ tryCompare(dialerDelegate, "visuallyMaximized", true);
247+
248+ tryCompare(dashApp.session.surface, "visible", false);
249+ compare(cameraApp.session.surface.visible, true);
250+
251+ // restore
252+ findChild(dialerDelegate, "decoratedWindow").maximize();
253+ compare(dashApp.session.surface.visible, true);
254+ compare(cameraApp.session.surface.visible, true);
255+ }
256+
257+ function test_applicationsBecomeVisibleWhenOccludingAppRemoved() {
258+ var dashApp = startApplication("unity8-dash");
259+ var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash");
260+ verify(dashDelegate);
261+
262+ var dialerApp = startApplication("dialer-app");
263+ var dialerDelegate = findChild(desktopStage, "stageDelegate_dialer-app");
264+ verify(dialerDelegate);
265+
266+ var cameraApp = startApplication("camera-app");
267+ var cameraDelegate = findChild(desktopStage, "stageDelegate_camera-app");
268+ verify(cameraDelegate);
269+ findChild(dialerDelegate, "decoratedWindow").maximize();
270+
271+ var galleryApp = startApplication("gallery-app");
272+ var galleryDelegate = findChild(desktopStage, "stageDelegate_gallery-app");
273+ verify(galleryDelegate);
274+ findChild(galleryDelegate, "decoratedWindow").maximize();
275+
276+ tryCompare(dialerDelegate, "visuallyMaximized", true);
277+ tryCompare(galleryDelegate, "visuallyMaximized", true);
278+
279+ tryCompare(dashApp.session.surface, "visible", false);
280+ tryCompare(dialerApp.session.surface, "visible", false);
281+ tryCompare(cameraApp.session.surface, "visible", false);
282+
283+ ApplicationManager.stopApplication("gallery-app");
284+
285+ compare(cameraApp.session.surface.visible, true);
286+ tryCompare(dialerApp.session.surface, "visible", true);
287+ tryCompare(dashApp.session.surface, "visible", false); // still occluded by maximised dialer
288+ }
213289 }
214290}
tests/qmltests/Stages/tst_PhoneStage.qml+4
@@ -18,6 +18,7 @@ import QtQuick 2.4
1818import QtTest 1.0
1919import Unity.Test 0.1 as UT
2020import ".."
21+import "../../../qml/Components"
2122import "../../../qml/Stages"
2223import Ubuntu.Components 1.3
2324import Unity.Application 0.1
@@ -26,6 +27,8 @@ Item {
2627 width: units.gu(70)
2728 height: units.gu(70)
2829
30+ property var greeter: { fullyShown: true }
31+
2932 PhoneStage {
3033 id: phoneStage
3134 anchors { fill: parent; rightMargin: units.gu(30) }
@@ -34,6 +37,7 @@ Item {
3437 maximizedAppTopMargin: units.gu(3) + units.dp(2)
3538 interactive: true
3639 shellOrientation: Qt.PortraitOrientation
40+ orientations: Orientations {}
3741 }
3842
3943 Binding {
tests/qmltests/Stages/tst_TabletStage.qml+6−1
@@ -30,6 +30,8 @@ Rectangle {
3030 width: tabletStageLoader.width + controls.width
3131 height: tabletStageLoader.height
3232
33+ property var greeter: { fullyShown: true }
34+
3335 Loader {
3436 id: tabletStageLoader
3537
@@ -53,7 +55,10 @@ Rectangle {
5355 shellOrientation: Qt.LandscapeOrientation
5456 nativeWidth: width
5557 nativeHeight: height
56− orientations: Orientations{} // Defaults are fine for testing
58+ orientations: Orientations {
59+ native_: Qt.LandscapeOrientation
60+ primary: Qt.LandscapeOrientation
61+ }
5762 focus: true
5863 }
5964 }
tests/qmltests/tst_Shell.qml+14−2
@@ -61,6 +61,10 @@ Rectangle {
6161
6262 anchors.centerIn: parent
6363
64+ property int shellOrientation: Qt.PortraitOrientation
65+ property int nativeOrientation: Qt.PortraitOrientation
66+ property int primaryOrientation: Qt.PortraitOrientation
67+
6468 state: "phone"
6569 states: [
6670 State {
@@ -77,6 +81,9 @@ Rectangle {
7781 target: shellLoader
7882 width: units.gu(100)
7983 height: units.gu(71)
84+ shellOrientation: Qt.LandscapeOrientation
85+ nativeOrientation: Qt.LandscapeOrientation
86+ primaryOrientation: Qt.LandscapeOrientation
8087 }
8188 },
8289 State {
@@ -99,8 +106,13 @@ Rectangle {
99106 Shell {
100107 id: __shell
101108 usageScenario: usageScenarioSelector.model[usageScenarioSelector.selectedIndex]
102− orientation: Qt.PortraitOrientation
103− orientations: Orientations{} // Defaults are fine for testing
109+ nativeWidth: width
110+ nativeHeight: height
111+ orientation: shellLoader.shellOrientation
112+ orientations: Orientations {
113+ native_: shellLoader.nativeOrientation
114+ primary: shellLoader.primaryOrientation
115+ }
104116 Component.onDestruction: {
105117 shellLoader.itemDestroyed = true;
106118 }