Merge lp:~unity-team/unity8/lp1475678.surface-occlude into lp:unity8

Proposed by Michał Sawicz
Status: Merged
Approved by: Daniel d'Andrada
Approved revision: 1989
Merged at revision: 2032
Proposed branch: lp:~unity-team/unity8/lp1475678.surface-occlude
Merge into: lp:unity8
Prerequisite: lp:~mterry/unity8/no-touch-no-lifecycle
Diff against target: 734 lines (+290/-46)
13 files modified
debian/control (+1/-1)
qml/Stages/DesktopStage.qml (+78/-8)
qml/Stages/PhoneStage.qml (+16/-5)
qml/Stages/TabletStage.qml (+17/-1)
qml/Stages/TransformedTabletSpreadDelegate.qml (+2/-0)
tests/mocks/Unity/Application/MirSurface.cpp (+44/-17)
tests/mocks/Unity/Application/MirSurface.h (+14/-4)
tests/mocks/Unity/Application/MirSurfaceItem.cpp (+12/-2)
tests/mocks/Unity/Application/MirSurfaceItem.h (+1/-0)
tests/qmltests/Stages/tst_DesktopStage.qml (+81/-5)
tests/qmltests/Stages/tst_PhoneStage.qml (+4/-0)
tests/qmltests/Stages/tst_TabletStage.qml (+6/-1)
tests/qmltests/tst_Shell.qml (+14/-2)
To merge this branch: bzr merge lp:~unity-team/unity8/lp1475678.surface-occlude
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Daniel d'Andrada (community) Approve
Michał Sawicz Pending
Michael Zanetti Pending
Review via email: mp+275926@code.launchpad.net

This proposal supersedes a proposal from 2015-10-05.

Commit message

