Merge lp:~mzanetti/unity8/alerting-pips into lp:unity8
- alerting-pips
- Merge into trunk
Status: | Superseded | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~mzanetti/unity8/alerting-pips | ||||||||||||
Merge into: | lp:unity8 | ||||||||||||
Diff against target: |
1121 lines (+207/-277) 26 files modified
CMakeLists.txt (+1/-1) debian/control (+1/-1) plugins/Greeter/Unity/Launcher/CMakeLists.txt (+1/-1) plugins/Greeter/Unity/Launcher/launcheritem.cpp (+14/-0) plugins/Greeter/Unity/Launcher/launcheritem.h (+3/-1) plugins/Greeter/Unity/Launcher/launchermodelas.cpp (+2/-7) plugins/Greeter/Unity/Launcher/launchermodelas.h (+0/-1) plugins/Unity/Launcher/CMakeLists.txt (+3/-1) plugins/Unity/Launcher/Launcher.qmltypes (+0/-182) plugins/Unity/Launcher/launcheritem.cpp (+14/-9) plugins/Unity/Launcher/launcheritem.h (+3/-0) plugins/Unity/Launcher/launchermodel.cpp (+45/-21) plugins/Unity/Launcher/launchermodel.h (+1/-1) qml/Launcher/LauncherDelegate.qml (+8/-8) qml/Launcher/LauncherPanel.qml (+11/-0) tests/mocks/Unity/Application/ApplicationInfo.cpp (+26/-25) tests/mocks/Unity/Application/ApplicationInfo.h (+3/-2) tests/mocks/Unity/Application/MirSurfaceListModel.cpp (+2/-2) tests/mocks/Unity/Launcher/CMakeLists.txt (+1/-1) tests/mocks/Unity/Launcher/MockLauncherItem.cpp (+16/-0) tests/mocks/Unity/Launcher/MockLauncherItem.h (+3/-0) tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+5/-0) tests/mocks/Unity/Launcher/MockLauncherModel.h (+1/-1) tests/plugins/Unity/Launcher/CMakeLists.txt (+1/-1) tests/plugins/Unity/Launcher/launchermodeltest.cpp (+13/-1) tests/qmltests/Launcher/tst_Launcher.qml (+29/-10) |
||||||||||||
To merge this branch: | bzr merge lp:~mzanetti/unity8/alerting-pips | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Needs Fixing | |
Ubuntu Unity PS integration team | Pending | ||
Unity Team | Pending | ||
Review via email: mp+294627@code.launchpad.net |
This proposal has been superseded by a proposal from 2016-05-13.
Commit message
Add support for the persistent alert state.
Paint pips blue when an app is in alert state
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
yes, listing them in a minute
* Did you perform an exploratory manual test run of your code change and any related functionality?
yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
yes
* If you changed the UI, has there been a design review?
yes, change requested by design. This reveals an issue in the design spec. Here's my conversation with John:
<mzanetti> I have a small issue with the persistent alert state
we are currently coloring pips blue. Problem is, if the app is not running and the alert happened because of a push notification, there is no pip which could be blue
the count emblem will still be there though
<JohnLea> humm, yes this is a small problem
I think it is ok for the moment, but a better solution could be to use something else as the persistent alert notification
<mzanetti> you tell me: a) ignore the problem or b) force a pip even if no surface
<JohnLea> for now do a)
<mzanetti> ack
<JohnLea> in the mean time I'll speak to Matthieu and ask him to have a look at other options, perhaps indicating something on the app icon itself
but that's for the future
Michael Zanetti (mzanetti) wrote : | # |
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2400
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 2401. By Michael Zanetti
-
cleanup
- 2402. By Michael Zanetti
-
fixes
- 2403. By Michael Zanetti
-
fixes
- 2404. By Michael Zanetti
-
fix tests
- 2405. By Michael Zanetti
-
fix usage of color vs palette
- 2406. By Michael Zanetti
-
test if the alert is properly cleared on focus
- 2407. By Michael Zanetti
-
merge prereq
- 2408. By Michael Zanetti
-
merge prereq, bump unity-api version requirement
- 2409. By Michael Zanetti
-
bump package requirement once more
- 2410. By Michael Zanetti
-
that wasn't necessary
- 2411. By Michael Zanetti
-
merge prereq
- 2412. By Michael Zanetti
-
merge prereq
Unmerged revisions
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2016-04-27 15:01:10 +0000 |
3 | +++ CMakeLists.txt 2016-05-13 11:17:06 +0000 |
4 | @@ -57,7 +57,7 @@ |
5 | find_package(Qt5Concurrent 5.4 REQUIRED) |
6 | find_package(Qt5Sql 5.4 REQUIRED) |
7 | |
8 | -pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=15) |
9 | +pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=16) |
10 | pkg_check_modules(GEONAMES REQUIRED geonames>=0.2) |
11 | pkg_check_modules(GIO REQUIRED gio-2.0>=2.32) |
12 | pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32) |
13 | |
14 | === modified file 'debian/control' |
15 | --- debian/control 2016-05-04 18:09:25 +0000 |
16 | +++ debian/control 2016-05-13 11:17:06 +0000 |
17 | @@ -30,7 +30,7 @@ |
18 | libqt5xmlpatterns5-dev, |
19 | libsystemsettings-dev, |
20 | libudev-dev, |
21 | - libunity-api-dev (>= 7.111), |
22 | + libunity-api-dev (>= 7.112), |
23 | libusermetricsoutput1-dev, |
24 | # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop |
25 | libx11-dev[!armhf], |
26 | |
27 | === modified file 'plugins/Greeter/Unity/Launcher/CMakeLists.txt' |
28 | --- plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-08-03 13:47:44 +0000 |
29 | +++ plugins/Greeter/Unity/Launcher/CMakeLists.txt 2016-05-13 11:17:06 +0000 |
30 | @@ -1,4 +1,4 @@ |
31 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
32 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=9) |
33 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
34 | |
35 | add_definitions(-DSM_BUSNAME=systemBus) |
36 | |
37 | === modified file 'plugins/Greeter/Unity/Launcher/launcheritem.cpp' |
38 | --- plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-09-14 09:11:08 +0000 |
39 | +++ plugins/Greeter/Unity/Launcher/launcheritem.cpp 2016-05-13 11:17:06 +0000 |
40 | @@ -32,6 +32,7 @@ |
41 | m_countVisible(false), |
42 | m_focused(false), |
43 | m_alerting(false), |
44 | + m_surfaceCount(0), |
45 | m_quickList(new QuickListModel(this)) |
46 | { |
47 | QuickListEntry nameAction; |
48 | @@ -179,6 +180,19 @@ |
49 | } |
50 | } |
51 | |
52 | +int LauncherItem::surfaceCount() const |
53 | +{ |
54 | + return m_surfaceCount; |
55 | +} |
56 | + |
57 | +void LauncherItem::setSurfaceCount(int surfaceCount) |
58 | +{ |
59 | + if (m_surfaceCount != surfaceCount) { |
60 | + m_surfaceCount = surfaceCount; |
61 | + Q_EMIT surfaceCountChanged(surfaceCount); |
62 | + } |
63 | +} |
64 | + |
65 | unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const |
66 | { |
67 | return m_quickList; |
68 | |
69 | === modified file 'plugins/Greeter/Unity/Launcher/launcheritem.h' |
70 | --- plugins/Greeter/Unity/Launcher/launcheritem.h 2015-06-02 13:50:46 +0000 |
71 | +++ plugins/Greeter/Unity/Launcher/launcheritem.h 2016-05-13 11:17:06 +0000 |
72 | @@ -42,6 +42,7 @@ |
73 | bool countVisible() const override; |
74 | bool focused() const override; |
75 | bool alerting() const override; |
76 | + int surfaceCount() const override; |
77 | |
78 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
79 | |
80 | @@ -56,7 +57,7 @@ |
81 | void setCountVisible(bool countVisible); |
82 | void setFocused(bool focused); |
83 | void setAlerting(bool alerting); |
84 | - |
85 | + void setSurfaceCount(int surfaceCount); |
86 | |
87 | private: |
88 | QString m_appId; |
89 | @@ -70,6 +71,7 @@ |
90 | bool m_countVisible; |
91 | bool m_focused; |
92 | bool m_alerting; |
93 | + int m_surfaceCount; |
94 | QuickListModel *m_quickList; |
95 | |
96 | friend class LauncherModel; |
97 | |
98 | === modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.cpp' |
99 | --- plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-10-26 14:05:14 +0000 |
100 | +++ plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2016-05-13 11:17:06 +0000 |
101 | @@ -69,18 +69,13 @@ |
102 | return item->focused(); |
103 | case RoleRunning: |
104 | return item->running(); |
105 | + case RoleSurfaceCount: |
106 | + return item->surfaceCount(); |
107 | } |
108 | |
109 | return QVariant(); |
110 | } |
111 | |
112 | -void LauncherModel::setAlerting(const QString &appId, bool alerting) |
113 | -{ |
114 | - Q_UNUSED(appId) |
115 | - Q_UNUSED(alerting) |
116 | - qWarning() << "This is a read only implementation. Cannot set alert-state of items."; |
117 | -} |
118 | - |
119 | unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const |
120 | { |
121 | if (index < 0 || index >= m_list.count()) { |
122 | |
123 | === modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.h' |
124 | --- plugins/Greeter/Unity/Launcher/launchermodelas.h 2015-10-26 14:05:14 +0000 |
125 | +++ plugins/Greeter/Unity/Launcher/launchermodelas.h 2016-05-13 11:17:06 +0000 |
126 | @@ -41,7 +41,6 @@ |
127 | |
128 | QVariant data(const QModelIndex &index, int role) const override; |
129 | |
130 | - Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override; |
131 | Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override; |
132 | Q_INVOKABLE void move(int oldIndex, int newIndex) override; |
133 | Q_INVOKABLE void pin(const QString &appId, int index = -1) override; |
134 | |
135 | === modified file 'plugins/Unity/Launcher/CMakeLists.txt' |
136 | --- plugins/Unity/Launcher/CMakeLists.txt 2016-04-19 20:36:29 +0000 |
137 | +++ plugins/Unity/Launcher/CMakeLists.txt 2016-05-13 11:17:06 +0000 |
138 | @@ -1,4 +1,4 @@ |
139 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
140 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=9) |
141 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
142 | |
143 | add_definitions(-DSM_BUSNAME=systemBus) |
144 | @@ -23,6 +23,8 @@ |
145 | asadapter.cpp |
146 | ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp |
147 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h |
148 | + ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h |
149 | + ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceListInterface.h |
150 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h |
151 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h |
152 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h |
153 | |
154 | === removed file 'plugins/Unity/Launcher/Launcher.qmltypes' |
155 | --- plugins/Unity/Launcher/Launcher.qmltypes 2015-02-13 09:01:16 +0000 |
156 | +++ plugins/Unity/Launcher/Launcher.qmltypes 1970-01-01 00:00:00 +0000 |
157 | @@ -1,182 +0,0 @@ |
158 | -import QtQuick.tooling 1.1 |
159 | - |
160 | -// This file describes the plugin-supplied types contained in the library. |
161 | -// It is used for QML tooling purposes only. |
162 | -// |
163 | -// This file was auto-generated by: |
164 | -// 'qmlplugindump -notrelocatable Unity.Launcher 0.1 plugins' |
165 | - |
166 | -Module { |
167 | - Component { |
168 | - name: "LauncherItem" |
169 | - prototype: "unity::shell::launcher::LauncherItemInterface" |
170 | - exports: ["Unity.Launcher/LauncherItem 0.1"] |
171 | - isCreatable: false |
172 | - exportMetaObjectRevisions: [0] |
173 | - } |
174 | - Component { |
175 | - name: "LauncherModel" |
176 | - prototype: "unity::shell::launcher::LauncherModelInterface" |
177 | - exports: ["Unity.Launcher/LauncherModel 0.1"] |
178 | - isCreatable: false |
179 | - isSingleton: true |
180 | - exportMetaObjectRevisions: [0] |
181 | - Method { |
182 | - name: "requestRemove" |
183 | - Parameter { name: "appId"; type: "string" } |
184 | - } |
185 | - Method { name: "refresh" } |
186 | - Method { |
187 | - name: "get" |
188 | - type: "unity::shell::launcher::LauncherItemInterface*" |
189 | - Parameter { name: "index"; type: "int" } |
190 | - } |
191 | - Method { |
192 | - name: "move" |
193 | - Parameter { name: "oldIndex"; type: "int" } |
194 | - Parameter { name: "newIndex"; type: "int" } |
195 | - } |
196 | - Method { |
197 | - name: "pin" |
198 | - Parameter { name: "appId"; type: "string" } |
199 | - Parameter { name: "index"; type: "int" } |
200 | - } |
201 | - Method { |
202 | - name: "pin" |
203 | - Parameter { name: "appId"; type: "string" } |
204 | - } |
205 | - Method { |
206 | - name: "quickListActionInvoked" |
207 | - Parameter { name: "appId"; type: "string" } |
208 | - Parameter { name: "actionIndex"; type: "int" } |
209 | - } |
210 | - Method { |
211 | - name: "setUser" |
212 | - Parameter { name: "username"; type: "string" } |
213 | - } |
214 | - Method { |
215 | - name: "getUrlForAppId" |
216 | - type: "string" |
217 | - Parameter { name: "appId"; type: "string" } |
218 | - } |
219 | - } |
220 | - Component { |
221 | - name: "QuickListModel" |
222 | - prototype: "unity::shell::launcher::QuickListModelInterface" |
223 | - exports: ["Unity.Launcher/QuickListModel 0.1"] |
224 | - isCreatable: false |
225 | - exportMetaObjectRevisions: [0] |
226 | - } |
227 | - Component { |
228 | - name: "unity::shell::launcher::LauncherItemInterface" |
229 | - prototype: "QObject" |
230 | - exports: ["Unity.Launcher/LauncherItemInterface 0.1"] |
231 | - isCreatable: false |
232 | - exportMetaObjectRevisions: [0] |
233 | - Property { name: "appId"; type: "string"; isReadonly: true } |
234 | - Property { name: "name"; type: "string"; isReadonly: true } |
235 | - Property { name: "icon"; type: "string"; isReadonly: true } |
236 | - Property { name: "pinned"; type: "bool"; isReadonly: true } |
237 | - Property { name: "running"; type: "bool"; isReadonly: true } |
238 | - Property { name: "recent"; type: "bool"; isReadonly: true } |
239 | - Property { name: "progress"; type: "int"; isReadonly: true } |
240 | - Property { name: "count"; type: "int"; isReadonly: true } |
241 | - Property { name: "countVisible"; type: "bool"; isReadonly: true } |
242 | - Property { name: "focused"; type: "bool"; isReadonly: true } |
243 | - Property { |
244 | - name: "quickList" |
245 | - type: "unity::shell::launcher::QuickListModelInterface" |
246 | - isReadonly: true |
247 | - isPointer: true |
248 | - } |
249 | - Signal { |
250 | - name: "nameChanged" |
251 | - Parameter { name: "name"; type: "string" } |
252 | - } |
253 | - Signal { |
254 | - name: "iconChanged" |
255 | - Parameter { name: "icon"; type: "string" } |
256 | - } |
257 | - Signal { |
258 | - name: "pinnedChanged" |
259 | - Parameter { name: "pinned"; type: "bool" } |
260 | - } |
261 | - Signal { |
262 | - name: "runningChanged" |
263 | - Parameter { name: "running"; type: "bool" } |
264 | - } |
265 | - Signal { |
266 | - name: "recentChanged" |
267 | - Parameter { name: "running"; type: "bool" } |
268 | - } |
269 | - Signal { |
270 | - name: "progressChanged" |
271 | - Parameter { name: "progress"; type: "int" } |
272 | - } |
273 | - Signal { |
274 | - name: "countChanged" |
275 | - Parameter { name: "count"; type: "int" } |
276 | - } |
277 | - Signal { |
278 | - name: "countVisibleChanged" |
279 | - Parameter { name: "countVisible"; type: "bool" } |
280 | - } |
281 | - Signal { |
282 | - name: "focusedChanged" |
283 | - Parameter { name: "focused"; type: "bool" } |
284 | - } |
285 | - } |
286 | - Component { |
287 | - name: "unity::shell::launcher::LauncherModelInterface" |
288 | - prototype: "QAbstractListModel" |
289 | - exports: ["Unity.Launcher/LauncherModelInterface 0.1"] |
290 | - isCreatable: false |
291 | - exportMetaObjectRevisions: [0] |
292 | - Property { |
293 | - name: "applicationManager" |
294 | - type: "unity::shell::application::ApplicationManagerInterface" |
295 | - isPointer: true |
296 | - } |
297 | - Property { name: "onlyPinned"; type: "bool" } |
298 | - Signal { name: "hint" } |
299 | - Method { |
300 | - name: "move" |
301 | - Parameter { name: "oldIndex"; type: "int" } |
302 | - Parameter { name: "newIndex"; type: "int" } |
303 | - } |
304 | - Method { |
305 | - name: "get" |
306 | - type: "unity::shell::launcher::LauncherItemInterface*" |
307 | - Parameter { name: "index"; type: "int" } |
308 | - } |
309 | - Method { |
310 | - name: "pin" |
311 | - Parameter { name: "appId"; type: "string" } |
312 | - Parameter { name: "index"; type: "int" } |
313 | - } |
314 | - Method { |
315 | - name: "pin" |
316 | - Parameter { name: "appId"; type: "string" } |
317 | - } |
318 | - Method { |
319 | - name: "requestRemove" |
320 | - Parameter { name: "appId"; type: "string" } |
321 | - } |
322 | - Method { |
323 | - name: "quickListActionInvoked" |
324 | - Parameter { name: "appId"; type: "string" } |
325 | - Parameter { name: "actionIndex"; type: "int" } |
326 | - } |
327 | - Method { |
328 | - name: "setUser" |
329 | - Parameter { name: "username"; type: "string" } |
330 | - } |
331 | - } |
332 | - Component { |
333 | - name: "unity::shell::launcher::QuickListModelInterface" |
334 | - prototype: "QAbstractListModel" |
335 | - exports: ["Unity.Launcher/QuickListInterface 0.1"] |
336 | - isCreatable: false |
337 | - exportMetaObjectRevisions: [0] |
338 | - } |
339 | -} |
340 | |
341 | === modified file 'plugins/Unity/Launcher/launcheritem.cpp' |
342 | --- plugins/Unity/Launcher/launcheritem.cpp 2016-03-09 12:34:09 +0000 |
343 | +++ plugins/Unity/Launcher/launcheritem.cpp 2016-05-13 11:17:06 +0000 |
344 | @@ -35,6 +35,7 @@ |
345 | m_countVisible(false), |
346 | m_focused(false), |
347 | m_alerting(false), |
348 | + m_surfaceCount(0), |
349 | m_quickList(new QuickListModel(this)) |
350 | { |
351 | Q_ASSERT(parent != nullptr); |
352 | @@ -162,9 +163,6 @@ |
353 | if (m_count != count) { |
354 | m_count = count; |
355 | Q_EMIT countChanged(count); |
356 | - if (m_countVisible) { |
357 | - setAlerting(true); |
358 | - } |
359 | } |
360 | } |
361 | |
362 | @@ -178,9 +176,6 @@ |
363 | if (m_countVisible != countVisible) { |
364 | m_countVisible = countVisible; |
365 | Q_EMIT countVisibleChanged(countVisible); |
366 | - if (countVisible) { |
367 | - setAlerting(true); |
368 | - } |
369 | } |
370 | } |
371 | |
372 | @@ -193,9 +188,6 @@ |
373 | { |
374 | if (m_focused != focused) { |
375 | m_focused = focused; |
376 | - if (focused) { |
377 | - setAlerting(false); |
378 | - } |
379 | Q_EMIT focusedChanged(focused); |
380 | } |
381 | } |
382 | @@ -213,6 +205,19 @@ |
383 | } |
384 | } |
385 | |
386 | +int LauncherItem::surfaceCount() const |
387 | +{ |
388 | + return m_surfaceCount; |
389 | +} |
390 | + |
391 | +void LauncherItem::setSurfaceCount(int surfaceCount) |
392 | +{ |
393 | + if (m_surfaceCount != surfaceCount) { |
394 | + m_surfaceCount = surfaceCount; |
395 | + Q_EMIT surfaceCountChanged(surfaceCount); |
396 | + } |
397 | +} |
398 | + |
399 | unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const |
400 | { |
401 | return m_quickList; |
402 | |
403 | === modified file 'plugins/Unity/Launcher/launcheritem.h' |
404 | --- plugins/Unity/Launcher/launcheritem.h 2016-03-10 13:07:01 +0000 |
405 | +++ plugins/Unity/Launcher/launcheritem.h 2016-05-13 11:17:06 +0000 |
406 | @@ -45,6 +45,7 @@ |
407 | bool countVisible() const override; |
408 | bool focused() const override; |
409 | bool alerting() const override; |
410 | + int surfaceCount() const override; |
411 | |
412 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
413 | |
414 | @@ -59,6 +60,7 @@ |
415 | void setCountVisible(bool countVisible); |
416 | void setFocused(bool focused); |
417 | void setAlerting(bool alerting); |
418 | + void setSurfaceCount(int surfaceCount); |
419 | |
420 | private: |
421 | QString m_appId; |
422 | @@ -72,6 +74,7 @@ |
423 | bool m_countVisible; |
424 | bool m_focused; |
425 | bool m_alerting; |
426 | + int m_surfaceCount; |
427 | QuickListModel *m_quickList; |
428 | QuickListEntry m_quitAction; |
429 | |
430 | |
431 | === modified file 'plugins/Unity/Launcher/launchermodel.cpp' |
432 | --- plugins/Unity/Launcher/launchermodel.cpp 2016-03-10 13:07:01 +0000 |
433 | +++ plugins/Unity/Launcher/launchermodel.cpp 2016-05-13 11:17:06 +0000 |
434 | @@ -25,6 +25,7 @@ |
435 | #include "asadapter.h" |
436 | |
437 | #include <unity/shell/application/ApplicationInfoInterface.h> |
438 | +#include <unity/shell/application/MirSurfaceListInterface.h> |
439 | |
440 | #include <QDesktopServices> |
441 | #include <QDebug> |
442 | @@ -88,6 +89,8 @@ |
443 | return item->alerting(); |
444 | case RoleRunning: |
445 | return item->running(); |
446 | + case RoleSurfaceCount: |
447 | + return item->surfaceCount(); |
448 | default: |
449 | qWarning() << Q_FUNC_INFO << "missing role, implement me"; |
450 | return QVariant(); |
451 | @@ -96,18 +99,6 @@ |
452 | return QVariant(); |
453 | } |
454 | |
455 | -void LauncherModel::setAlerting(const QString &appId, bool alerting) { |
456 | - int index = findApplication(appId); |
457 | - if (index >= 0) { |
458 | - QModelIndex modelIndex = this->index(index); |
459 | - LauncherItem *item = m_list.at(index); |
460 | - if (!item->focused()) { |
461 | - item->setAlerting(alerting); |
462 | - Q_EMIT dataChanged(modelIndex, modelIndex, {RoleAlerting}); |
463 | - } |
464 | - } |
465 | -} |
466 | - |
467 | unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const |
468 | { |
469 | if (index < 0 || index >= m_list.count()) { |
470 | @@ -358,11 +349,13 @@ |
471 | if (idx >= 0) { |
472 | LauncherItem *item = m_list.at(idx); |
473 | item->setCount(count); |
474 | - if (item->countVisible()) { |
475 | - setAlerting(item->appId(), true); |
476 | + QVector<int> changedRoles = {RoleCount}; |
477 | + if (item->countVisible() && !item->alerting() && !item->focused()) { |
478 | + changedRoles << RoleAlerting; |
479 | + item->setAlerting(true); |
480 | } |
481 | m_asAdapter->syncItems(m_list); |
482 | - Q_EMIT dataChanged(index(idx), index(idx), {RoleCount}); |
483 | + Q_EMIT dataChanged(index(idx), index(idx), changedRoles); |
484 | } |
485 | } |
486 | |
487 | @@ -372,10 +365,12 @@ |
488 | if (idx >= 0) { |
489 | LauncherItem *item = m_list.at(idx); |
490 | item->setCountVisible(countVisible); |
491 | - if (countVisible) { |
492 | - setAlerting(item->appId(), true); |
493 | + QVector<int> changedRoles = {RoleCount}; |
494 | + if (countVisible && !item->alerting() && !item->focused()) { |
495 | + changedRoles << RoleAlerting; |
496 | + item->setAlerting(true); |
497 | } |
498 | - Q_EMIT dataChanged(index(idx), index(idx), {RoleCountVisible}); |
499 | + Q_EMIT dataChanged(index(idx), index(idx), changedRoles); |
500 | |
501 | // If countVisible goes to false, and the item is neither pinned nor recent we can drop it |
502 | if (!countVisible && !item->pinned() && !item->recent()) { |
503 | @@ -495,10 +490,12 @@ |
504 | |
505 | void LauncherModel::alert(const QString &appId) |
506 | { |
507 | + qDebug() << "alerting for appId" << appId; |
508 | int idx = findApplication(appId); |
509 | if (idx >= 0) { |
510 | LauncherItem *item = m_list.at(idx); |
511 | - setAlerting(item->appId(), true); |
512 | + if (!item->focused() && !item->alerting()) |
513 | + item->setAlerting(true); |
514 | Q_EMIT dataChanged(index(idx), index(idx), {RoleAlerting}); |
515 | } |
516 | } |
517 | @@ -525,21 +522,42 @@ |
518 | item->setRecent(true); |
519 | Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleRecent}); |
520 | } |
521 | + if (item->surfaceCount() != app->surfaceCount()) { |
522 | + item->setSurfaceCount(app->surfaceCount()); |
523 | + Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleSurfaceCount}); |
524 | + } |
525 | + |
526 | item->setRunning(true); |
527 | } else { |
528 | LauncherItem *item = new LauncherItem(app->appId(), app->name(), app->icon().toString(), this); |
529 | item->setRecent(true); |
530 | item->setRunning(true); |
531 | item->setFocused(app->focused()); |
532 | - |
533 | + item->setSurfaceCount(app->surfaceCount()); |
534 | beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); |
535 | m_list.append(item); |
536 | endInsertRows(); |
537 | } |
538 | + connect(app, &ApplicationInfoInterface::surfaceCountChanged, this, &LauncherModel::applicationSurfaceCountChanged); |
539 | m_asAdapter->syncItems(m_list); |
540 | Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleRunning}); |
541 | } |
542 | |
543 | +void LauncherModel::applicationSurfaceCountChanged(int count) |
544 | +{ |
545 | + ApplicationInfoInterface *app = static_cast<ApplicationInfoInterface*>(sender()); |
546 | + int idx = findApplication(app->appId()); |
547 | + if (idx < 0) { |
548 | + qWarning() << "Received a surface count changed event from an app that's not in the Launcher model"; |
549 | + return; |
550 | + } |
551 | + LauncherItem *item = m_list.at(idx); |
552 | + if (item->surfaceCount() != count) { |
553 | + item->setSurfaceCount(count); |
554 | + Q_EMIT dataChanged(index(idx), index(idx), {RoleSurfaceCount}); |
555 | + } |
556 | +} |
557 | + |
558 | void LauncherModel::applicationRemoved(const QModelIndex &parent, int row) |
559 | { |
560 | Q_UNUSED(parent) |
561 | @@ -576,8 +594,14 @@ |
562 | for (int i = 0; i < m_list.count(); ++i) { |
563 | LauncherItem *item = m_list.at(i); |
564 | if (!item->focused() && item->appId() == appId) { |
565 | + QVector<int> changedRoles; |
566 | + changedRoles << RoleFocused; |
567 | item->setFocused(true); |
568 | - Q_EMIT dataChanged(index(i), index(i), {RoleFocused}); |
569 | + if (item->alerting()) { |
570 | + changedRoles << RoleAlerting; |
571 | + item->setAlerting(false); |
572 | + } |
573 | + Q_EMIT dataChanged(index(i), index(i), changedRoles); |
574 | } else if (item->focused() && item->appId() != appId) { |
575 | item->setFocused(false); |
576 | Q_EMIT dataChanged(index(i), index(i), {RoleFocused}); |
577 | |
578 | === modified file 'plugins/Unity/Launcher/launchermodel.h' |
579 | --- plugins/Unity/Launcher/launchermodel.h 2016-03-01 15:24:11 +0000 |
580 | +++ plugins/Unity/Launcher/launchermodel.h 2016-05-13 11:17:06 +0000 |
581 | @@ -45,7 +45,6 @@ |
582 | |
583 | QVariant data(const QModelIndex &index, int role) const override; |
584 | |
585 | - Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override; |
586 | Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override; |
587 | Q_INVOKABLE void move(int oldIndex, int newIndex) override; |
588 | Q_INVOKABLE void pin(const QString &appId, int index = -1) override; |
589 | @@ -79,6 +78,7 @@ |
590 | void applicationAdded(const QModelIndex &parent, int row); |
591 | void applicationRemoved(const QModelIndex &parent, int row); |
592 | void focusedAppIdChanged(); |
593 | + void applicationSurfaceCountChanged(int); |
594 | |
595 | private: |
596 | QList<LauncherItem*> m_list; |
597 | |
598 | === modified file 'qml/Launcher/LauncherDelegate.qml' |
599 | --- qml/Launcher/LauncherDelegate.qml 2016-03-29 13:51:56 +0000 |
600 | +++ qml/Launcher/LauncherDelegate.qml 2016-05-13 11:17:06 +0000 |
601 | @@ -32,11 +32,16 @@ |
602 | property bool alerting: false |
603 | property bool highlighted: false |
604 | property bool shortcutHintShown: false |
605 | + property int surfaceCount: 1 |
606 | |
607 | readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight |
608 | readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight |
609 | readonly property alias wiggling: wiggleAnim.running |
610 | |
611 | + onAlertingChanged: { |
612 | + print("item", index, "alerting:", alerting) |
613 | + } |
614 | + |
615 | property int itemWidth |
616 | property int itemHeight |
617 | // The angle used for rotating |
618 | @@ -114,12 +119,6 @@ |
619 | duration: priv.wiggleDuration |
620 | easing.type: Easing.OutQuad |
621 | } |
622 | - |
623 | - UbuntuNumberAnimation { |
624 | - target: root |
625 | - property: "alerting" |
626 | - to: 0 |
627 | - } |
628 | } |
629 | |
630 | Item { |
631 | @@ -221,12 +220,13 @@ |
632 | } |
633 | spacing: units.gu(.5) |
634 | Repeater { |
635 | - model: 1 // TODO: This should be "Math.min(3, app.surfaceCount)" once we have multiple surfaces |
636 | + objectName: "surfacePipRepeater" |
637 | + model: Math.min(3, root.surfaceCount) |
638 | Rectangle { |
639 | objectName: "runningHighlight" + index |
640 | width: units.gu(0.25) |
641 | height: units.gu(.5) |
642 | - color: "white" |
643 | + color: root.alerting ? UbuntuColors.blue : "white" |
644 | visible: root.itemRunning |
645 | } |
646 | } |
647 | |
648 | === modified file 'qml/Launcher/LauncherPanel.qml' |
649 | --- qml/Launcher/LauncherPanel.qml 2016-04-27 15:01:10 +0000 |
650 | +++ qml/Launcher/LauncherPanel.qml 2016-05-13 11:17:06 +0000 |
651 | @@ -239,10 +239,20 @@ |
652 | alerting: model.alerting |
653 | highlighted: root.highlightIndex == index |
654 | shortcutHintShown: root.shortcutHintsShown && index <= 9 |
655 | + surfaceCount: model.surfaceCount |
656 | z: -Math.abs(offset) |
657 | maxAngle: 55 |
658 | property bool dragging: false |
659 | |
660 | + Timer { |
661 | + interval: 1000 |
662 | + running: index == 2 |
663 | + repeat: true |
664 | + onTriggered: { |
665 | + print("is alerting", model.alerting) |
666 | + } |
667 | + } |
668 | + |
669 | SequentialAnimation { |
670 | id: peekingAnimation |
671 | |
672 | @@ -274,6 +284,7 @@ |
673 | } |
674 | |
675 | onAlertingChanged: { |
676 | + print("panel alerting changed", alerting) |
677 | if(alerting) { |
678 | if (!dragging && (launcherListView.peekingIndex === -1 || launcher.visibleWidth > 0)) { |
679 | launcherListView.moveToIndex(index) |
680 | |
681 | === modified file 'tests/mocks/Unity/Application/ApplicationInfo.cpp' |
682 | --- tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-04-27 15:01:10 +0000 |
683 | +++ tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-05-13 11:17:06 +0000 |
684 | @@ -55,8 +55,9 @@ |
685 | ApplicationInfo::ApplicationInfo(const QString &appId, QObject *parent) |
686 | : ApplicationInfoInterface(appId, parent) |
687 | , m_appId(appId) |
688 | + , m_surfaceList(new MirSurfaceListModel(this)) |
689 | { |
690 | - connect(&m_surfaceList, &MirSurfaceListModel::countChanged, |
691 | + connect(m_surfaceList, &MirSurfaceListModel::countChanged, |
692 | this, &ApplicationInfo::onSurfaceCountChanged, Qt::QueuedConnection); |
693 | |
694 | m_surfaceCreationTimer.setSingleShot(true); |
695 | @@ -78,8 +79,8 @@ |
696 | if (state() == ApplicationInfo::Stopped) { return; } |
697 | |
698 | QString surfaceName = name(); |
699 | - if (m_surfaceList.count() > 0) { |
700 | - surfaceName.append(QString(" %1").arg(m_surfaceList.count()+1)); |
701 | + if (m_surfaceList->count() > 0) { |
702 | + surfaceName.append(QString(" %1").arg(m_surfaceList->count()+1)); |
703 | } |
704 | |
705 | auto surfaceManager = SurfaceManager::instance(); |
706 | @@ -95,7 +96,7 @@ |
707 | |
708 | surface->setShellChrome(m_shellChrome); |
709 | |
710 | - m_surfaceList.appendSurface(surface); |
711 | + m_surfaceList->appendSurface(surface); |
712 | |
713 | ++m_liveSurfaceCount; |
714 | connect(surface, &MirSurface::liveChanged, this, [this, surface](){ |
715 | @@ -186,12 +187,12 @@ |
716 | if (value != m_state) { |
717 | DEBUG_MSG(qPrintable(stateToStr(value))); |
718 | if (!m_manualSurfaceCreation && value == ApplicationInfo::Starting) { |
719 | - Q_ASSERT(m_surfaceList.count() == 0); |
720 | + Q_ASSERT(m_surfaceList->count() == 0); |
721 | m_surfaceCreationTimer.start(); |
722 | } else if (value == ApplicationInfo::Stopped) { |
723 | m_surfaceCreationTimer.stop(); |
724 | - for (int i = 0; i < m_surfaceList.count(); ++i) { |
725 | - MirSurface *surface = static_cast<MirSurface*>(m_surfaceList.get(i)); |
726 | + for (int i = 0; i < m_surfaceList->count(); ++i) { |
727 | + MirSurface *surface = static_cast<MirSurface*>(m_surfaceList->get(i)); |
728 | surface->setLive(false); |
729 | } |
730 | } |
731 | @@ -205,9 +206,9 @@ |
732 | { |
733 | DEBUG_MSG(""); |
734 | |
735 | - if (m_surfaceList.count() > 0) { |
736 | - for (int i = 0; i < m_surfaceList.count(); ++i) { |
737 | - MirSurface *surface = static_cast<MirSurface*>(m_surfaceList.get(i)); |
738 | + if (m_surfaceList->count() > 0) { |
739 | + for (int i = 0; i < m_surfaceList->count(); ++i) { |
740 | + MirSurface *surface = static_cast<MirSurface*>(m_surfaceList->get(i)); |
741 | surface->close(); |
742 | } |
743 | } else { |
744 | @@ -219,15 +220,15 @@ |
745 | void ApplicationInfo::setFullscreen(bool value) |
746 | { |
747 | m_fullscreen = value; |
748 | - if (m_surfaceList.rowCount() > 0) { |
749 | - m_surfaceList.get(0)->setState(Mir::FullscreenState); |
750 | + if (m_surfaceList->rowCount() > 0) { |
751 | + m_surfaceList->get(0)->setState(Mir::FullscreenState); |
752 | } |
753 | } |
754 | |
755 | bool ApplicationInfo::fullscreen() const |
756 | { |
757 | - if (m_surfaceList.rowCount() > 0) { |
758 | - return m_surfaceList.get(0)->state() == Mir::FullscreenState; |
759 | + if (m_surfaceList->rowCount() > 0) { |
760 | + return m_surfaceList->get(0)->state() == Mir::FullscreenState; |
761 | } else { |
762 | return m_fullscreen; |
763 | } |
764 | @@ -333,16 +334,16 @@ |
765 | void ApplicationInfo::setShellChrome(Mir::ShellChrome shellChrome) |
766 | { |
767 | m_shellChrome = shellChrome; |
768 | - if (m_surfaceList.rowCount() > 0) { |
769 | - static_cast<MirSurface*>(m_surfaceList.get(0))->setShellChrome(shellChrome); |
770 | + if (m_surfaceList->rowCount() > 0) { |
771 | + static_cast<MirSurface*>(m_surfaceList->get(0))->setShellChrome(shellChrome); |
772 | } |
773 | } |
774 | |
775 | bool ApplicationInfo::focused() const |
776 | { |
777 | bool someSurfaceHasFocus = false; // to be proven wrong |
778 | - for (int i = 0; i < m_surfaceList.count() && !someSurfaceHasFocus; ++i) { |
779 | - someSurfaceHasFocus = m_surfaceList.get(i)->focused(); |
780 | + for (int i = 0; i < m_surfaceList->count() && !someSurfaceHasFocus; ++i) { |
781 | + someSurfaceHasFocus = m_surfaceList->get(i)->focused(); |
782 | } |
783 | return someSurfaceHasFocus; |
784 | } |
785 | @@ -354,12 +355,12 @@ |
786 | } |
787 | |
788 | if (value) { |
789 | - if (m_surfaceList.count() > 0) { |
790 | - m_surfaceList.get(0)->requestFocus(); |
791 | + if (m_surfaceList->count() > 0) { |
792 | + m_surfaceList->get(0)->requestFocus(); |
793 | } |
794 | } else { |
795 | - for (int i = 0; i < m_surfaceList.count(); ++i) { |
796 | - MirSurface *surface = static_cast<MirSurface*>(m_surfaceList.get(i)); |
797 | + for (int i = 0; i < m_surfaceList->count(); ++i) { |
798 | + MirSurface *surface = static_cast<MirSurface*>(m_surfaceList->get(i)); |
799 | if (surface->focused()) { |
800 | surface->setFocused(false); |
801 | } |
802 | @@ -369,16 +370,16 @@ |
803 | |
804 | void ApplicationInfo::onSurfaceCountChanged() |
805 | { |
806 | - if (m_surfaceList.count() == 0 && m_state == Running) { |
807 | + if (m_surfaceList->count() == 0 && m_state == Running) { |
808 | setState(Stopped); |
809 | } |
810 | } |
811 | |
812 | void ApplicationInfo::requestFocus() |
813 | { |
814 | - if (m_surfaceList.count() == 0) { |
815 | + if (m_surfaceList->count() == 0) { |
816 | Q_EMIT focusRequested(); |
817 | } else { |
818 | - m_surfaceList.get(0)->requestFocus(); |
819 | + m_surfaceList->get(0)->requestFocus(); |
820 | } |
821 | } |
822 | |
823 | === modified file 'tests/mocks/Unity/Application/ApplicationInfo.h' |
824 | --- tests/mocks/Unity/Application/ApplicationInfo.h 2016-04-27 15:01:10 +0000 |
825 | +++ tests/mocks/Unity/Application/ApplicationInfo.h 2016-05-13 11:17:06 +0000 |
826 | @@ -107,7 +107,8 @@ |
827 | |
828 | Q_INVOKABLE void setShellChrome(Mir::ShellChrome shellChrome); |
829 | |
830 | - MirSurfaceListInterface* surfaceList() override { return &m_surfaceList; } |
831 | + MirSurfaceListInterface* surfaceList() const override { return m_surfaceList; } |
832 | + int surfaceCount() const override { return m_surfaceList->count(); } |
833 | |
834 | void setFocused(bool value); |
835 | |
836 | @@ -147,7 +148,7 @@ |
837 | bool m_isTouchApp{true}; |
838 | bool m_exemptFromLifecycle{false}; |
839 | QSize m_initialSurfaceSize; |
840 | - MirSurfaceListModel m_surfaceList; |
841 | + MirSurfaceListModel *m_surfaceList; |
842 | int m_liveSurfaceCount{0}; |
843 | QTimer m_surfaceCreationTimer; |
844 | QList<MirSurface*> m_closingSurfaces; |
845 | |
846 | === modified file 'tests/mocks/Unity/Application/MirSurfaceListModel.cpp' |
847 | --- tests/mocks/Unity/Application/MirSurfaceListModel.cpp 2016-04-04 13:37:49 +0000 |
848 | +++ tests/mocks/Unity/Application/MirSurfaceListModel.cpp 2016-05-13 11:17:06 +0000 |
849 | @@ -66,7 +66,7 @@ |
850 | m_surfaceList.append(surface); |
851 | connectSurface(surface); |
852 | endInsertRows(); |
853 | - Q_EMIT countChanged(); |
854 | + Q_EMIT countChanged(m_surfaceList.count()); |
855 | } |
856 | |
857 | void MirSurfaceListModel::connectSurface(MirSurface *surface) |
858 | @@ -82,7 +82,7 @@ |
859 | beginRemoveRows(QModelIndex(), i, i); |
860 | m_surfaceList.removeAt(i); |
861 | endRemoveRows(); |
862 | - Q_EMIT countChanged(); |
863 | + Q_EMIT countChanged(m_surfaceList.count()); |
864 | } |
865 | } |
866 | |
867 | |
868 | === modified file 'tests/mocks/Unity/Launcher/CMakeLists.txt' |
869 | --- tests/mocks/Unity/Launcher/CMakeLists.txt 2015-07-23 10:31:56 +0000 |
870 | +++ tests/mocks/Unity/Launcher/CMakeLists.txt 2016-05-13 11:17:06 +0000 |
871 | @@ -1,4 +1,4 @@ |
872 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
873 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=9) |
874 | |
875 | include_directories( |
876 | ${CMAKE_CURRENT_SOURCE_DIR} |
877 | |
878 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp' |
879 | --- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-11-23 15:41:34 +0000 |
880 | +++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2016-05-13 11:17:06 +0000 |
881 | @@ -21,6 +21,7 @@ |
882 | #include "MockQuickListModel.h" |
883 | |
884 | #include <paths.h> |
885 | +#include <QDebug> |
886 | |
887 | using namespace unity::shell::launcher; |
888 | |
889 | @@ -38,6 +39,7 @@ |
890 | m_countVisible(false), |
891 | m_focused(false), |
892 | m_alerting(false), |
893 | + m_surfaceCount(0), |
894 | m_quickList(new MockQuickListModel(this)) |
895 | { |
896 | } |
897 | @@ -178,10 +180,24 @@ |
898 | { |
899 | if (m_alerting != alerting) { |
900 | m_alerting = alerting; |
901 | + qDebug() << m_appId << "setting alerting" << alerting; |
902 | Q_EMIT alertingChanged(alerting); |
903 | } |
904 | } |
905 | |
906 | +int MockLauncherItem::surfaceCount() const |
907 | +{ |
908 | + return m_surfaceCount; |
909 | +} |
910 | + |
911 | +void MockLauncherItem::setSurfaceCount(int surfaceCount) |
912 | +{ |
913 | + if (m_surfaceCount != surfaceCount) { |
914 | + m_surfaceCount = surfaceCount; |
915 | + Q_EMIT surfaceCountChanged(surfaceCount); |
916 | + } |
917 | +} |
918 | + |
919 | unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const |
920 | { |
921 | return m_quickList; |
922 | |
923 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h' |
924 | --- tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-07-23 14:13:57 +0000 |
925 | +++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2016-05-13 11:17:06 +0000 |
926 | @@ -46,6 +46,7 @@ |
927 | bool countVisible() const override; |
928 | bool focused() const override; |
929 | bool alerting() const override; |
930 | + int surfaceCount() const override; |
931 | |
932 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
933 | |
934 | @@ -58,6 +59,7 @@ |
935 | void setCountVisible(bool countVisible); |
936 | void setFocused(bool focused); |
937 | void setAlerting(bool alerting); |
938 | + void setSurfaceCount(int surfaceCount); |
939 | |
940 | QString m_appId; |
941 | QString m_desktopFile; |
942 | @@ -71,6 +73,7 @@ |
943 | bool m_countVisible; |
944 | bool m_focused; |
945 | bool m_alerting; |
946 | + int m_surfaceCount; |
947 | MockQuickListModel *m_quickList; |
948 | |
949 | friend class MockLauncherModel; |
950 | |
951 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp' |
952 | --- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-11-25 10:35:29 +0000 |
953 | +++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2016-05-13 11:17:06 +0000 |
954 | @@ -25,6 +25,7 @@ |
955 | MockLauncherItem *item = new MockLauncherItem("dialer-app", "/usr/share/applications/dialer-app.desktop", "Dialer", "dialer-app", this); |
956 | item->setProgress(0); |
957 | item->setPinned(true); |
958 | + item->setSurfaceCount(1); |
959 | item->setRunning(true); |
960 | item->setFocused(true); |
961 | m_list.append(item); |
962 | @@ -36,6 +37,7 @@ |
963 | item->setProgress(50); |
964 | item->setCountVisible(true); |
965 | item->setRunning(true); |
966 | + item->setSurfaceCount(2); |
967 | item->setAlerting(false); |
968 | m_list.append(item); |
969 | item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this); |
970 | @@ -44,6 +46,7 @@ |
971 | item->setProgress(150); |
972 | m_list.append(item); |
973 | item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this); |
974 | + item->setSurfaceCount(5); |
975 | item->setCount(1); |
976 | item->setCountVisible(true); |
977 | item->setRunning(true); |
978 | @@ -119,6 +122,8 @@ |
979 | return item->focused(); |
980 | case RoleAlerting: |
981 | return item->alerting(); |
982 | + case RoleSurfaceCount: |
983 | + return item->surfaceCount(); |
984 | } |
985 | |
986 | return QVariant(); |
987 | |
988 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.h' |
989 | --- tests/mocks/Unity/Launcher/MockLauncherModel.h 2015-07-23 10:31:56 +0000 |
990 | +++ tests/mocks/Unity/Launcher/MockLauncherModel.h 2016-05-13 11:17:06 +0000 |
991 | @@ -38,7 +38,7 @@ |
992 | |
993 | QVariant data(const QModelIndex& index, int role) const override; |
994 | |
995 | - Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override; |
996 | + Q_INVOKABLE void setAlerting(const QString &appId, bool alerting); // Only for testing |
997 | Q_INVOKABLE unity::shell::launcher::LauncherItemInterface *get(int index) const override; |
998 | Q_INVOKABLE void move(int oldIndex, int newIndex) override; |
999 | Q_INVOKABLE void pin(const QString &appId, int index = -1) override; |
1000 | |
1001 | === modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt' |
1002 | --- tests/plugins/Unity/Launcher/CMakeLists.txt 2016-04-19 20:36:29 +0000 |
1003 | +++ tests/plugins/Unity/Launcher/CMakeLists.txt 2016-05-13 11:17:06 +0000 |
1004 | @@ -1,5 +1,5 @@ |
1005 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
1006 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
1007 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=8) |
1008 | |
1009 | include_directories( |
1010 | ${CMAKE_CURRENT_SOURCE_DIR} |
1011 | |
1012 | === modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp' |
1013 | --- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2016-04-27 15:01:10 +0000 |
1014 | +++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2016-05-13 11:17:06 +0000 |
1015 | @@ -66,13 +66,16 @@ |
1016 | void setExemptFromLifecycle(bool) override {} |
1017 | QSize initialSurfaceSize() const override { return QSize(); } |
1018 | void setInitialSurfaceSize(const QSize &) override {} |
1019 | - MirSurfaceListInterface* surfaceList() override { return nullptr; } |
1020 | + MirSurfaceListInterface* surfaceList() const override { return nullptr; } |
1021 | + int surfaceCount() const override { return m_surfaceCount; } |
1022 | + void setSurfaceCount(int count) { m_surfaceCount = count; Q_EMIT surfaceCountChanged(count); } |
1023 | |
1024 | // Methods used for mocking (not in the interface) |
1025 | void setFocused(bool focused) { m_focused = focused; Q_EMIT focusedChanged(focused); } |
1026 | private: |
1027 | QString m_appId; |
1028 | bool m_focused; |
1029 | + int m_surfaceCount = 0; |
1030 | }; |
1031 | |
1032 | // This is a mock, specifically to test the LauncherModel |
1033 | @@ -691,6 +694,15 @@ |
1034 | QCOMPARE(getASConfig().at(index).value("countVisible").toBool(), true); |
1035 | QCOMPARE(getASConfig().at(index).value("count").toInt(), 55); |
1036 | } |
1037 | + |
1038 | + void testSurfaceCountUpdates() { |
1039 | + QString appId = launcherModel->get(0)->appId(); |
1040 | + |
1041 | + QCOMPARE(launcherModel->get(0)->surfaceCount(), 0); |
1042 | + MockApp *app = qobject_cast<MockApp*>(appManager->findApplication(appId)); |
1043 | + app->setSurfaceCount(1); |
1044 | + QCOMPARE(launcherModel->get(0)->surfaceCount(), 1); |
1045 | + } |
1046 | }; |
1047 | |
1048 | QTEST_GUILESS_MAIN(LauncherModelTest) |
1049 | |
1050 | === modified file 'tests/qmltests/Launcher/tst_Launcher.qml' |
1051 | --- tests/qmltests/Launcher/tst_Launcher.qml 2016-03-29 10:43:22 +0000 |
1052 | +++ tests/qmltests/Launcher/tst_Launcher.qml 2016-05-13 11:17:06 +0000 |
1053 | @@ -176,7 +176,10 @@ |
1054 | |
1055 | Button { |
1056 | text: "set alert" |
1057 | - onClicked: LauncherModel.setAlerting(LauncherModel.get(parseInt(appIdEntryAlert.displayText)).appId, true) |
1058 | + onClicked: { |
1059 | + print("should alert", LauncherModel.get(parseInt(appIdEntryAlert.displayText)).appId) |
1060 | + LauncherModel.setAlerting(LauncherModel.get(parseInt(appIdEntryAlert.displayText)).appId, true) |
1061 | + } |
1062 | } |
1063 | |
1064 | TextArea { |
1065 | @@ -478,25 +481,26 @@ |
1066 | function test_progressOverlays() { |
1067 | dragLauncherIntoView(); |
1068 | var launcherListView = findChild(launcher, "launcherListView"); |
1069 | + var moveAnimation = findInvisibleChild(launcherListView, "moveAnimation") |
1070 | for (var i = 0; i < launcherListView.count; ++i) { |
1071 | + launcherListView.moveToIndex(i); |
1072 | + waitForRendering(launcherListView); |
1073 | + tryCompare(moveAnimation, "running", false); |
1074 | + |
1075 | var delegate = findChild(launcherListView, "launcherDelegate" + i) |
1076 | compare(findChild(delegate, "progressOverlay").visible, LauncherModel.get(i).progress >= 0) |
1077 | } |
1078 | } |
1079 | |
1080 | - function test_runningHighlight() { |
1081 | - dragLauncherIntoView(); |
1082 | - var launcherListView = findChild(launcher, "launcherListView"); |
1083 | - for (var i = 0; i < launcherListView.count; ++i) { |
1084 | - var delegate = findChild(launcherListView, "launcherDelegate" + i) |
1085 | - compare(findChild(delegate, "runningHighlight0").visible, LauncherModel.get(i).running) |
1086 | - } |
1087 | - } |
1088 | - |
1089 | function test_focusedHighlight() { |
1090 | dragLauncherIntoView(); |
1091 | var launcherListView = findChild(launcher, "launcherListView"); |
1092 | + var moveAnimation = findInvisibleChild(launcherListView, "moveAnimation") |
1093 | + |
1094 | for (var i = 0; i < launcherListView.count; ++i) { |
1095 | + launcherListView.moveToIndex(i); |
1096 | + waitForRendering(launcherListView); |
1097 | + tryCompare(moveAnimation, "running", false); |
1098 | var delegate = findChild(launcherListView, "launcherDelegate" + i) |
1099 | compare(findChild(delegate, "focusedHighlight").visible, LauncherModel.get(i).focused) |
1100 | } |
1101 | @@ -1283,5 +1287,20 @@ |
1102 | |
1103 | assertFocusOnIndex(-2); |
1104 | } |
1105 | + |
1106 | + function test_surfaceCountPips() { |
1107 | + var launcherListView = findChild(launcher, "launcherListView") |
1108 | + var moveAnimation = findInvisibleChild(launcherListView, "moveAnimation") |
1109 | + |
1110 | + for (var i = 0; i < launcherListView.count; i++) { |
1111 | + launcherListView.moveToIndex(i); |
1112 | + waitForRendering(launcherListView); |
1113 | + tryCompare(moveAnimation, "running", false); |
1114 | + |
1115 | + var delegate = findChild(launcher, "launcherDelegate" + i); |
1116 | + var surfacePipRepeater = findInvisibleChild(delegate, "surfacePipRepeater"); |
1117 | + compare(surfacePipRepeater.model, Math.min(3, LauncherModel.get(i).surfaceCount)) |
1118 | + } |
1119 | + } |
1120 | } |
1121 | } |
* Are there any related MPs required for this MP to build/function as expected? Please list.
yes, listing them in a minute
* Did you perform an exploratory manual test run of your code change and any related functionality?
yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
yes
* If you changed the UI, has there been a design review?
yes, change requested by design. This reveals an issue in the design spec. Here's my conversation with John:
<mzanetti> I have a small issue with the persistent alert state
we are currently coloring pips blue. Problem is, if the app is not running and the alert happened because of a push notification, there is no pip which could be blue
the count emblem will still be there though
<JohnLea> humm, yes this is a small problem
I think it is ok for the moment, but a better solution could be to use something else as the persistent alert notification
<mzanetti> you tell me: a) ignore the problem or b) force a pip even if no surface
<JohnLea> for now do a)
<mzanetti> ack
<JohnLea> in the mean time I'll speak to Matthieu and ask him to have a look at other options, perhaps indicating something on the app icon itself
but that's for the future