Merge lp:~nick-dedekind/unity8/lp1475678.surface-occlude into lp:unity8
- lp1475678.surface-occlude
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~nick-dedekind/unity8/lp1475678.surface-occlude |
Merge into: | lp:unity8 |
Diff against target: |
510 lines (+233/-35) 9 files modified
debian/control (+1/-1) qml/Stages/DesktopStage.qml (+71/-3) qml/Stages/PhoneStage.qml (+10/-3) qml/Stages/TabletStage.qml (+8/-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 (+72/-5) |
To merge this branch: | bzr merge lp:~nick-dedekind/unity8/lp1475678.surface-occlude |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Michał Sawicz | Needs Fixing | ||
Michael Zanetti (community) | Abstain | ||
Daniel d'Andrada (community) | Needs Fixing | ||
Review via email: mp+273427@code.launchpad.net |
This proposal has been superseded by a proposal from 2015-10-27.
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:/
https:/
https:/
* 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?
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1974. By Nick Dedekind
-
occlude on screen power
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1974
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
In qml/Stages/
"""
+ // Hiding tiles when their progress is negative or reached the maximum
"""
A TODO item?
- 1975. By Nick Dedekind
-
update hide comment
Nick Dedekind (nick-dedekind) wrote : | # |
> In qml/Stages/
>
> """
> + // Hiding tiles when their progress is negative or reached the maximum
> """
>
> A TODO item?
Yes. Fixed.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1975
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
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
Michał Sawicz (saviq) wrote : | # |
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.
Lukáš Tinkl (lukas-kde) wrote : | # |
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?
Daniel d'Andrada (dandrader) wrote : | # |
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.
- 1976. By Nick Dedekind
-
dekstop stage item visibility
Nick Dedekind (nick-dedekind) wrote : | # |
> 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.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1976
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
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.
Michael Zanetti (mzanetti) wrote : | # |
* Open 2 windows so that both are visible. Maximize one, the other will disappear before it's occluded.
* It breaks the alt+tab preview.
- 1977. By Nick Dedekind
-
fixed surface visibility
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1977
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
> * 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.
- 1978. By Nick Dedekind
-
Only visible if in front of maximized application
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1978
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) : | # |
- 1979. By Nick Dedekind
-
merged with trunk
- 1980. By Nick Dedekind
-
bump libunity-api version
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1980
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Unmerged revisions
- 1980. By Nick Dedekind
-
bump libunity-api version
- 1979. By Nick Dedekind
-
merged with trunk
Preview Diff
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2015-10-21 11:51:11 +0000 | |||
3 | +++ debian/control 2015-10-26 18:36:26 +0000 | |||
4 | @@ -29,7 +29,7 @@ | |||
5 | 29 | libqt5xmlpatterns5-dev, | 29 | libqt5xmlpatterns5-dev, |
6 | 30 | libsystemsettings-dev, | 30 | libsystemsettings-dev, |
7 | 31 | libudev-dev, | 31 | libudev-dev, |
9 | 32 | libunity-api-dev (>= 7.101), | 32 | libunity-api-dev (>= 7.102), |
10 | 33 | libusermetricsoutput1-dev, | 33 | libusermetricsoutput1-dev, |
11 | 34 | libxcb1-dev, | 34 | libxcb1-dev, |
12 | 35 | pkg-config, | 35 | pkg-config, |
13 | 36 | 36 | ||
14 | === modified file 'qml/Stages/DesktopStage.qml' | |||
15 | --- qml/Stages/DesktopStage.qml 2015-10-19 14:27:57 +0000 | |||
16 | +++ qml/Stages/DesktopStage.qml 2015-10-26 18:36:26 +0000 | |||
17 | @@ -65,6 +65,11 @@ | |||
18 | 65 | 65 | ||
19 | 66 | ApplicationManager.requestFocusApplication(appId) | 66 | ApplicationManager.requestFocusApplication(appId) |
20 | 67 | } | 67 | } |
21 | 68 | onApplicationRemoved: { | ||
22 | 69 | if (priv.foregroundMaximizedAppId === appId) { | ||
23 | 70 | priv.foregroundMaximizedAppIdIndex = -1; | ||
24 | 71 | } | ||
25 | 72 | } | ||
26 | 68 | 73 | ||
27 | 69 | onFocusRequested: { | 74 | onFocusRequested: { |
28 | 70 | var appIndex = priv.indexOf(appId); | 75 | var appIndex = priv.indexOf(appId); |
29 | @@ -86,6 +91,17 @@ | |||
30 | 86 | var index = indexOf(focusedAppId); | 91 | var index = indexOf(focusedAppId); |
31 | 87 | return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null | 92 | return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null |
32 | 88 | } | 93 | } |
33 | 94 | readonly property string foregroundMaximizedAppId: { | ||
34 | 95 | if (foregroundMaximizedAppIdIndex == -1) { | ||
35 | 96 | return ""; | ||
36 | 97 | } | ||
37 | 98 | var app = ApplicationManager.get(foregroundMaximizedAppIdIndex); | ||
38 | 99 | if (app) { | ||
39 | 100 | return app.appId; | ||
40 | 101 | } | ||
41 | 102 | return ""; | ||
42 | 103 | } | ||
43 | 104 | property int foregroundMaximizedAppIdIndex: -1 | ||
44 | 89 | 105 | ||
45 | 90 | function indexOf(appId) { | 106 | function indexOf(appId) { |
46 | 91 | for (var i = 0; i < ApplicationManager.count; i++) { | 107 | for (var i = 0; i < ApplicationManager.count; i++) { |
47 | @@ -132,6 +148,7 @@ | |||
48 | 132 | 148 | ||
49 | 133 | delegate: FocusScope { | 149 | delegate: FocusScope { |
50 | 134 | id: appDelegate | 150 | id: appDelegate |
51 | 151 | objectName: "stageDelegate_" + model.appId | ||
52 | 135 | z: ApplicationManager.count - index | 152 | z: ApplicationManager.count - index |
53 | 136 | y: units.gu(3) | 153 | y: units.gu(3) |
54 | 137 | width: units.gu(60) | 154 | width: units.gu(60) |
55 | @@ -141,12 +158,47 @@ | |||
56 | 141 | property bool maximized: false | 158 | property bool maximized: false |
57 | 142 | property bool minimized: false | 159 | property bool minimized: false |
58 | 143 | 160 | ||
59 | 161 | property bool visuallyMaximized: false | ||
60 | 162 | property bool visuallyMinimized: false | ||
61 | 163 | |||
62 | 144 | onFocusChanged: { | 164 | onFocusChanged: { |
63 | 145 | if (focus && ApplicationManager.focusedApplicationId !== model.appId) { | 165 | if (focus && ApplicationManager.focusedApplicationId !== model.appId) { |
64 | 146 | ApplicationManager.focusApplication(model.appId); | 166 | ApplicationManager.focusApplication(model.appId); |
65 | 147 | } | 167 | } |
66 | 148 | } | 168 | } |
67 | 149 | 169 | ||
68 | 170 | onZChanged: updateMaximized() | ||
69 | 171 | onVisuallyMaximizedChanged: updateMaximized() | ||
70 | 172 | Connections { | ||
71 | 173 | target: priv | ||
72 | 174 | onForegroundMaximizedAppIdIndexChanged: updateMaximized() | ||
73 | 175 | } | ||
74 | 176 | |||
75 | 177 | property bool connectMaxEnabled: true | ||
76 | 178 | function updateMaximized() { | ||
77 | 179 | if (!connectMaxEnabled) return; | ||
78 | 180 | connectMaxEnabled = false; | ||
79 | 181 | |||
80 | 182 | // work out if this is the top maximized app. | ||
81 | 183 | if (visuallyMaximized) { | ||
82 | 184 | if (priv.foregroundMaximizedAppId === model.appId) { | ||
83 | 185 | priv.foregroundMaximizedAppIdIndex = index; | ||
84 | 186 | } | ||
85 | 187 | else if (priv.foregroundMaximizedAppIdIndex == -1 || | ||
86 | 188 | (index >= 0 && index <= priv.foregroundMaximizedAppIdIndex)) { | ||
87 | 189 | priv.foregroundMaximizedAppIdIndex = index; | ||
88 | 190 | } | ||
89 | 191 | } else if (priv.foregroundMaximizedAppId === model.appId) { | ||
90 | 192 | priv.foregroundMaximizedAppIdIndex = -1; | ||
91 | 193 | } | ||
92 | 194 | |||
93 | 195 | connectMaxEnabled = true; | ||
94 | 196 | } | ||
95 | 197 | |||
96 | 198 | visible: !visuallyMinimized && | ||
97 | 199 | (priv.foregroundMaximizedAppIdIndex === -1 || priv.foregroundMaximizedAppIdIndex >= index) || | ||
98 | 200 | (spread.focus && index === spread.highlightedIndex) | ||
99 | 201 | |||
100 | 150 | Binding { | 202 | Binding { |
101 | 151 | target: ApplicationManager.get(index) | 203 | target: ApplicationManager.get(index) |
102 | 152 | property: "requestedState" | 204 | property: "requestedState" |
103 | @@ -186,9 +238,25 @@ | |||
104 | 186 | ] | 238 | ] |
105 | 187 | transitions: [ | 239 | transitions: [ |
106 | 188 | Transition { | 240 | Transition { |
110 | 189 | from: "maximized,minimized,normal," | 241 | to: "normal" |
111 | 190 | to: "maximized,minimized,normal," | 242 | PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized"; value: false } |
112 | 191 | PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale" } | 243 | PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale," } |
113 | 244 | }, | ||
114 | 245 | Transition { | ||
115 | 246 | to: "maximized" | ||
116 | 247 | SequentialAnimation { | ||
117 | 248 | PropertyAction { target: appDelegate; property: "visuallyMinimized"; value: false } | ||
118 | 249 | PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale" } | ||
119 | 250 | PropertyAction { target: appDelegate; property: "visuallyMaximized"; value: true } | ||
120 | 251 | } | ||
121 | 252 | }, | ||
122 | 253 | Transition { | ||
123 | 254 | to: "minimized" | ||
124 | 255 | SequentialAnimation { | ||
125 | 256 | PropertyAction { target: appDelegate; property: "visuallyMaximized"; value: false } | ||
126 | 257 | PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale" } | ||
127 | 258 | PropertyAction { target: appDelegate; property: "visuallyMinimized"; value: true } | ||
128 | 259 | } | ||
129 | 192 | }, | 260 | }, |
130 | 193 | Transition { | 261 | Transition { |
131 | 194 | from: "" | 262 | from: "" |
132 | 195 | 263 | ||
133 | === modified file 'qml/Stages/PhoneStage.qml' | |||
134 | --- qml/Stages/PhoneStage.qml 2015-09-21 13:37:47 +0000 | |||
135 | +++ qml/Stages/PhoneStage.qml 2015-10-26 18:36:26 +0000 | |||
136 | @@ -20,6 +20,7 @@ | |||
137 | 20 | import Unity.Application 0.1 | 20 | import Unity.Application 0.1 |
138 | 21 | import Unity.Session 0.1 | 21 | import Unity.Session 0.1 |
139 | 22 | import Utils 0.1 | 22 | import Utils 0.1 |
140 | 23 | import Powerd 0.1 | ||
141 | 23 | import "../Components" | 24 | import "../Components" |
142 | 24 | 25 | ||
143 | 25 | Rectangle { | 26 | Rectangle { |
144 | @@ -531,9 +532,15 @@ | |||
145 | 531 | return progress; | 532 | return progress; |
146 | 532 | } | 533 | } |
147 | 533 | 534 | ||
151 | 534 | // Hiding tiles when their progress is negative or reached the maximum | 535 | // Hide tile when progress is such that it will be off screen. |
152 | 535 | visible: (progress >= 0 && progress < 1.7) | 536 | property bool occluded: { |
153 | 536 | || (isDash && priv.focusedAppDelegateIsDislocated) | 537 | if (spreadView.active && (progress >= 0 && progress < 1.7)) return false; |
154 | 538 | if (!spreadView.active && isFocused) return false; | ||
155 | 539 | return true; | ||
156 | 540 | } | ||
157 | 541 | |||
158 | 542 | visible: Powerd.status == Powerd.On && | ||
159 | 543 | (!occluded || (isDash && priv.focusedAppDelegateIsDislocated)) | ||
160 | 537 | 544 | ||
161 | 538 | 545 | ||
162 | 539 | shellOrientationAngle: root.shellOrientationAngle | 546 | shellOrientationAngle: root.shellOrientationAngle |
163 | 540 | 547 | ||
164 | === modified file 'qml/Stages/TabletStage.qml' | |||
165 | --- qml/Stages/TabletStage.qml 2015-08-03 13:47:44 +0000 | |||
166 | +++ qml/Stages/TabletStage.qml 2015-10-26 18:36:26 +0000 | |||
167 | @@ -676,6 +676,14 @@ | |||
168 | 676 | return tileProgress; | 676 | return tileProgress; |
169 | 677 | } | 677 | } |
170 | 678 | 678 | ||
171 | 679 | // TODO: Hiding tile when progress is such that it will be off screen. | ||
172 | 680 | property bool occluded: { | ||
173 | 681 | if (spreadView.active) return false; | ||
174 | 682 | else if (isFocused) return false; | ||
175 | 683 | return true; | ||
176 | 684 | } | ||
177 | 685 | visible: !occluded | ||
178 | 686 | |||
179 | 679 | animatedProgress: { | 687 | animatedProgress: { |
180 | 680 | if (spreadView.phase == 0 && (spreadTile.active || spreadView.nextInStack == index)) { | 688 | if (spreadView.phase == 0 && (spreadTile.active || spreadView.nextInStack == index)) { |
181 | 681 | if (progress < spreadView.positionMarker1) { | 689 | if (progress < spreadView.positionMarker1) { |
182 | 682 | 690 | ||
183 | === modified file 'tests/mocks/Unity/Application/MirSurface.cpp' | |||
184 | --- tests/mocks/Unity/Application/MirSurface.cpp 2015-09-25 12:13:13 +0000 | |||
185 | +++ tests/mocks/Unity/Application/MirSurface.cpp 2015-10-26 18:36:26 +0000 | |||
186 | @@ -31,7 +31,7 @@ | |||
187 | 31 | , m_screenshotUrl(screenshot) | 31 | , m_screenshotUrl(screenshot) |
188 | 32 | , m_qmlFilePath(qmlFilePath) | 32 | , m_qmlFilePath(qmlFilePath) |
189 | 33 | , m_live(true) | 33 | , m_live(true) |
191 | 34 | , m_viewCount(0) | 34 | , m_visible(true) |
192 | 35 | , m_activeFocus(false) | 35 | , m_activeFocus(false) |
193 | 36 | , m_width(-1) | 36 | , m_width(-1) |
194 | 37 | , m_height(-1) | 37 | , m_height(-1) |
195 | @@ -73,6 +73,11 @@ | |||
196 | 73 | return m_live; | 73 | return m_live; |
197 | 74 | } | 74 | } |
198 | 75 | 75 | ||
199 | 76 | bool MirSurface::visible() const | ||
200 | 77 | { | ||
201 | 78 | return m_visible; | ||
202 | 79 | } | ||
203 | 80 | |||
204 | 76 | void MirSurface::setLive(bool live) | 81 | void MirSurface::setLive(bool live) |
205 | 77 | { | 82 | { |
206 | 78 | // qDebug().nospace() << "MirSurface::setLive("<<live<<") " << name(); | 83 | // qDebug().nospace() << "MirSurface::setLive("<<live<<") " << name(); |
207 | @@ -82,7 +87,7 @@ | |||
208 | 82 | m_live = live; | 87 | m_live = live; |
209 | 83 | Q_EMIT liveChanged(live); | 88 | Q_EMIT liveChanged(live); |
210 | 84 | 89 | ||
212 | 85 | if (!m_live && m_viewCount == 0) { | 90 | if (!m_live && m_views.count() == 0) { |
213 | 86 | deleteLater(); | 91 | deleteLater(); |
214 | 87 | } | 92 | } |
215 | 88 | } | 93 | } |
216 | @@ -120,27 +125,49 @@ | |||
217 | 120 | Q_EMIT orientationAngleChanged(angle); | 125 | Q_EMIT orientationAngleChanged(angle); |
218 | 121 | } | 126 | } |
219 | 122 | 127 | ||
221 | 123 | void MirSurface::incrementViewCount() | 128 | |
222 | 129 | |||
223 | 130 | void MirSurface::registerView(qintptr viewId) | ||
224 | 124 | { | 131 | { |
227 | 125 | ++m_viewCount; | 132 | m_views.insert(viewId, MirSurface::View{false}); |
228 | 126 | // qDebug().nospace() << "MirSurface::incrementViewCount() viewCount(after)=" << m_viewCount << " " << name(); | 133 | // qDebug().nospace() << "MirSurface[" << name() << "]::registerView(" << viewId << ")" |
229 | 134 | // << " after=" << m_views.count(); | ||
230 | 127 | } | 135 | } |
231 | 128 | 136 | ||
233 | 129 | void MirSurface::decrementViewCount() | 137 | void MirSurface::unregisterView(qintptr viewId) |
234 | 130 | { | 138 | { |
241 | 131 | --m_viewCount; | 139 | // qDebug().nospace() << "MirSurface[" << name() << "]::unregisterView(" << viewId << ")" |
242 | 132 | // qDebug().nospace() << "MirSurface::decrementViewCount() viewCount(after)=" << m_viewCount << " " << name(); | 140 | // << " after=" << m_views.count() << " live=" << m_live; |
243 | 133 | 141 | m_views.remove(viewId); | |
244 | 134 | Q_ASSERT(m_viewCount >= 0); | 142 | if (!m_live && m_views.count() == 0) { |
239 | 135 | |||
240 | 136 | if (!m_live && m_viewCount == 0) { | ||
245 | 137 | deleteLater(); | 143 | deleteLater(); |
246 | 138 | } | 144 | } |
252 | 139 | } | 145 | updateVisibility(); |
253 | 140 | 146 | } | |
254 | 141 | int MirSurface::viewCount() const | 147 | |
255 | 142 | { | 148 | void MirSurface::setViewVisibility(qintptr viewId, bool visible) |
256 | 143 | return m_viewCount; | 149 | { |
257 | 150 | if (!m_views.contains(viewId)) return; | ||
258 | 151 | |||
259 | 152 | m_views[viewId].visible = visible; | ||
260 | 153 | updateVisibility(); | ||
261 | 154 | } | ||
262 | 155 | |||
263 | 156 | void MirSurface::updateVisibility() | ||
264 | 157 | { | ||
265 | 158 | bool newVisible = false; | ||
266 | 159 | QHashIterator<qintptr, View> i(m_views); | ||
267 | 160 | while (i.hasNext()) { | ||
268 | 161 | i.next(); | ||
269 | 162 | newVisible |= i.value().visible; | ||
270 | 163 | } | ||
271 | 164 | |||
272 | 165 | if (newVisible != visible()) { | ||
273 | 166 | // qDebug().nospace() << "MirSurface[" << name() << "]::updateVisibility(" << newVisible << ")"; | ||
274 | 167 | |||
275 | 168 | m_visible = newVisible; | ||
276 | 169 | Q_EMIT visibleChanged(m_visible); | ||
277 | 170 | } | ||
278 | 144 | } | 171 | } |
279 | 145 | 172 | ||
280 | 146 | bool MirSurface::activeFocus() const | 173 | bool MirSurface::activeFocus() const |
281 | 147 | 174 | ||
282 | === modified file 'tests/mocks/Unity/Application/MirSurface.h' | |||
283 | --- tests/mocks/Unity/Application/MirSurface.h 2015-09-02 10:35:16 +0000 | |||
284 | +++ tests/mocks/Unity/Application/MirSurface.h 2015-10-26 18:36:26 +0000 | |||
285 | @@ -19,6 +19,7 @@ | |||
286 | 19 | 19 | ||
287 | 20 | #include <QObject> | 20 | #include <QObject> |
288 | 21 | #include <QUrl> | 21 | #include <QUrl> |
289 | 22 | #include <QHash> | ||
290 | 22 | 23 | ||
291 | 23 | // unity-api | 24 | // unity-api |
292 | 24 | #include <unity/shell/application/MirSurfaceInterface.h> | 25 | #include <unity/shell/application/MirSurfaceInterface.h> |
293 | @@ -58,6 +59,8 @@ | |||
294 | 58 | 59 | ||
295 | 59 | bool live() const override; | 60 | bool live() const override; |
296 | 60 | 61 | ||
297 | 62 | bool visible() const override; | ||
298 | 63 | |||
299 | 61 | Mir::OrientationAngle orientationAngle() const override; | 64 | Mir::OrientationAngle orientationAngle() const override; |
300 | 62 | void setOrientationAngle(Mir::OrientationAngle) override; | 65 | void setOrientationAngle(Mir::OrientationAngle) override; |
301 | 63 | 66 | ||
302 | @@ -66,9 +69,10 @@ | |||
303 | 66 | 69 | ||
304 | 67 | Q_INVOKABLE void setLive(bool live); | 70 | Q_INVOKABLE void setLive(bool live); |
305 | 68 | 71 | ||
309 | 69 | void incrementViewCount(); | 72 | void registerView(qintptr viewId); |
310 | 70 | void decrementViewCount(); | 73 | void unregisterView(qintptr viewId); |
311 | 71 | int viewCount() const; | 74 | void setViewVisibility(qintptr viewId, bool visible); |
312 | 75 | int viewCount() const { return m_views.count(); } | ||
313 | 72 | 76 | ||
314 | 73 | int width() const; | 77 | int width() const; |
315 | 74 | int height() const; | 78 | int height() const; |
316 | @@ -97,6 +101,8 @@ | |||
317 | 97 | void activeFocusChanged(bool); | 101 | void activeFocusChanged(bool); |
318 | 98 | 102 | ||
319 | 99 | private: | 103 | private: |
320 | 104 | void updateVisibility(); | ||
321 | 105 | |||
322 | 100 | const QString m_name; | 106 | const QString m_name; |
323 | 101 | const Mir::Type m_type; | 107 | const Mir::Type m_type; |
324 | 102 | Mir::State m_state; | 108 | Mir::State m_state; |
325 | @@ -104,10 +110,14 @@ | |||
326 | 104 | QUrl m_screenshotUrl; | 110 | QUrl m_screenshotUrl; |
327 | 105 | QUrl m_qmlFilePath; | 111 | QUrl m_qmlFilePath; |
328 | 106 | bool m_live; | 112 | bool m_live; |
330 | 107 | int m_viewCount; | 113 | bool m_visible; |
331 | 108 | bool m_activeFocus; | 114 | bool m_activeFocus; |
332 | 109 | int m_width; | 115 | int m_width; |
333 | 110 | int m_height; | 116 | int m_height; |
334 | 117 | struct View { | ||
335 | 118 | bool visible; | ||
336 | 119 | }; | ||
337 | 120 | QHash<qintptr, View> m_views; | ||
338 | 111 | }; | 121 | }; |
339 | 112 | 122 | ||
340 | 113 | #endif // MOCK_MIR_SURFACE_H | 123 | #endif // MOCK_MIR_SURFACE_H |
341 | 114 | 124 | ||
342 | === modified file 'tests/mocks/Unity/Application/MirSurfaceItem.cpp' | |||
343 | --- tests/mocks/Unity/Application/MirSurfaceItem.cpp 2015-09-25 12:13:13 +0000 | |||
344 | +++ tests/mocks/Unity/Application/MirSurfaceItem.cpp 2015-10-26 18:36:26 +0000 | |||
345 | @@ -44,6 +44,8 @@ | |||
346 | 44 | Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 | | 44 | Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 | |
347 | 45 | Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 | | 45 | Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 | |
348 | 46 | Qt::ExtraButton12 | Qt::ExtraButton13); | 46 | Qt::ExtraButton12 | Qt::ExtraButton13); |
349 | 47 | |||
350 | 48 | connect(this, &QQuickItem::visibleChanged, this, &MirSurfaceItem::updateMirSurfaceVisibility); | ||
351 | 47 | } | 49 | } |
352 | 48 | 50 | ||
353 | 49 | MirSurfaceItem::~MirSurfaceItem() | 51 | MirSurfaceItem::~MirSurfaceItem() |
354 | @@ -194,17 +196,18 @@ | |||
355 | 194 | m_qmlContentComponent = nullptr; | 196 | m_qmlContentComponent = nullptr; |
356 | 195 | 197 | ||
357 | 196 | disconnect(m_qmlSurface, nullptr, this, nullptr); | 198 | disconnect(m_qmlSurface, nullptr, this, nullptr); |
359 | 197 | m_qmlSurface->decrementViewCount(); | 199 | m_qmlSurface->unregisterView((qintptr)this); |
360 | 198 | } | 200 | } |
361 | 199 | 201 | ||
362 | 200 | m_qmlSurface = static_cast<MirSurface*>(surface); | 202 | m_qmlSurface = static_cast<MirSurface*>(surface); |
363 | 201 | 203 | ||
364 | 202 | if (m_qmlSurface) { | 204 | if (m_qmlSurface) { |
366 | 203 | m_qmlSurface->incrementViewCount(); | 205 | m_qmlSurface->registerView((qintptr)this); |
367 | 204 | 206 | ||
368 | 205 | m_qmlSurface->setActiveFocus(hasActiveFocus()); | 207 | m_qmlSurface->setActiveFocus(hasActiveFocus()); |
369 | 206 | 208 | ||
370 | 207 | updateSurfaceSize(); | 209 | updateSurfaceSize(); |
371 | 210 | updateMirSurfaceVisibility(); | ||
372 | 208 | 211 | ||
373 | 209 | connect(m_qmlSurface, &MirSurface::orientationAngleChanged, this, &MirSurfaceItem::orientationAngleChanged); | 212 | connect(m_qmlSurface, &MirSurface::orientationAngleChanged, this, &MirSurfaceItem::orientationAngleChanged); |
374 | 210 | connect(m_qmlSurface, &MirSurface::screenshotUrlChanged, this, &MirSurfaceItem::updateScreenshot); | 213 | connect(m_qmlSurface, &MirSurface::screenshotUrlChanged, this, &MirSurfaceItem::updateScreenshot); |
375 | @@ -253,6 +256,13 @@ | |||
376 | 253 | } | 256 | } |
377 | 254 | } | 257 | } |
378 | 255 | 258 | ||
379 | 259 | void MirSurfaceItem::updateMirSurfaceVisibility() | ||
380 | 260 | { | ||
381 | 261 | if (!m_qmlSurface) return; | ||
382 | 262 | |||
383 | 263 | m_qmlSurface->setViewVisibility((qintptr)this, isVisible()); | ||
384 | 264 | } | ||
385 | 265 | |||
386 | 256 | void MirSurfaceItem::setConsumesInput(bool value) | 266 | void MirSurfaceItem::setConsumesInput(bool value) |
387 | 257 | { | 267 | { |
388 | 258 | if (m_consumesInput != value) { | 268 | if (m_consumesInput != value) { |
389 | 259 | 269 | ||
390 | === modified file 'tests/mocks/Unity/Application/MirSurfaceItem.h' | |||
391 | --- tests/mocks/Unity/Application/MirSurfaceItem.h 2015-09-19 07:37:52 +0000 | |||
392 | +++ tests/mocks/Unity/Application/MirSurfaceItem.h 2015-10-26 18:36:26 +0000 | |||
393 | @@ -87,6 +87,7 @@ | |||
394 | 87 | private Q_SLOTS: | 87 | private Q_SLOTS: |
395 | 88 | void onComponentStatusChanged(QQmlComponent::Status status); | 88 | void onComponentStatusChanged(QQmlComponent::Status status); |
396 | 89 | void updateScreenshot(QUrl screenshot); | 89 | void updateScreenshot(QUrl screenshot); |
397 | 90 | void updateMirSurfaceVisibility(); | ||
398 | 90 | 91 | ||
399 | 91 | private: | 92 | private: |
400 | 92 | void createQmlContentItem(); | 93 | void createQmlContentItem(); |
401 | 93 | 94 | ||
402 | === modified file 'tests/qmltests/Stages/tst_DesktopStage.qml' | |||
403 | --- tests/qmltests/Stages/tst_DesktopStage.qml 2015-09-17 12:25:29 +0000 | |||
404 | +++ tests/qmltests/Stages/tst_DesktopStage.qml 2015-10-26 18:36:26 +0000 | |||
405 | @@ -35,12 +35,15 @@ | |||
406 | 35 | value: false | 35 | value: false |
407 | 36 | } | 36 | } |
408 | 37 | 37 | ||
410 | 38 | Component.onCompleted: { | 38 | Component.onCompleted: resetGeometry() |
411 | 39 | |||
412 | 40 | function resetGeometry() { | ||
413 | 39 | // ensures apps which are tested decorations are in view. | 41 | // ensures apps which are tested decorations are in view. |
414 | 40 | WindowStateStorage.geometry = { | 42 | WindowStateStorage.geometry = { |
415 | 41 | 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)), | 43 | 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)), |
416 | 42 | 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)), | 44 | 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)), |
417 | 43 | 'camera-app': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)), | 45 | 'camera-app': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)), |
418 | 46 | 'gallery-app': Qt.rect(units.gu(51), units.gu(44), units.gu(50), units.gu(40)) | ||
419 | 44 | } | 47 | } |
420 | 45 | } | 48 | } |
421 | 46 | 49 | ||
422 | @@ -110,14 +113,14 @@ | |||
423 | 110 | 113 | ||
424 | 111 | desktopStageLoader.active = true; | 114 | desktopStageLoader.active = true; |
425 | 112 | tryCompare(desktopStageLoader, "status", Loader.Ready); | 115 | tryCompare(desktopStageLoader, "status", Loader.Ready); |
426 | 116 | root.resetGeometry(); | ||
427 | 113 | } | 117 | } |
428 | 114 | 118 | ||
429 | 115 | function killAllRunningApps() { | 119 | function killAllRunningApps() { |
433 | 116 | while (ApplicationManager.count > 1) { | 120 | while (ApplicationManager.count > 0) { |
434 | 117 | var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0 | 121 | ApplicationManager.stopApplication(ApplicationManager.get(0).appId); |
432 | 118 | ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId); | ||
435 | 119 | } | 122 | } |
437 | 120 | compare(ApplicationManager.count, 1) | 123 | compare(ApplicationManager.count, 0) |
438 | 121 | } | 124 | } |
439 | 122 | 125 | ||
440 | 123 | function waitUntilAppSurfaceShowsUp(appId) { | 126 | function waitUntilAppSurfaceShowsUp(appId) { |
441 | @@ -210,5 +213,69 @@ | |||
442 | 210 | tap(toAppDecoration); | 213 | tap(toAppDecoration); |
443 | 211 | tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true); | 214 | tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true); |
444 | 212 | } | 215 | } |
445 | 216 | |||
446 | 217 | function test_minimizeApplicationHidesSurface(data) { | ||
447 | 218 | var dashApp = startApplication("unity8-dash"); | ||
448 | 219 | |||
449 | 220 | var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash"); | ||
450 | 221 | verify(dashDelegate); | ||
451 | 222 | |||
452 | 223 | dashDelegate.minimize(); | ||
453 | 224 | tryCompare(dashApp.session.surface, "visible", false); | ||
454 | 225 | } | ||
455 | 226 | |||
456 | 227 | function test_maximizeApplicationHidesSurfacesBehindIt(data) { | ||
457 | 228 | var dashApp = startApplication("unity8-dash"); | ||
458 | 229 | var dialerApp = startApplication("dialer-app"); | ||
459 | 230 | var cameraApp = startApplication("camera-app"); | ||
460 | 231 | |||
461 | 232 | var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash"); | ||
462 | 233 | verify(dashDelegate); | ||
463 | 234 | var dialerDelegate = findChild(desktopStage, "stageDelegate_dialer-app"); | ||
464 | 235 | verify(dialerDelegate); | ||
465 | 236 | var cameraDelegate = findChild(desktopStage, "stageDelegate_camera-app"); | ||
466 | 237 | verify(cameraDelegate); | ||
467 | 238 | |||
468 | 239 | dialerDelegate.maximize(); | ||
469 | 240 | tryCompare(dialerDelegate, "visuallyMaximized", true); | ||
470 | 241 | |||
471 | 242 | tryCompare(dashApp.session.surface, "visible", false); | ||
472 | 243 | compare(cameraApp.session.surface.visible, true); | ||
473 | 244 | |||
474 | 245 | dialerDelegate.unmaximize(); | ||
475 | 246 | compare(dashApp.session.surface.visible, true); | ||
476 | 247 | compare(cameraApp.session.surface.visible, true); | ||
477 | 248 | } | ||
478 | 249 | |||
479 | 250 | function test_applicationsBecomeVisibleWhenOccludingAppRemoved(data) { | ||
480 | 251 | var dashApp = startApplication("unity8-dash"); | ||
481 | 252 | var dialerApp = startApplication("dialer-app"); | ||
482 | 253 | var cameraApp = startApplication("camera-app"); | ||
483 | 254 | var galleryApp = startApplication("gallery-app"); | ||
484 | 255 | |||
485 | 256 | var dashDelegate = findChild(desktopStage, "stageDelegate_unity8-dash"); | ||
486 | 257 | verify(dashDelegate); | ||
487 | 258 | var dialerDelegate = findChild(desktopStage, "stageDelegate_dialer-app"); | ||
488 | 259 | verify(dialerDelegate); | ||
489 | 260 | var cameraDelegate = findChild(desktopStage, "stageDelegate_camera-app"); | ||
490 | 261 | verify(cameraDelegate); | ||
491 | 262 | var galleryDelegate = findChild(desktopStage, "stageDelegate_gallery-app"); | ||
492 | 263 | verify(galleryDelegate); | ||
493 | 264 | |||
494 | 265 | dialerDelegate.maximize(); | ||
495 | 266 | galleryDelegate.maximize(); | ||
496 | 267 | tryCompare(dialerDelegate, "visuallyMaximized", true); | ||
497 | 268 | tryCompare(galleryDelegate, "visuallyMaximized", true); | ||
498 | 269 | |||
499 | 270 | tryCompare(dashApp.session.surface, "visible", false); | ||
500 | 271 | tryCompare(dialerApp.session.surface, "visible", false); | ||
501 | 272 | tryCompare(cameraApp.session.surface, "visible", false); | ||
502 | 273 | |||
503 | 274 | ApplicationManager.stopApplication("gallery-app"); | ||
504 | 275 | |||
505 | 276 | compare(cameraApp.session.surface.visible, true); | ||
506 | 277 | tryCompare(dialerApp.session.surface, "visible", true); | ||
507 | 278 | tryCompare(dashApp.session.surface, "visible", false); // still occluded by maximised dialer | ||
508 | 279 | } | ||
509 | 213 | } | 280 | } |
510 | 214 | } | 281 | } |
FAILED: Continuous integration, rev:1972 jenkins. qa.ubuntu. com/job/ unity8- ci/6421/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 4503/console jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- wily-touch/ 800/console jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- vivid/1133/ console jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- wily/452/ console jenkins. qa.ubuntu. com/job/ unity8- vivid-amd64- ci/1028/ console jenkins. qa.ubuntu. com/job/ unity8- vivid-i386- ci/1029/ console jenkins. qa.ubuntu. com/job/ unity8- wily-amd64- ci/660/ console jenkins. qa.ubuntu. com/job/ unity8- wily-i386- ci/661/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 4500/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- wily-armhf/ 800/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/6421/ rebuild
http://