Support server->client visibility change to stop rendering (lp:#1475678)

Description of the change

Support server->client visibility change to stop rendering (lp:#1475678)

 * Are there any related MPs required for this MP to build/function as expected? Please list.
https://code.launchpad.net/~nick-dedekind/qtmir/lp1475678.surface-occlude/+merge/273426
https://code.launchpad.net/~nick-dedekind/unity-api/lp1475678.surface-occlude/+merge/275884
https://code.launchpad.net/~nick-dedekind/qtubuntu/lp1475678.surface-occlude/+merge/273424
https://code.launchpad.net/~mterry/qtmir/no-touch-no-lifecycle/+merge/272791

 * Did you perform an exploratory manual test run of your code change and any related functionality?
 * Did you make sure that your branch does not contain spurious tags?
 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
 * If you changed the UI, has there been a design review?

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

In qml/Stages/TabletStage.qml:

"""
+ // Hiding tiles when their progress is negative or reached the maximum
"""

A TODO item?

review: Needs Information
Revision history for this message
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal

> In qml/Stages/TabletStage.qml:
>
> """
> + // Hiding tiles when their progress is negative or reached the maximum
> """
>
> A TODO item?

Yes. Fixed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

Shouldn't we do something for DesktopStage.qml as well? I quickly checked its code and it seems it doesn't set windows visibility at all.

Things to check:
 - Minimized windows should have their MirSurfaces invisible/occluded.
 - When a window is focused (on foreground, index 0) and maximized, the MirSurfaces of all others should be invisible/occluded

review: Needs Fixing
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

W dniu 13.10.2015 o 14:41, Daniel d'Andrada pisze:
> Things to check:
> - Minimized windows should have their MirSurfaces invisible/occluded.
> - When a window is focused (on foreground, index 0) and maximized, the MirSurfaces of all others should be invisible/occluded

And (maybe later) we should actually try and determine real visibility -
if a window is completely covered by others (we should probably exclude
windows with alpha from this), it should be made invisible/occluded, too.

Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

Left some inline comments; also:

> When a window is focused (on foreground, index 0) and maximized, the MirSurfaces of all others
> should be invisible/occluded

Just wondering what happens in multi monitor situations, should all the other windows/surfaces get occluded too in this case?

Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

On 13/10/2015 10:32, Lukáš Tinkl wrote:
>> When a window is focused (on foreground, index 0) and maximized, the MirSurfaces of all others
>> >should be invisible/occluded
> Just wondering what happens in multi monitor situations, should all the other windows/surfaces get occluded too in this case?

Since multimonitor hasn't landed and this branch does not build on top
of it, it can't really address multimonitor issues here. Furthermore, on
the first iteration, windows will be shown all in a single screen (be it
the built-in display or an external monitor), so multimonitor doesn't
really affect occlusion scenarios right now.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal

> Shouldn't we do something for DesktopStage.qml as well? I quickly checked its
> code and it seems it doesn't set windows visibility at all.
>
> Things to check:
> - Minimized windows should have their MirSurfaces invisible/occluded.
> - When a window is focused (on foreground, index 0) and maximized, the
> MirSurfaces of all others should be invisible/occluded

Added.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

Could you please add a qml test to tst_DesktopStage to cover the "hide windows behind the maximized one" feature? Logic looks involved enough to warrant a test.

Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

* Open 2 windows so that both are visible. Maximize one, the other will disappear before it's occluded.

* It breaks the alt+tab preview.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

> * Open 2 windows so that both are visible. Maximize one, the other will
> disappear before it's occluded.
>
> * It breaks the alt+tab preview.

Both seem to be fixed now.

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) : Posted in a previous version of this proposal
review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
1979. By Nick Dedekind

bump libunity-api version

1980. By Michał Sawicz

Merge lp:~mterry/unity8/no-touch-no-lifecycle

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1981. By Nick Dedekind

added clear

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In DesktopStage.qml:

"""
if (priv.foregroundMaximizedAppId === model.appId) {
    priv.foregroundMaximizedAppIdIndex = index;
}
else if (priv.foregroundMaximizedAppIdIndex == -1 ||
         (index >= 0 && index <= priv.foregroundMaximizedAppIdIndex)) {
    priv.foregroundMaximizedAppIdIndex = index;
}
"""

Coding style. The "else if" should be in the same line as the closing braces of the previous if.

if () {
} else if () {
}

-------------------------------

In DesktopStage.qml:

"""
(spread.focus && index === spread.highlightedIndex)
"""

Everywhere checks for spread.state == "altTab". You should do the same. spread.focus just happens to be true when the spread is being displayed (alttab state).

--------------------------------

In DesktopStage.qml:

It looks like a circular dependency (binding loop?) as foregroundMaximizedAppId is defined by foregroundMaximizedAppIdIndex (as per the binding assined to it) but foregroundMaximizedAppId also helps define foregroundMaximizedAppIdIndex in updateMaximized().

And it smells fishy that you had to come up with connectMaxEnabled as a way to avoid recursive calls to updateMaximize().

There must be a better way.

-------------------------------

Whenever feasible tests should be manually reproducible. test_applicationsBecomeVisibleWhenOccludingAppRemoved maximizes too applications in a row. You cannot do it manually. It's not a scenario that could happen in "real life". You cannot maximize dialer without also focusing it, which would bring it to the front. Better change the order of the calls so that you maximize dialer right after you launch it.

And you should preferably maximize a window by clicking on its corresponding button in its decoration, like a real user would do, and not by calling an internal function. Again, following the logic of being as close to "real life" code paths as possible. Who knows, maybe clicking on the maximize button causes some subtleties in the QML state which affects what is being tested. And that would not happen when you call the internal function directly.

-----------------------------------

Also all those new tests are taking a data parameter but none of them have a testFoo_data() function. Please remove the parameter.

review: Needs Fixing
1982. By Nick Dedekind

remove binding loop

1983. By Nick Dedekind

review

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> In DesktopStage.qml:
>
> """
> if (priv.foregroundMaximizedAppId === model.appId) {
> priv.foregroundMaximizedAppIdIndex = index;
> }
> else if (priv.foregroundMaximizedAppIdIndex == -1 ||
> (index >= 0 && index <= priv.foregroundMaximizedAppIdIndex)) {
> priv.foregroundMaximizedAppIdIndex = index;
> }
> """
>
> Coding style. The "else if" should be in the same line as the closing braces
> of the previous if.
>
> if () {
> } else if () {
> }
>
> -------------------------------
>
> In DesktopStage.qml:
>
>
> """
> (spread.focus && index === spread.highlightedIndex)
> """
>
> Everywhere checks for spread.state == "altTab". You should do the same.
> spread.focus just happens to be true when the spread is being displayed
> (alttab state).

Done.

>
> --------------------------------
>
> In DesktopStage.qml:
>
> It looks like a circular dependency (binding loop?) as
> foregroundMaximizedAppId is defined by foregroundMaximizedAppIdIndex (as per
> the binding assined to it) but foregroundMaximizedAppId also helps define
> foregroundMaximizedAppIdIndex in updateMaximized().
>
> And it smells fishy that you had to come up with connectMaxEnabled as a way to
> avoid recursive calls to updateMaximize().
>
> There must be a better way.

Done.

>
> -------------------------------
>
> Whenever feasible tests should be manually reproducible.
> test_applicationsBecomeVisibleWhenOccludingAppRemoved maximizes too
> applications in a row. You cannot do it manually. It's not a scenario that
> could happen in "real life". You cannot maximize dialer without also focusing
> it, which would bring it to the front. Better change the order of the calls so
> that you maximize dialer right after you launch it.
>
> And you should preferably maximize a window by clicking on its corresponding
> button in its decoration, like a real user would do, and not by calling an
> internal function. Again, following the logic of being as close to "real life"
> code paths as possible. Who knows, maybe clicking on the maximize button
> causes some subtleties in the QML state which affects what is being tested.
> And that would not happen when you call the internal function directly.

Apart from the fact you actually can maximize an app underneath another (bug maybe), this is just setting up the initial conditions for the test, ie having 2 maximised applications. I've changed it to maximise after opening the applications.

These are supposed to be unit tests which are testing the stage aren't they, so we shouldn't be testing the decorations.

>
> -----------------------------------
>
> Also all those new tests are taking a data parameter but none of them have a
> testFoo_data() function. Please remove the parameter.

Done.

1984. By Nick Dedekind

reverted max change

1985. By Nick Dedekind

reverted debug

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

On 29/10/2015 12:32, Nick Dedekind wrote:
> These are supposed to be unit tests which are testing the stage aren't they, so we shouldn't be testing the decorations.

Kind of. If you skip this part you're missing the
interactions/integration between the decoration and the Stage. As I
previously explained. So your test is not wrong, but it's definitely
less valuable in my opinion.

But ok, won't block because of this.

1986. By Nick Dedekind

seq animations

1987. By Nick Dedekind

removed foregroundMaximizedAppId

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

All qmltests passed but for one, unrelated, failure:

FAIL! : qmltestrunner::IndicatorsMenu::test_verticalVelocityDetector() property currentItem
   Actual ():
   Expected ():
   Loc: [/home/dandrader/unity8/lp1475678.surface-occlude/tests/qmltests/Panel/tst_IndicatorsMenu.qml(257)]

It passes if run in "make testIndicatorsMenu" but fails in "make xvfbtestIndicatorsMenu"

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Getting this warning several times on the Nexus 7. Don't understand why:

file:///usr/share/unity8//Stages/TabletStage.qml:665: ReferenceError: isFocused is not defined

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)
1988. By Nick Dedekind

use maximise as unmaximise if already maximised

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> On 29/10/2015 12:32, Nick Dedekind wrote:
> > These are supposed to be unit tests which are testing the stage aren't they,
> so we shouldn't be testing the decorations.
>
> Kind of. If you skip this part you're missing the
> interactions/integration between the decoration and the Stage. As I
> previously explained. So your test is not wrong, but it's definitely
> less valuable in my opinion.
>
> But ok, won't block because of this.

Valid. I've changed the test to emit the signal from the DecoratedWindow.
I had to fix another bug to do this. where clicking maximise when already maximised will not unmaximise.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> All qmltests passed but for one, unrelated, failure:
>
> FAIL! : qmltestrunner::IndicatorsMenu::test_verticalVelocityDetector()
> property currentItem
> Actual ():
> Expected ():
> Loc: [/home/dandrader/unity8/lp1475678.surface-
> occlude/tests/qmltests/Panel/tst_IndicatorsMenu.qml(257)]
>
>
> It passes if run in "make testIndicatorsMenu" but fails in "make
> xvfbtestIndicatorsMenu"

Works for me. maybe it's a random failure?

1989. By Nick Dedekind

fixed tablet undefined

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> Getting this warning several times on the Nexus 7. Don't understand why:
>
> file:///usr/share/unity8//Stages/TabletStage.qml:665: ReferenceError:
> isFocused is not defined

Doesnt exist in tablet delegate. Fixed.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

This qml state fast-forwarding is a real PITA. This is what happens when I maximize the settings application:

http://pastebin.ubuntu.com/13008409/

So we do generate some noise, with apps getting switched unnecessarily (invisible-then-visible-then-invisible).

But not a deal-breaker. Guess we can optimize (or work around) that later.

Revision history for this message
Daniel d'Andrada (dandrader) :
review: Approve
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> This qml state fast-forwarding is a real PITA. This is what happens when I
> maximize the settings application:
>
> http://pastebin.ubuntu.com/13008409/
>
> So we do generate some noise, with apps getting switched unnecessarily
> (invisible-then-visible-then-invisible).
>
> But not a deal-breaker. Guess we can optimize (or work around) that later.

BTW, adding a TODO or FIXME in the code about this issue would be nice, so we don't forget about it.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1990. By Nick Dedekind

Fixed shell test orientation defaults

1991. By Nick Dedekind

fixed occlusion exceptions

1992. By Nick Dedekind

switch around

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2015-10-21 11:51:11 +0000
+++ debian/control 2015-11-04 14:53:37 +0000
@@ -29,7 +29,7 @@
29 libqt5xmlpatterns5-dev,29 libqt5xmlpatterns5-dev,
30 libsystemsettings-dev,30 libsystemsettings-dev,
31 libudev-dev,31 libudev-dev,
32 libunity-api-dev (>= 7.101),32 libunity-api-dev (>= 7.102),
33 libusermetricsoutput1-dev,33 libusermetricsoutput1-dev,
34 libxcb1-dev,34 libxcb1-dev,
35 pkg-config,35 pkg-config,
3636
=== modified file 'qml/Stages/DesktopStage.qml'
--- qml/Stages/DesktopStage.qml 2015-11-04 14:53:36 +0000
+++ qml/Stages/DesktopStage.qml 2015-11-04 14:53:37 +0000
@@ -68,6 +68,22 @@
68 var index = indexOf(focusedAppId);68 var index = indexOf(focusedAppId);
69 return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null69 return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null
70 }70 }
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
72 function indexOf(appId) {88 function indexOf(appId) {
73 for (var i = 0; i < ApplicationManager.count; i++) {89 for (var i = 0; i < ApplicationManager.count; i++) {
@@ -114,8 +130,12 @@
114 model: ApplicationManager130 model: ApplicationManager
115 objectName: "appRepeater"131 objectName: "appRepeater"
116132
133 onItemAdded: priv.updateForegroundMaximizedApp()
134 onItemRemoved: priv.updateForegroundMaximizedApp()
135
117 delegate: FocusScope {136 delegate: FocusScope {
118 id: appDelegate137 id: appDelegate
138 objectName: "stageDelegate_" + model.appId
119 z: ApplicationManager.count - index139 z: ApplicationManager.count - index
120 y: units.gu(3)140 y: units.gu(3)
121 width: units.gu(60)141 width: units.gu(60)
@@ -126,12 +146,25 @@
126 property bool minimized: false146 property bool minimized: false
127 property bool animationsEnabled: true147 property bool animationsEnabled: true
128148
149 property bool visuallyMaximized: false
150 property bool visuallyMinimized: false
151
129 onFocusChanged: {152 onFocusChanged: {
130 if (focus && ApplicationManager.focusedApplicationId !== model.appId) {153 if (focus && ApplicationManager.focusedApplicationId !== model.appId) {
131 ApplicationManager.focusApplication(model.appId);154 ApplicationManager.focusApplication(model.appId);
132 }155 }
133 }156 }
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
135 Binding {168 Binding {
136 target: ApplicationManager.get(index)169 target: ApplicationManager.get(index)
137 property: "requestedState"170 property: "requestedState"
@@ -161,23 +194,60 @@
161194
162 states: [195 states: [
163 State {196 State {
164 name: "normal"; when: !appDelegate.maximized && !appDelegate.minimized197 name: "normal";
198 when: !appDelegate.maximized && !appDelegate.minimized
199 PropertyChanges {
200 target: appDelegate;
201 visuallyMinimized: false;
202 visuallyMaximized: false
203 }
165 },204 },
166 State {205 State {
167 name: "maximized"; when: appDelegate.maximized206 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 }
169 },214 },
170 State {215 State {
171 name: "minimized"; when: appDelegate.minimized216 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 }
173 }225 }
174 ]226 ]
175 transitions: [227 transitions: [
176 Transition {228 Transition {
177 from: "maximized,minimized,normal,"229 to: "normal"
178 to: "maximized,minimized,normal,"230 enabled: appDelegate.animationsEnabled
179 enabled: appDelegate.animationsEnabled231 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
180 PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale" }232 PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale,opacity" }
233 },
234 Transition {
235 to: "maximized"
236 enabled: appDelegate.animationsEnabled
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 }
181 },251 },
182 Transition {252 Transition {
183 from: ""253 from: ""
@@ -223,7 +293,7 @@
223 focus: true293 focus: true
224294
225 onClose: ApplicationManager.stopApplication(model.appId)295 onClose: ApplicationManager.stopApplication(model.appId)
226 onMaximize: appDelegate.maximize()296 onMaximize: appDelegate.maximized ? appDelegate.unmaximize() : appDelegate.maximize()
227 onMinimize: appDelegate.minimize()297 onMinimize: appDelegate.minimize()
228 onDecorationPressed: { ApplicationManager.focusApplication(model.appId) }298 onDecorationPressed: { ApplicationManager.focusApplication(model.appId) }
229 }299 }
230300
=== modified file 'qml/Stages/PhoneStage.qml'
--- qml/Stages/PhoneStage.qml 2015-11-04 14:53:36 +0000
+++ qml/Stages/PhoneStage.qml 2015-11-04 14:53:37 +0000
@@ -20,6 +20,7 @@
20import Unity.Application 0.120import Unity.Application 0.1
21import Unity.Session 0.121import Unity.Session 0.1
22import Utils 0.122import Utils 0.1
23import Powerd 0.1
23import "../Components"24import "../Components"
2425
25AbstractStage {26AbstractStage {
@@ -182,7 +183,8 @@
182 }183 }
183 }184 }
184185
185 property bool focusedAppDelegateIsDislocated: focusedAppDelegate && focusedAppDelegate.x !== 0186 property bool focusedAppDelegateIsDislocated: focusedAppDelegate &&
187 (focusedAppDelegate.x !== 0 || focusedAppDelegate.xBehavior.running)
186188
187 function indexOf(appId) {189 function indexOf(appId) {
188 for (var i = 0; i < root.applicationManager.count; i++) {190 for (var i = 0; i < root.applicationManager.count; i++) {
@@ -473,7 +475,6 @@
473475
474 property var xBehavior: xBehavior476 property var xBehavior: xBehavior
475 Behavior on x {477 Behavior on x {
476 id: xBehavior
477 enabled: root.spreadEnabled &&478 enabled: root.spreadEnabled &&
478 !spreadView.active &&479 !spreadView.active &&
479 !snapAnimation.running &&480 !snapAnimation.running &&
@@ -481,6 +482,7 @@
481 priv.animateX &&482 priv.animateX &&
482 !root.beingResized483 !root.beingResized
483 UbuntuNumberAnimation {484 UbuntuNumberAnimation {
485 id: xBehavior
484 duration: UbuntuAnimation.BriskDuration486 duration: UbuntuAnimation.BriskDuration
485 }487 }
486 }488 }
@@ -520,9 +522,18 @@
520 return progress;522 return progress;
521 }523 }
522524
523 // Hiding tiles when their progress is negative or reached the maximum525 // Hide tile when progress is such that it will be off screen.
524 visible: (progress >= 0 && progress < 1.7)526 property bool occluded: {
525 || (isDash && priv.focusedAppDelegateIsDislocated)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
527 shellOrientationAngle: root.shellOrientationAngle538 shellOrientationAngle: root.shellOrientationAngle
528 shellOrientation: root.shellOrientation539 shellOrientation: root.shellOrientation
529540
=== modified file 'qml/Stages/TabletStage.qml'
--- qml/Stages/TabletStage.qml 2015-11-04 14:53:36 +0000
+++ qml/Stages/TabletStage.qml 2015-11-04 14:53:37 +0000
@@ -1,4 +1,4 @@
1/*1/*
2 * Copyright (C) 2014-2015 Canonical, Ltd.2 * Copyright (C) 2014-2015 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@
19import Ubuntu.Gestures 0.119import Ubuntu.Gestures 0.1
20import Unity.Application 0.120import Unity.Application 0.1
21import Utils 0.121import Utils 0.1
22import Powerd 0.1
22import "../Components"23import "../Components"
2324
24AbstractStage {25AbstractStage {
@@ -146,6 +147,8 @@
146 }147 }
147 }148 }
148149
150 property bool focusedAppDelegateIsDislocated: focusedAppDelegate &&
151 (focusedAppDelegate.dragOffset !== 0 || focusedAppDelegate.xTranslateAnimating)
149 function indexOf(appId) {152 function indexOf(appId) {
150 for (var i = 0; i < ApplicationManager.count; i++) {153 for (var i = 0; i < ApplicationManager.count; i++) {
151 if (ApplicationManager.get(i).appId == appId) {154 if (ApplicationManager.get(i).appId == appId) {
@@ -659,6 +662,19 @@
659 return tileProgress;662 return tileProgress;
660 }663 }
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
662 animatedProgress: {678 animatedProgress: {
663 if (spreadView.phase == 0 && (spreadTile.active || spreadView.nextInStack == index)) {679 if (spreadView.phase == 0 && (spreadTile.active || spreadView.nextInStack == index)) {
664 if (progress < spreadView.positionMarker1) {680 if (progress < spreadView.positionMarker1) {
665681
=== modified file 'qml/Stages/TransformedTabletSpreadDelegate.qml'
--- qml/Stages/TransformedTabletSpreadDelegate.qml 2015-03-06 04:44:11 +0000
+++ qml/Stages/TransformedTabletSpreadDelegate.qml 2015-11-04 14:53:37 +0000
@@ -48,6 +48,7 @@
48 property bool isInSideStage: false48 property bool isInSideStage: false
4949
50 property int dragOffset: 050 property int dragOffset: 0
51 readonly property alias xTranslateAnimating: xTranslateAnimation.running
5152
52 dropShadow: spreadView.active ||53 dropShadow: spreadView.active ||
53 (active54 (active
@@ -144,6 +145,7 @@
144 spreadView.animateX &&145 spreadView.animateX &&
145 !spreadView.beingResized146 !spreadView.beingResized
146 UbuntuNumberAnimation {147 UbuntuNumberAnimation {
148 id: xTranslateAnimation
147 duration: UbuntuAnimation.FastDuration149 duration: UbuntuAnimation.FastDuration
148 }150 }
149 }151 }
150152
=== modified file 'tests/mocks/Unity/Application/MirSurface.cpp'
--- tests/mocks/Unity/Application/MirSurface.cpp 2015-09-25 12:13:13 +0000
+++ tests/mocks/Unity/Application/MirSurface.cpp 2015-11-04 14:53:37 +0000
@@ -31,7 +31,7 @@
31 , m_screenshotUrl(screenshot)31 , m_screenshotUrl(screenshot)
32 , m_qmlFilePath(qmlFilePath)32 , m_qmlFilePath(qmlFilePath)
33 , m_live(true)33 , m_live(true)
34 , m_viewCount(0)34 , m_visible(true)
35 , m_activeFocus(false)35 , m_activeFocus(false)
36 , m_width(-1)36 , m_width(-1)
37 , m_height(-1)37 , m_height(-1)
@@ -73,6 +73,11 @@
73 return m_live;73 return m_live;
74}74}
7575
76bool MirSurface::visible() const
77{
78 return m_visible;
79}
80
76void MirSurface::setLive(bool live)81void MirSurface::setLive(bool live)
77{82{
78// qDebug().nospace() << "MirSurface::setLive("<<live<<") " << name();83// qDebug().nospace() << "MirSurface::setLive("<<live<<") " << name();
@@ -82,7 +87,7 @@
82 m_live = live;87 m_live = live;
83 Q_EMIT liveChanged(live);88 Q_EMIT liveChanged(live);
8489
85 if (!m_live && m_viewCount == 0) {90 if (!m_live && m_views.count() == 0) {
86 deleteLater();91 deleteLater();
87 }92 }
88}93}
@@ -120,27 +125,49 @@
120 Q_EMIT orientationAngleChanged(angle);125 Q_EMIT orientationAngleChanged(angle);
121}126}
122127
123void MirSurface::incrementViewCount()128
129
130void MirSurface::registerView(qintptr viewId)
124{131{
125 ++m_viewCount;132 m_views.insert(viewId, MirSurface::View{false});
126// qDebug().nospace() << "MirSurface::incrementViewCount() viewCount(after)=" << m_viewCount << " " << name();133// qDebug().nospace() << "MirSurface[" << name() << "]::registerView(" << viewId << ")"
134// << " after=" << m_views.count();
127}135}
128136
129void MirSurface::decrementViewCount()137void MirSurface::unregisterView(qintptr viewId)
130{138{
131 --m_viewCount;139// qDebug().nospace() << "MirSurface[" << name() << "]::unregisterView(" << viewId << ")"
132// qDebug().nospace() << "MirSurface::decrementViewCount() viewCount(after)=" << m_viewCount << " " << name();140// << " after=" << m_views.count() << " live=" << m_live;
133141 m_views.remove(viewId);
134 Q_ASSERT(m_viewCount >= 0);142 if (!m_live && m_views.count() == 0) {
135
136 if (!m_live && m_viewCount == 0) {
137 deleteLater();143 deleteLater();
138 }144 }
139}145 updateVisibility();
140146}
141int MirSurface::viewCount() const147
142{148void MirSurface::setViewVisibility(qintptr viewId, bool visible)
143 return m_viewCount;149{
150 if (!m_views.contains(viewId)) return;
151
152 m_views[viewId].visible = visible;
153 updateVisibility();
154}
155
156void 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 }
144}171}
145172
146bool MirSurface::activeFocus() const173bool MirSurface::activeFocus() const
147174
=== modified file 'tests/mocks/Unity/Application/MirSurface.h'
--- tests/mocks/Unity/Application/MirSurface.h 2015-09-02 10:35:16 +0000
+++ tests/mocks/Unity/Application/MirSurface.h 2015-11-04 14:53:37 +0000
@@ -19,6 +19,7 @@
1919
20#include <QObject>20#include <QObject>
21#include <QUrl>21#include <QUrl>
22#include <QHash>
2223
23// unity-api24// unity-api
24#include <unity/shell/application/MirSurfaceInterface.h>25#include <unity/shell/application/MirSurfaceInterface.h>
@@ -58,6 +59,8 @@
5859
59 bool live() const override;60 bool live() const override;
6061
62 bool visible() const override;
63
61 Mir::OrientationAngle orientationAngle() const override;64 Mir::OrientationAngle orientationAngle() const override;
62 void setOrientationAngle(Mir::OrientationAngle) override;65 void setOrientationAngle(Mir::OrientationAngle) override;
6366
@@ -66,9 +69,10 @@
6669
67 Q_INVOKABLE void setLive(bool live);70 Q_INVOKABLE void setLive(bool live);
6871
69 void incrementViewCount();72 void registerView(qintptr viewId);
70 void decrementViewCount();73 void unregisterView(qintptr viewId);
71 int viewCount() const;74 void setViewVisibility(qintptr viewId, bool visible);
75 int viewCount() const { return m_views.count(); }
7276
73 int width() const;77 int width() const;
74 int height() const;78 int height() const;
@@ -97,6 +101,8 @@
97 void activeFocusChanged(bool);101 void activeFocusChanged(bool);
98102
99private:103private:
104 void updateVisibility();
105
100 const QString m_name;106 const QString m_name;
101 const Mir::Type m_type;107 const Mir::Type m_type;
102 Mir::State m_state;108 Mir::State m_state;
@@ -104,10 +110,14 @@
104 QUrl m_screenshotUrl;110 QUrl m_screenshotUrl;
105 QUrl m_qmlFilePath;111 QUrl m_qmlFilePath;
106 bool m_live;112 bool m_live;
107 int m_viewCount;113 bool m_visible;
108 bool m_activeFocus;114 bool m_activeFocus;
109 int m_width;115 int m_width;
110 int m_height;116 int m_height;
117 struct View {
118 bool visible;
119 };
120 QHash<qintptr, View> m_views;
111};121};
112122
113#endif // MOCK_MIR_SURFACE_H123#endif // MOCK_MIR_SURFACE_H
114124
=== modified file 'tests/mocks/Unity/Application/MirSurfaceItem.cpp'
--- tests/mocks/Unity/Application/MirSurfaceItem.cpp 2015-09-25 12:13:13 +0000
+++ tests/mocks/Unity/Application/MirSurfaceItem.cpp 2015-11-04 14:53:37 +0000
@@ -44,6 +44,8 @@
44 Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 |44 Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 |
45 Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 |45 Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 |
46 Qt::ExtraButton12 | Qt::ExtraButton13);46 Qt::ExtraButton12 | Qt::ExtraButton13);
47
48 connect(this, &QQuickItem::visibleChanged, this, &MirSurfaceItem::updateMirSurfaceVisibility);
47}49}
4850
49MirSurfaceItem::~MirSurfaceItem()51MirSurfaceItem::~MirSurfaceItem()
@@ -194,17 +196,18 @@
194 m_qmlContentComponent = nullptr;196 m_qmlContentComponent = nullptr;
195197
196 disconnect(m_qmlSurface, nullptr, this, nullptr);198 disconnect(m_qmlSurface, nullptr, this, nullptr);
197 m_qmlSurface->decrementViewCount();199 m_qmlSurface->unregisterView((qintptr)this);
198 }200 }
199201
200 m_qmlSurface = static_cast<MirSurface*>(surface);202 m_qmlSurface = static_cast<MirSurface*>(surface);
201203
202 if (m_qmlSurface) {204 if (m_qmlSurface) {
203 m_qmlSurface->incrementViewCount();205 m_qmlSurface->registerView((qintptr)this);
204206
205 m_qmlSurface->setActiveFocus(hasActiveFocus());207 m_qmlSurface->setActiveFocus(hasActiveFocus());
206208
207 updateSurfaceSize();209 updateSurfaceSize();
210 updateMirSurfaceVisibility();
208211
209 connect(m_qmlSurface, &MirSurface::orientationAngleChanged, this, &MirSurfaceItem::orientationAngleChanged);212 connect(m_qmlSurface, &MirSurface::orientationAngleChanged, this, &MirSurfaceItem::orientationAngleChanged);
210 connect(m_qmlSurface, &MirSurface::screenshotUrlChanged, this, &MirSurfaceItem::updateScreenshot);213 connect(m_qmlSurface, &MirSurface::screenshotUrlChanged, this, &MirSurfaceItem::updateScreenshot);
@@ -253,6 +256,13 @@
253 }256 }
254}257}
255258
259void MirSurfaceItem::updateMirSurfaceVisibility()
260{
261 if (!m_qmlSurface) return;
262
263 m_qmlSurface->setViewVisibility((qintptr)this, isVisible());
264}
265
256void MirSurfaceItem::setConsumesInput(bool value)266void MirSurfaceItem::setConsumesInput(bool value)
257{267{
258 if (m_consumesInput != value) {268 if (m_consumesInput != value) {
259269
=== modified file 'tests/mocks/Unity/Application/MirSurfaceItem.h'
--- tests/mocks/Unity/Application/MirSurfaceItem.h 2015-09-19 07:37:52 +0000
+++ tests/mocks/Unity/Application/MirSurfaceItem.h 2015-11-04 14:53:37 +0000
@@ -87,6 +87,7 @@
87private Q_SLOTS:87private Q_SLOTS:
88 void onComponentStatusChanged(QQmlComponent::Status status);88 void onComponentStatusChanged(QQmlComponent::Status status);
89 void updateScreenshot(QUrl screenshot);89 void updateScreenshot(QUrl screenshot);
90 void updateMirSurfaceVisibility();
9091
91private:92private:
92 void createQmlContentItem();93 void createQmlContentItem();
9394
=== modified file 'tests/qmltests/Stages/tst_DesktopStage.qml'
--- tests/qmltests/Stages/tst_DesktopStage.qml 2015-09-17 12:25:29 +0000
+++ tests/qmltests/Stages/tst_DesktopStage.qml 2015-11-04 14:53:37 +0000
@@ -23,24 +23,31 @@
23import Utils 0.123import Utils 0.1
2424
25import "../../../qml/Stages"25import "../../../qml/Stages"
26import "../../../qml/Components"
2627
27Item {28Item {
28 id: root29 id: root
29 width: desktopStageLoader.width + controls.width30 width: desktopStageLoader.width + controls.width
30 height: desktopStageLoader.height31 height: desktopStageLoader.height
3132
33 property var greeter: { fullyShown: true }
34
32 Binding {35 Binding {
33 target: MouseTouchAdaptor36 target: MouseTouchAdaptor
34 property: "enabled"37 property: "enabled"
35 value: false38 value: false
36 }39 }
3740
38 Component.onCompleted: {41 Component.onCompleted: resetGeometry()
42
43 function resetGeometry() {
39 // ensures apps which are tested decorations are in view.44 // ensures apps which are tested decorations are in view.
45 WindowStateStorage.clear();
40 WindowStateStorage.geometry = {46 WindowStateStorage.geometry = {
41 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)),47 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)),
42 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)),48 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)),
43 'camera-app': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)),49 '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))
44 }51 }
45 }52 }
4653
@@ -61,6 +68,7 @@
61 Component.onDestruction: {68 Component.onDestruction: {
62 desktopStageLoader.itemDestroyed = true;69 desktopStageLoader.itemDestroyed = true;
63 }70 }
71 orientations: Orientations {}
64 }72 }
65 }73 }
66 }74 }
@@ -110,14 +118,14 @@
110118
111 desktopStageLoader.active = true;119 desktopStageLoader.active = true;
112 tryCompare(desktopStageLoader, "status", Loader.Ready);120 tryCompare(desktopStageLoader, "status", Loader.Ready);
121 root.resetGeometry();
113 }122 }
114123
115 function killAllRunningApps() {124 function killAllRunningApps() {
116 while (ApplicationManager.count > 1) {125 while (ApplicationManager.count > 0) {
117 var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0126 ApplicationManager.stopApplication(ApplicationManager.get(0).appId);
118 ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
119 }127 }
120 compare(ApplicationManager.count, 1)128 compare(ApplicationManager.count, 0)
121 }129 }
122130
123 function waitUntilAppSurfaceShowsUp(appId) {131 function waitUntilAppSurfaceShowsUp(appId) {
@@ -210,5 +218,73 @@
210 tap(toAppDecoration);218 tap(toAppDecoration);
211 tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true);219 tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true);
212 }220 }
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 }
213 }289 }
214}290}
215291
=== modified file 'tests/qmltests/Stages/tst_PhoneStage.qml'
--- tests/qmltests/Stages/tst_PhoneStage.qml 2015-11-04 14:53:36 +0000
+++ tests/qmltests/Stages/tst_PhoneStage.qml 2015-11-04 14:53:37 +0000
@@ -18,6 +18,7 @@
18import QtTest 1.018import QtTest 1.0
19import Unity.Test 0.1 as UT19import Unity.Test 0.1 as UT
20import ".."20import ".."
21import "../../../qml/Components"
21import "../../../qml/Stages"22import "../../../qml/Stages"
22import Ubuntu.Components 0.123import Ubuntu.Components 0.1
23import Unity.Application 0.124import Unity.Application 0.1
@@ -26,6 +27,8 @@
26 width: units.gu(70)27 width: units.gu(70)
27 height: units.gu(70)28 height: units.gu(70)
2829
30 property var greeter: { fullyShown: true }
31
29 PhoneStage {32 PhoneStage {
30 id: phoneStage33 id: phoneStage
31 anchors { fill: parent; rightMargin: units.gu(30) }34 anchors { fill: parent; rightMargin: units.gu(30) }
@@ -34,6 +37,7 @@
34 maximizedAppTopMargin: units.gu(3) + units.dp(2)37 maximizedAppTopMargin: units.gu(3) + units.dp(2)
35 interactive: true38 interactive: true
36 shellOrientation: Qt.PortraitOrientation39 shellOrientation: Qt.PortraitOrientation
40 orientations: Orientations {}
37 }41 }
3842
39 Binding {43 Binding {
4044
=== modified file 'tests/qmltests/Stages/tst_TabletStage.qml'
--- tests/qmltests/Stages/tst_TabletStage.qml 2015-11-04 14:53:36 +0000
+++ tests/qmltests/Stages/tst_TabletStage.qml 2015-11-04 14:53:37 +0000
@@ -30,6 +30,8 @@
30 width: tabletStageLoader.width + controls.width30 width: tabletStageLoader.width + controls.width
31 height: tabletStageLoader.height31 height: tabletStageLoader.height
3232
33 property var greeter: { fullyShown: true }
34
33 Loader {35 Loader {
34 id: tabletStageLoader36 id: tabletStageLoader
3537
@@ -53,7 +55,10 @@
53 shellOrientation: Qt.LandscapeOrientation55 shellOrientation: Qt.LandscapeOrientation
54 nativeWidth: width56 nativeWidth: width
55 nativeHeight: height57 nativeHeight: height
56 orientations: Orientations{} // Defaults are fine for testing58 orientations: Orientations {
59 native_: Qt.LandscapeOrientation
60 primary: Qt.LandscapeOrientation
61 }
57 focus: true62 focus: true
58 }63 }
59 }64 }
6065
=== modified file 'tests/qmltests/tst_Shell.qml'
--- tests/qmltests/tst_Shell.qml 2015-11-04 14:53:36 +0000
+++ tests/qmltests/tst_Shell.qml 2015-11-04 14:53:37 +0000
@@ -61,6 +61,10 @@
6161
62 anchors.centerIn: parent62 anchors.centerIn: parent
6363
64 property int shellOrientation: Qt.PortraitOrientation
65 property int nativeOrientation: Qt.PortraitOrientation
66 property int primaryOrientation: Qt.PortraitOrientation
67
64 state: "phone"68 state: "phone"
65 states: [69 states: [
66 State {70 State {
@@ -77,6 +81,9 @@
77 target: shellLoader81 target: shellLoader
78 width: units.gu(100)82 width: units.gu(100)
79 height: units.gu(71)83 height: units.gu(71)
84 shellOrientation: Qt.LandscapeOrientation
85 nativeOrientation: Qt.LandscapeOrientation
86 primaryOrientation: Qt.LandscapeOrientation
80 }87 }
81 },88 },
82 State {89 State {
@@ -99,8 +106,13 @@
99 Shell {106 Shell {
100 id: __shell107 id: __shell
101 usageScenario: usageScenarioSelector.model[usageScenarioSelector.selectedIndex]108 usageScenario: usageScenarioSelector.model[usageScenarioSelector.selectedIndex]
102 orientation: Qt.PortraitOrientation109 nativeWidth: width
103 orientations: Orientations{} // Defaults are fine for testing110 nativeHeight: height
111 orientation: shellLoader.shellOrientation
112 orientations: Orientations {
113 native_: shellLoader.nativeOrientation
114 primary: shellLoader.primaryOrientation
115 }
104 Component.onDestruction: {116 Component.onDestruction: {
105 shellLoader.itemDestroyed = true;117 shellLoader.itemDestroyed = true;
106 }118 }

Subscribers

People subscribed via source and target branches