Merge lp:~mzanetti/unity8/launcher-surfaceCount-pips into lp:unity8

Proposed by Michael Zanetti
Status: Merged
Approved by: Lukáš Tinkl
Approved revision: 2406
Merged at revision: 2449
Proposed branch: lp:~mzanetti/unity8/launcher-surfaceCount-pips
Merge into: lp:unity8
Prerequisite: lp:~dandrader/unity8/promptsZOrder
Diff against target: 930 lines (+176/-237)
24 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/-0)
plugins/Unity/Launcher/CMakeLists.txt (+3/-1)
plugins/Unity/Launcher/Launcher.qmltypes (+0/-182)
plugins/Unity/Launcher/launcheritem.cpp (+14/-0)
plugins/Unity/Launcher/launcheritem.h (+3/-0)
plugins/Unity/Launcher/launchermodel.cpp (+29/-2)
plugins/Unity/Launcher/launchermodel.h (+1/-0)
qml/Launcher/LauncherDelegate.qml (+3/-1)
qml/Launcher/LauncherPanel.qml (+1/-0)
tests/mocks/Unity/Application/ApplicationInfo.cpp (+29/-27)
tests/mocks/Unity/Application/ApplicationInfo.h (+5/-4)
tests/mocks/Unity/Application/MirSurfaceListModel.cpp (+3/-3)
tests/mocks/Unity/Launcher/CMakeLists.txt (+1/-1)
tests/mocks/Unity/Launcher/MockLauncherItem.cpp (+14/-0)
tests/mocks/Unity/Launcher/MockLauncherItem.h (+3/-0)
tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+5/-0)
tests/plugins/Unity/Launcher/CMakeLists.txt (+1/-1)
tests/plugins/Unity/Launcher/launchermodeltest.cpp (+14/-2)
tests/qmltests/Launcher/tst_Launcher.qml (+25/-9)
To merge this branch: bzr merge lp:~mzanetti/unity8/launcher-surfaceCount-pips
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Needs Fixing
Lukáš Tinkl (community) Approve
Albert Astals Cid (community) merges fine Abstain
Daniel d'Andrada Pending
Review via email: mp+296455@code.launchpad.net

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

Commit message

Add support for the launcher surface pips displaying the correct number of surfaces

Description of the change

To test this, you can install this app:
http://notyetthere.org/data/multiwindow.mzanetti_0.1_all.click

* Are there any related MPs required for this MP to build/function as expected? Please list.

https://code.launchpad.net/~mzanetti/unity-api/surfaceCount-property/+merge/294264
https://code.launchpad.net/~mzanetti/qtmir/surfaceCount-property/+merge/294265

 * 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?

no real ui change, just showing more of the pips, as requested by design

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

Test fails with:

FAIL! : qmltestrunner::Launcher::test_surfaceCountPips() Compared values are not the same
   Actual (): 0
   Expected (): NaN
   Loc: [/home/ltinkl/bzr/unity8/launcher-surfaceCount-pips/tests/qmltests/Launcher/tst_Launcher.qml(1298)]

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

Please either update or nuke (prefered) Launcher.qmltypes

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

> Please either update or nuke (prefered) Launcher.qmltypes

done

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

> Please either update or nuke (prefered) Launcher.qmltypes

I can't see this happening here and from your log output it doesn't seem to make too much sense either atm. How are you launching the test? just make xvfbtestLauncher?

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

Cool, no more objections from my side, works as expected

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

Yes

* Did CI run pass? If not, please explain why.

Not, due to unity-api changes, passes locally

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

Coding style:

"""
void LauncherModel::applicationSurfaceCountChanged(int count)
"""

You're naming a method like signal.

"""
ApplicationInfoInterface *app = static_cast<ApplicationInfoInterface*>(sender());
"""

You wouldn't have to do that if this method received the relevant application as a parameter.

This QOject::sender() has a bad reputation: http://doc.qt.io/qt-5/qobject.html#sender

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

seriously? can't we move on from this useless nitpicking please? I know what I'm doing with with the call to sender(). If you read through your link, you'll see that none of the warnings are an issue in this case. One the other branch you suggest to use a lambda to capture pointers that might vanish independently from the actual thing you connect to. *that* is an issue, not the proper use of the sender() method. It seems you are starting to contradict yourself in your own reviews. I don't think this is useful any more.

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

Here I use surfaceList::count instead of application::surfaceCount and got no crashes (both on phone and laptop):
http://bazaar.launchpad.net/~dandrader/unity8/launcher-surfaceCount-pips/revision/2398

As the documentation says about sender(), "This function violates the object-oriented principle of modularity.", even if you're using it correctly.

I've been using lambdas extensively with Qt signal/slot connections for a while now and they're working fine.

I still think Application::surfaceCount is redundant.

A side comment: regardless of whether you use lambdas and surfaceList::count or not, in LauncherModel::applicationRemoved you should disconnect what you connected in LauncherModel::applicationAdded.

review: Needs Fixing
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in tests/mocks/Unity/Application/ApplicationInfo.h
Text conflict in tests/mocks/Unity/Application/MirSurfaceListModel.cpp
Text conflict in tests/plugins/Unity/Launcher/launchermodeltest.cpp
3 conflicts encountered.

review: Needs Fixing
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

Nice, still works as expected; re-tested after recent fixes and merges

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

Yes

* Did CI run pass? If not, please explain why.

Not, due to unity-api changes, passes locally

review: Approve
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2401
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1340/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/1778/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1804
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1749
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1749
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1749
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1742/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1742/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/1742/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1742/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1742/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/1742/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1742/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1742/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/1742/console

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1340/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2405
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1375/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/1840/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1866
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1804
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1804
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1804
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1795/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1795/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/1795/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1795/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1795/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/1795/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1795/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1795/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/1795/console

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1375/rebuild

review: Needs Fixing (continuous-integration)
2406. By Michael Zanetti

fix broken mock

Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Approving after the prereq rebase, let's wait for CI and silo testing for top approval

review: Approve
Revision history for this message
Albert Astals Cid (aacid) :
review: Abstain (merges fine)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Tested in silo 25, works as expected.

review: Approve
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2406
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1409/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/1875/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1901
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1838
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1838
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1838
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1829/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1829/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/1829/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1829/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1829/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/1829/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1829/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1829/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/1829/console

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1409/rebuild

review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-05-27 13:54:26 +0000
3+++ CMakeLists.txt 2016-06-06 14:13:23 +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=17)
9+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=18)
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-27 13:54:26 +0000
16+++ debian/control 2016-06-06 14:13:23 +0000
17@@ -32,7 +32,7 @@
18 libubuntugestures5-dev,
19 libubuntugestures5-private-dev,
20 libudev-dev,
21- libunity-api-dev (>= 7.113),
22+ libunity-api-dev (>= 7.114),
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-06-06 14:13:23 +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=8)
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-06-06 14:13:23 +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-06-06 14:13:23 +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-06-06 14:13:23 +0000
101@@ -69,6 +69,8 @@
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=== modified file 'plugins/Unity/Launcher/CMakeLists.txt'
112--- plugins/Unity/Launcher/CMakeLists.txt 2016-04-19 20:36:29 +0000
113+++ plugins/Unity/Launcher/CMakeLists.txt 2016-06-06 14:13:23 +0000
114@@ -1,4 +1,4 @@
115-pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
116+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=8)
117 pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
118
119 add_definitions(-DSM_BUSNAME=systemBus)
120@@ -23,6 +23,8 @@
121 asadapter.cpp
122 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
123 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
124+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
125+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceListInterface.h
126 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
127 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
128 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h
129
130=== removed file 'plugins/Unity/Launcher/Launcher.qmltypes'
131--- plugins/Unity/Launcher/Launcher.qmltypes 2015-02-13 09:01:16 +0000
132+++ plugins/Unity/Launcher/Launcher.qmltypes 1970-01-01 00:00:00 +0000
133@@ -1,182 +0,0 @@
134-import QtQuick.tooling 1.1
135-
136-// This file describes the plugin-supplied types contained in the library.
137-// It is used for QML tooling purposes only.
138-//
139-// This file was auto-generated by:
140-// 'qmlplugindump -notrelocatable Unity.Launcher 0.1 plugins'
141-
142-Module {
143- Component {
144- name: "LauncherItem"
145- prototype: "unity::shell::launcher::LauncherItemInterface"
146- exports: ["Unity.Launcher/LauncherItem 0.1"]
147- isCreatable: false
148- exportMetaObjectRevisions: [0]
149- }
150- Component {
151- name: "LauncherModel"
152- prototype: "unity::shell::launcher::LauncherModelInterface"
153- exports: ["Unity.Launcher/LauncherModel 0.1"]
154- isCreatable: false
155- isSingleton: true
156- exportMetaObjectRevisions: [0]
157- Method {
158- name: "requestRemove"
159- Parameter { name: "appId"; type: "string" }
160- }
161- Method { name: "refresh" }
162- Method {
163- name: "get"
164- type: "unity::shell::launcher::LauncherItemInterface*"
165- Parameter { name: "index"; type: "int" }
166- }
167- Method {
168- name: "move"
169- Parameter { name: "oldIndex"; type: "int" }
170- Parameter { name: "newIndex"; type: "int" }
171- }
172- Method {
173- name: "pin"
174- Parameter { name: "appId"; type: "string" }
175- Parameter { name: "index"; type: "int" }
176- }
177- Method {
178- name: "pin"
179- Parameter { name: "appId"; type: "string" }
180- }
181- Method {
182- name: "quickListActionInvoked"
183- Parameter { name: "appId"; type: "string" }
184- Parameter { name: "actionIndex"; type: "int" }
185- }
186- Method {
187- name: "setUser"
188- Parameter { name: "username"; type: "string" }
189- }
190- Method {
191- name: "getUrlForAppId"
192- type: "string"
193- Parameter { name: "appId"; type: "string" }
194- }
195- }
196- Component {
197- name: "QuickListModel"
198- prototype: "unity::shell::launcher::QuickListModelInterface"
199- exports: ["Unity.Launcher/QuickListModel 0.1"]
200- isCreatable: false
201- exportMetaObjectRevisions: [0]
202- }
203- Component {
204- name: "unity::shell::launcher::LauncherItemInterface"
205- prototype: "QObject"
206- exports: ["Unity.Launcher/LauncherItemInterface 0.1"]
207- isCreatable: false
208- exportMetaObjectRevisions: [0]
209- Property { name: "appId"; type: "string"; isReadonly: true }
210- Property { name: "name"; type: "string"; isReadonly: true }
211- Property { name: "icon"; type: "string"; isReadonly: true }
212- Property { name: "pinned"; type: "bool"; isReadonly: true }
213- Property { name: "running"; type: "bool"; isReadonly: true }
214- Property { name: "recent"; type: "bool"; isReadonly: true }
215- Property { name: "progress"; type: "int"; isReadonly: true }
216- Property { name: "count"; type: "int"; isReadonly: true }
217- Property { name: "countVisible"; type: "bool"; isReadonly: true }
218- Property { name: "focused"; type: "bool"; isReadonly: true }
219- Property {
220- name: "quickList"
221- type: "unity::shell::launcher::QuickListModelInterface"
222- isReadonly: true
223- isPointer: true
224- }
225- Signal {
226- name: "nameChanged"
227- Parameter { name: "name"; type: "string" }
228- }
229- Signal {
230- name: "iconChanged"
231- Parameter { name: "icon"; type: "string" }
232- }
233- Signal {
234- name: "pinnedChanged"
235- Parameter { name: "pinned"; type: "bool" }
236- }
237- Signal {
238- name: "runningChanged"
239- Parameter { name: "running"; type: "bool" }
240- }
241- Signal {
242- name: "recentChanged"
243- Parameter { name: "running"; type: "bool" }
244- }
245- Signal {
246- name: "progressChanged"
247- Parameter { name: "progress"; type: "int" }
248- }
249- Signal {
250- name: "countChanged"
251- Parameter { name: "count"; type: "int" }
252- }
253- Signal {
254- name: "countVisibleChanged"
255- Parameter { name: "countVisible"; type: "bool" }
256- }
257- Signal {
258- name: "focusedChanged"
259- Parameter { name: "focused"; type: "bool" }
260- }
261- }
262- Component {
263- name: "unity::shell::launcher::LauncherModelInterface"
264- prototype: "QAbstractListModel"
265- exports: ["Unity.Launcher/LauncherModelInterface 0.1"]
266- isCreatable: false
267- exportMetaObjectRevisions: [0]
268- Property {
269- name: "applicationManager"
270- type: "unity::shell::application::ApplicationManagerInterface"
271- isPointer: true
272- }
273- Property { name: "onlyPinned"; type: "bool" }
274- Signal { name: "hint" }
275- Method {
276- name: "move"
277- Parameter { name: "oldIndex"; type: "int" }
278- Parameter { name: "newIndex"; type: "int" }
279- }
280- Method {
281- name: "get"
282- type: "unity::shell::launcher::LauncherItemInterface*"
283- Parameter { name: "index"; type: "int" }
284- }
285- Method {
286- name: "pin"
287- Parameter { name: "appId"; type: "string" }
288- Parameter { name: "index"; type: "int" }
289- }
290- Method {
291- name: "pin"
292- Parameter { name: "appId"; type: "string" }
293- }
294- Method {
295- name: "requestRemove"
296- Parameter { name: "appId"; type: "string" }
297- }
298- Method {
299- name: "quickListActionInvoked"
300- Parameter { name: "appId"; type: "string" }
301- Parameter { name: "actionIndex"; type: "int" }
302- }
303- Method {
304- name: "setUser"
305- Parameter { name: "username"; type: "string" }
306- }
307- }
308- Component {
309- name: "unity::shell::launcher::QuickListModelInterface"
310- prototype: "QAbstractListModel"
311- exports: ["Unity.Launcher/QuickListInterface 0.1"]
312- isCreatable: false
313- exportMetaObjectRevisions: [0]
314- }
315-}
316
317=== modified file 'plugins/Unity/Launcher/launcheritem.cpp'
318--- plugins/Unity/Launcher/launcheritem.cpp 2016-03-09 12:34:09 +0000
319+++ plugins/Unity/Launcher/launcheritem.cpp 2016-06-06 14:13:23 +0000
320@@ -35,6 +35,7 @@
321 m_countVisible(false),
322 m_focused(false),
323 m_alerting(false),
324+ m_surfaceCount(0),
325 m_quickList(new QuickListModel(this))
326 {
327 Q_ASSERT(parent != nullptr);
328@@ -213,6 +214,19 @@
329 }
330 }
331
332+int LauncherItem::surfaceCount() const
333+{
334+ return m_surfaceCount;
335+}
336+
337+void LauncherItem::setSurfaceCount(int surfaceCount)
338+{
339+ if (m_surfaceCount != surfaceCount) {
340+ m_surfaceCount = surfaceCount;
341+ Q_EMIT surfaceCountChanged(surfaceCount);
342+ }
343+}
344+
345 unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
346 {
347 return m_quickList;
348
349=== modified file 'plugins/Unity/Launcher/launcheritem.h'
350--- plugins/Unity/Launcher/launcheritem.h 2016-03-10 13:07:01 +0000
351+++ plugins/Unity/Launcher/launcheritem.h 2016-06-06 14:13:23 +0000
352@@ -45,6 +45,7 @@
353 bool countVisible() const override;
354 bool focused() const override;
355 bool alerting() const override;
356+ int surfaceCount() const override;
357
358 unity::shell::launcher::QuickListModelInterface *quickList() const override;
359
360@@ -59,6 +60,7 @@
361 void setCountVisible(bool countVisible);
362 void setFocused(bool focused);
363 void setAlerting(bool alerting);
364+ void setSurfaceCount(int surfaceCount);
365
366 private:
367 QString m_appId;
368@@ -72,6 +74,7 @@
369 bool m_countVisible;
370 bool m_focused;
371 bool m_alerting;
372+ int m_surfaceCount;
373 QuickListModel *m_quickList;
374 QuickListEntry m_quitAction;
375
376
377=== modified file 'plugins/Unity/Launcher/launchermodel.cpp'
378--- plugins/Unity/Launcher/launchermodel.cpp 2016-03-10 13:07:01 +0000
379+++ plugins/Unity/Launcher/launchermodel.cpp 2016-06-06 14:13:23 +0000
380@@ -25,6 +25,7 @@
381 #include "asadapter.h"
382
383 #include <unity/shell/application/ApplicationInfoInterface.h>
384+#include <unity/shell/application/MirSurfaceListInterface.h>
385
386 #include <QDesktopServices>
387 #include <QDebug>
388@@ -88,6 +89,8 @@
389 return item->alerting();
390 case RoleRunning:
391 return item->running();
392+ case RoleSurfaceCount:
393+ return item->surfaceCount();
394 default:
395 qWarning() << Q_FUNC_INFO << "missing role, implement me";
396 return QVariant();
397@@ -525,28 +528,50 @@
398 item->setRecent(true);
399 Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleRecent});
400 }
401+ if (item->surfaceCount() != app->surfaceCount()) {
402+ item->setSurfaceCount(app->surfaceCount());
403+ Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleSurfaceCount});
404+ }
405+
406 item->setRunning(true);
407 } else {
408 LauncherItem *item = new LauncherItem(app->appId(), app->name(), app->icon().toString(), this);
409 item->setRecent(true);
410 item->setRunning(true);
411 item->setFocused(app->focused());
412-
413+ item->setSurfaceCount(app->surfaceCount());
414 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
415 m_list.append(item);
416 endInsertRows();
417 }
418+ connect(app, &ApplicationInfoInterface::surfaceCountChanged, this, &LauncherModel::applicationSurfaceCountChanged);
419 m_asAdapter->syncItems(m_list);
420 Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleRunning});
421 }
422
423+void LauncherModel::applicationSurfaceCountChanged(int count)
424+{
425+ ApplicationInfoInterface *app = static_cast<ApplicationInfoInterface*>(sender());
426+ int idx = findApplication(app->appId());
427+ if (idx < 0) {
428+ qWarning() << "Received a surface count changed event from an app that's not in the Launcher model";
429+ return;
430+ }
431+ LauncherItem *item = m_list.at(idx);
432+ if (item->surfaceCount() != count) {
433+ item->setSurfaceCount(count);
434+ Q_EMIT dataChanged(index(idx), index(idx), {RoleSurfaceCount});
435+ }
436+}
437+
438 void LauncherModel::applicationRemoved(const QModelIndex &parent, int row)
439 {
440 Q_UNUSED(parent)
441
442+ ApplicationInfoInterface *app = m_appManager->get(row);
443 int appIndex = -1;
444 for (int i = 0; i < m_list.count(); ++i) {
445- if (m_list.at(i)->appId() == m_appManager->get(row)->appId()) {
446+ if (m_list.at(i)->appId() == app->appId()) {
447 appIndex = i;
448 break;
449 }
450@@ -557,6 +582,8 @@
451 return;
452 }
453
454+ disconnect(app, &ApplicationInfoInterface::surfaceCountChanged, this, &LauncherModel::applicationSurfaceCountChanged);
455+
456 LauncherItem * item = m_list.at(appIndex);
457 item->setRunning(false);
458
459
460=== modified file 'plugins/Unity/Launcher/launchermodel.h'
461--- plugins/Unity/Launcher/launchermodel.h 2016-03-01 15:24:11 +0000
462+++ plugins/Unity/Launcher/launchermodel.h 2016-06-06 14:13:23 +0000
463@@ -79,6 +79,7 @@
464 void applicationAdded(const QModelIndex &parent, int row);
465 void applicationRemoved(const QModelIndex &parent, int row);
466 void focusedAppIdChanged();
467+ void applicationSurfaceCountChanged(int);
468
469 private:
470 QList<LauncherItem*> m_list;
471
472=== modified file 'qml/Launcher/LauncherDelegate.qml'
473--- qml/Launcher/LauncherDelegate.qml 2016-05-17 20:46:51 +0000
474+++ qml/Launcher/LauncherDelegate.qml 2016-06-06 14:13:23 +0000
475@@ -32,6 +32,7 @@
476 property bool alerting: false
477 property bool highlighted: false
478 property bool shortcutHintShown: false
479+ property int surfaceCount: 1
480
481 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
482 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
483@@ -221,7 +222,8 @@
484 }
485 spacing: units.gu(.5)
486 Repeater {
487- model: 1 // TODO: This should be "Math.min(3, app.surfaceCount)" once we have multiple surfaces
488+ objectName: "surfacePipRepeater"
489+ model: Math.min(3, root.surfaceCount)
490 Rectangle {
491 objectName: "runningHighlight" + index
492 width: units.gu(0.25)
493
494=== modified file 'qml/Launcher/LauncherPanel.qml'
495--- qml/Launcher/LauncherPanel.qml 2016-04-27 15:01:10 +0000
496+++ qml/Launcher/LauncherPanel.qml 2016-06-06 14:13:23 +0000
497@@ -239,6 +239,7 @@
498 alerting: model.alerting
499 highlighted: root.highlightIndex == index
500 shortcutHintShown: root.shortcutHintsShown && index <= 9
501+ surfaceCount: model.surfaceCount
502 z: -Math.abs(offset)
503 maxAngle: 55
504 property bool dragging: false
505
506=== modified file 'tests/mocks/Unity/Application/ApplicationInfo.cpp'
507--- tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-05-17 19:59:44 +0000
508+++ tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-06-06 14:13:23 +0000
509@@ -55,8 +55,10 @@
510 ApplicationInfo::ApplicationInfo(const QString &appId, QObject *parent)
511 : ApplicationInfoInterface(appId, parent)
512 , m_appId(appId)
513+ , m_surfaceList(new MirSurfaceListModel(this))
514+ , m_promptSurfaceList(new MirSurfaceListModel(this))
515 {
516- connect(&m_surfaceList, &MirSurfaceListModel::countChanged,
517+ connect(m_surfaceList, &MirSurfaceListModel::countChanged,
518 this, &ApplicationInfo::onSurfaceCountChanged, Qt::QueuedConnection);
519
520 m_surfaceCreationTimer.setSingleShot(true);
521@@ -78,8 +80,8 @@
522 if (state() == ApplicationInfo::Stopped) { return; }
523
524 QString surfaceName = name();
525- if (m_surfaceList.count() > 0) {
526- surfaceName.append(QString(" %1").arg(m_surfaceList.count()+1));
527+ if (m_surfaceList->count() > 0) {
528+ surfaceName.append(QString(" %1").arg(m_surfaceList->count()+1));
529 }
530
531 auto surfaceManager = SurfaceManager::instance();
532@@ -95,7 +97,7 @@
533
534 surface->setShellChrome(m_shellChrome);
535
536- m_surfaceList.appendSurface(surface);
537+ m_surfaceList->appendSurface(surface);
538
539 ++m_liveSurfaceCount;
540 connect(surface, &MirSurface::liveChanged, this, [this, surface](){
541@@ -186,16 +188,16 @@
542 if (value != m_state) {
543 DEBUG_MSG(qPrintable(stateToStr(value)));
544 if (!m_manualSurfaceCreation && value == ApplicationInfo::Starting) {
545- Q_ASSERT(m_surfaceList.count() == 0);
546+ Q_ASSERT(m_surfaceList->count() == 0);
547 m_surfaceCreationTimer.start();
548 } else if (value == ApplicationInfo::Stopped) {
549 m_surfaceCreationTimer.stop();
550- for (int i = 0; i < m_surfaceList.count(); ++i) {
551- MirSurface *surface = static_cast<MirSurface*>(m_surfaceList.get(i));
552+ for (int i = 0; i < m_surfaceList->count(); ++i) {
553+ MirSurface *surface = static_cast<MirSurface*>(m_surfaceList->get(i));
554 surface->setLive(false);
555 }
556- for (int i = 0; i < m_promptSurfaceList.count(); ++i) {
557- auto surface = static_cast<MirSurface*>(m_promptSurfaceList.get(i));
558+ for (int i = 0; i < m_promptSurfaceList->count(); ++i) {
559+ auto surface = static_cast<MirSurface*>(m_promptSurfaceList->get(i));
560 surface->setLive(false);
561 }
562 }
563@@ -209,9 +211,9 @@
564 {
565 DEBUG_MSG("");
566
567- if (m_surfaceList.count() > 0) {
568- for (int i = 0; i < m_surfaceList.count(); ++i) {
569- MirSurface *surface = static_cast<MirSurface*>(m_surfaceList.get(i));
570+ if (m_surfaceList->count() > 0) {
571+ for (int i = 0; i < m_surfaceList->count(); ++i) {
572+ MirSurface *surface = static_cast<MirSurface*>(m_surfaceList->get(i));
573 surface->close();
574 }
575 } else {
576@@ -223,15 +225,15 @@
577 void ApplicationInfo::setFullscreen(bool value)
578 {
579 m_fullscreen = value;
580- if (m_surfaceList.rowCount() > 0) {
581- m_surfaceList.get(0)->setState(Mir::FullscreenState);
582+ if (m_surfaceList->rowCount() > 0) {
583+ m_surfaceList->get(0)->setState(Mir::FullscreenState);
584 }
585 }
586
587 bool ApplicationInfo::fullscreen() const
588 {
589- if (m_surfaceList.rowCount() > 0) {
590- return m_surfaceList.get(0)->state() == Mir::FullscreenState;
591+ if (m_surfaceList->rowCount() > 0) {
592+ return m_surfaceList->get(0)->state() == Mir::FullscreenState;
593 } else {
594 return m_fullscreen;
595 }
596@@ -341,16 +343,16 @@
597 void ApplicationInfo::setShellChrome(Mir::ShellChrome shellChrome)
598 {
599 m_shellChrome = shellChrome;
600- if (m_surfaceList.rowCount() > 0) {
601- static_cast<MirSurface*>(m_surfaceList.get(0))->setShellChrome(shellChrome);
602+ if (m_surfaceList->rowCount() > 0) {
603+ static_cast<MirSurface*>(m_surfaceList->get(0))->setShellChrome(shellChrome);
604 }
605 }
606
607 bool ApplicationInfo::focused() const
608 {
609 bool someSurfaceHasFocus = false; // to be proven wrong
610- for (int i = 0; i < m_surfaceList.count() && !someSurfaceHasFocus; ++i) {
611- someSurfaceHasFocus = m_surfaceList.get(i)->focused();
612+ for (int i = 0; i < m_surfaceList->count() && !someSurfaceHasFocus; ++i) {
613+ someSurfaceHasFocus = m_surfaceList->get(i)->focused();
614 }
615 return someSurfaceHasFocus;
616 }
617@@ -362,12 +364,12 @@
618 }
619
620 if (value) {
621- if (m_surfaceList.count() > 0) {
622- m_surfaceList.get(0)->requestFocus();
623+ if (m_surfaceList->count() > 0) {
624+ m_surfaceList->get(0)->requestFocus();
625 }
626 } else {
627- for (int i = 0; i < m_surfaceList.count(); ++i) {
628- MirSurface *surface = static_cast<MirSurface*>(m_surfaceList.get(i));
629+ for (int i = 0; i < m_surfaceList->count(); ++i) {
630+ MirSurface *surface = static_cast<MirSurface*>(m_surfaceList->get(i));
631 if (surface->focused()) {
632 surface->setFocused(false);
633 }
634@@ -377,16 +379,16 @@
635
636 void ApplicationInfo::onSurfaceCountChanged()
637 {
638- if (m_surfaceList.count() == 0 && m_state == Running) {
639+ if (m_surfaceList->count() == 0 && m_state == Running) {
640 setState(Stopped);
641 }
642 }
643
644 void ApplicationInfo::requestFocus()
645 {
646- if (m_surfaceList.count() == 0) {
647+ if (m_surfaceList->count() == 0) {
648 Q_EMIT focusRequested();
649 } else {
650- m_surfaceList.get(0)->requestFocus();
651+ m_surfaceList->get(0)->requestFocus();
652 }
653 }
654
655=== modified file 'tests/mocks/Unity/Application/ApplicationInfo.h'
656--- tests/mocks/Unity/Application/ApplicationInfo.h 2016-05-27 13:52:52 +0000
657+++ tests/mocks/Unity/Application/ApplicationInfo.h 2016-06-06 14:13:23 +0000
658@@ -107,8 +107,9 @@
659
660 Q_INVOKABLE void setShellChrome(Mir::ShellChrome shellChrome);
661
662- MirSurfaceListInterface* surfaceList() override { return &m_surfaceList; }
663- MirSurfaceListInterface* promptSurfaceList() override { return &m_promptSurfaceList; }
664+ MirSurfaceListInterface* surfaceList() const override { return m_surfaceList; }
665+ MirSurfaceListInterface* promptSurfaceList() const override { return m_promptSurfaceList; }
666+ int surfaceCount() const override { return m_surfaceList->count(); }
667
668 void setFocused(bool value);
669
670@@ -148,8 +149,8 @@
671 bool m_isTouchApp{true};
672 bool m_exemptFromLifecycle{false};
673 QSize m_initialSurfaceSize;
674- MirSurfaceListModel m_surfaceList;
675- MirSurfaceListModel m_promptSurfaceList;
676+ MirSurfaceListModel *m_surfaceList;
677+ MirSurfaceListModel *m_promptSurfaceList;
678 int m_liveSurfaceCount{0};
679 QTimer m_surfaceCreationTimer;
680 QList<MirSurface*> m_closingSurfaces;
681
682=== modified file 'tests/mocks/Unity/Application/MirSurfaceListModel.cpp'
683--- tests/mocks/Unity/Application/MirSurfaceListModel.cpp 2016-06-06 14:13:22 +0000
684+++ tests/mocks/Unity/Application/MirSurfaceListModel.cpp 2016-06-06 14:13:23 +0000
685@@ -66,7 +66,7 @@
686 m_surfaceList.append(surface);
687 connectSurface(surface);
688 endInsertRows();
689- Q_EMIT countChanged();
690+ Q_EMIT countChanged(m_surfaceList.count());
691 if (m_surfaceList.count() == 1) {
692 Q_EMIT firstChanged();
693 }
694@@ -78,7 +78,7 @@
695 m_surfaceList.prepend(surface);
696 connectSurface(surface);
697 endInsertRows();
698- Q_EMIT countChanged();
699+ Q_EMIT countChanged(m_surfaceList.count());
700 Q_EMIT firstChanged();
701 }
702
703@@ -95,7 +95,7 @@
704 beginRemoveRows(QModelIndex(), i, i);
705 m_surfaceList.removeAt(i);
706 endRemoveRows();
707- Q_EMIT countChanged();
708+ Q_EMIT countChanged(m_surfaceList.count());
709 if (m_surfaceList.count() == 0 || i == 0) {
710 Q_EMIT firstChanged();
711 }
712
713=== modified file 'tests/mocks/Unity/Launcher/CMakeLists.txt'
714--- tests/mocks/Unity/Launcher/CMakeLists.txt 2015-07-23 10:31:56 +0000
715+++ tests/mocks/Unity/Launcher/CMakeLists.txt 2016-06-06 14:13:23 +0000
716@@ -1,4 +1,4 @@
717-pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
718+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=8)
719
720 include_directories(
721 ${CMAKE_CURRENT_SOURCE_DIR}
722
723=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp'
724--- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-11-23 15:41:34 +0000
725+++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2016-06-06 14:13:23 +0000
726@@ -38,6 +38,7 @@
727 m_countVisible(false),
728 m_focused(false),
729 m_alerting(false),
730+ m_surfaceCount(0),
731 m_quickList(new MockQuickListModel(this))
732 {
733 }
734@@ -182,6 +183,19 @@
735 }
736 }
737
738+int MockLauncherItem::surfaceCount() const
739+{
740+ return m_surfaceCount;
741+}
742+
743+void MockLauncherItem::setSurfaceCount(int surfaceCount)
744+{
745+ if (m_surfaceCount != surfaceCount) {
746+ m_surfaceCount = surfaceCount;
747+ Q_EMIT surfaceCountChanged(surfaceCount);
748+ }
749+}
750+
751 unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const
752 {
753 return m_quickList;
754
755=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h'
756--- tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-07-23 14:13:57 +0000
757+++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2016-06-06 14:13:23 +0000
758@@ -46,6 +46,7 @@
759 bool countVisible() const override;
760 bool focused() const override;
761 bool alerting() const override;
762+ int surfaceCount() const override;
763
764 unity::shell::launcher::QuickListModelInterface *quickList() const override;
765
766@@ -58,6 +59,7 @@
767 void setCountVisible(bool countVisible);
768 void setFocused(bool focused);
769 void setAlerting(bool alerting);
770+ void setSurfaceCount(int surfaceCount);
771
772 QString m_appId;
773 QString m_desktopFile;
774@@ -71,6 +73,7 @@
775 bool m_countVisible;
776 bool m_focused;
777 bool m_alerting;
778+ int m_surfaceCount;
779 MockQuickListModel *m_quickList;
780
781 friend class MockLauncherModel;
782
783=== modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp'
784--- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-11-25 10:35:29 +0000
785+++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2016-06-06 14:13:23 +0000
786@@ -25,6 +25,7 @@
787 MockLauncherItem *item = new MockLauncherItem("dialer-app", "/usr/share/applications/dialer-app.desktop", "Dialer", "dialer-app", this);
788 item->setProgress(0);
789 item->setPinned(true);
790+ item->setSurfaceCount(1);
791 item->setRunning(true);
792 item->setFocused(true);
793 m_list.append(item);
794@@ -36,6 +37,7 @@
795 item->setProgress(50);
796 item->setCountVisible(true);
797 item->setRunning(true);
798+ item->setSurfaceCount(2);
799 item->setAlerting(false);
800 m_list.append(item);
801 item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this);
802@@ -44,6 +46,7 @@
803 item->setProgress(150);
804 m_list.append(item);
805 item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this);
806+ item->setSurfaceCount(5);
807 item->setCount(1);
808 item->setCountVisible(true);
809 item->setRunning(true);
810@@ -119,6 +122,8 @@
811 return item->focused();
812 case RoleAlerting:
813 return item->alerting();
814+ case RoleSurfaceCount:
815+ return item->surfaceCount();
816 }
817
818 return QVariant();
819
820=== modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt'
821--- tests/plugins/Unity/Launcher/CMakeLists.txt 2016-04-19 20:36:29 +0000
822+++ tests/plugins/Unity/Launcher/CMakeLists.txt 2016-06-06 14:13:23 +0000
823@@ -1,5 +1,5 @@
824 pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
825-pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
826+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=8)
827
828 include_directories(
829 ${CMAKE_CURRENT_SOURCE_DIR}
830
831=== modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp'
832--- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2016-05-17 19:25:23 +0000
833+++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2016-06-06 14:13:23 +0000
834@@ -66,14 +66,17 @@
835 void setExemptFromLifecycle(bool) override {}
836 QSize initialSurfaceSize() const override { return QSize(); }
837 void setInitialSurfaceSize(const QSize &) override {}
838- MirSurfaceListInterface* surfaceList() override { return nullptr; }
839- MirSurfaceListInterface* promptSurfaceList() override { return nullptr; }
840+ MirSurfaceListInterface* surfaceList() const override { return nullptr; }
841+ MirSurfaceListInterface* promptSurfaceList() const override { return nullptr; }
842+ int surfaceCount() const override { return m_surfaceCount; }
843+ void setSurfaceCount(int count) { m_surfaceCount = count; Q_EMIT surfaceCountChanged(count); }
844
845 // Methods used for mocking (not in the interface)
846 void setFocused(bool focused) { m_focused = focused; Q_EMIT focusedChanged(focused); }
847 private:
848 QString m_appId;
849 bool m_focused;
850+ int m_surfaceCount = 0;
851 };
852
853 // This is a mock, specifically to test the LauncherModel
854@@ -692,6 +695,15 @@
855 QCOMPARE(getASConfig().at(index).value("countVisible").toBool(), true);
856 QCOMPARE(getASConfig().at(index).value("count").toInt(), 55);
857 }
858+
859+ void testSurfaceCountUpdates() {
860+ QString appId = launcherModel->get(0)->appId();
861+
862+ QCOMPARE(launcherModel->get(0)->surfaceCount(), 0);
863+ MockApp *app = qobject_cast<MockApp*>(appManager->findApplication(appId));
864+ app->setSurfaceCount(1);
865+ QCOMPARE(launcherModel->get(0)->surfaceCount(), 1);
866+ }
867 };
868
869 QTEST_GUILESS_MAIN(LauncherModelTest)
870
871=== modified file 'tests/qmltests/Launcher/tst_Launcher.qml'
872--- tests/qmltests/Launcher/tst_Launcher.qml 2016-05-27 13:53:41 +0000
873+++ tests/qmltests/Launcher/tst_Launcher.qml 2016-06-06 14:13:23 +0000
874@@ -486,25 +486,26 @@
875 function test_progressOverlays() {
876 dragLauncherIntoView();
877 var launcherListView = findChild(launcher, "launcherListView");
878+ var moveAnimation = findInvisibleChild(launcherListView, "moveAnimation")
879 for (var i = 0; i < launcherListView.count; ++i) {
880+ launcherListView.moveToIndex(i);
881+ waitForRendering(launcherListView);
882+ tryCompare(moveAnimation, "running", false);
883+
884 var delegate = findChild(launcherListView, "launcherDelegate" + i)
885 compare(findChild(delegate, "progressOverlay").visible, LauncherModel.get(i).progress >= 0)
886 }
887 }
888
889- function test_runningHighlight() {
890- dragLauncherIntoView();
891- var launcherListView = findChild(launcher, "launcherListView");
892- for (var i = 0; i < launcherListView.count; ++i) {
893- var delegate = findChild(launcherListView, "launcherDelegate" + i)
894- compare(findChild(delegate, "runningHighlight0").visible, LauncherModel.get(i).running)
895- }
896- }
897-
898 function test_focusedHighlight() {
899 dragLauncherIntoView();
900 var launcherListView = findChild(launcher, "launcherListView");
901+ var moveAnimation = findInvisibleChild(launcherListView, "moveAnimation")
902+
903 for (var i = 0; i < launcherListView.count; ++i) {
904+ launcherListView.moveToIndex(i);
905+ waitForRendering(launcherListView);
906+ tryCompare(moveAnimation, "running", false);
907 var delegate = findChild(launcherListView, "launcherDelegate" + i)
908 compare(findChild(delegate, "focusedHighlight").visible, LauncherModel.get(i).focused)
909 }
910@@ -1295,5 +1296,20 @@
911
912 assertFocusOnIndex(-2);
913 }
914+
915+ function test_surfaceCountPips() {
916+ var launcherListView = findChild(launcher, "launcherListView")
917+ var moveAnimation = findInvisibleChild(launcherListView, "moveAnimation")
918+
919+ for (var i = 0; i < launcherListView.count; i++) {
920+ launcherListView.moveToIndex(i);
921+ waitForRendering(launcherListView);
922+ tryCompare(moveAnimation, "running", false);
923+
924+ var delegate = findChild(launcher, "launcherDelegate" + i);
925+ var surfacePipRepeater = findInvisibleChild(delegate, "surfacePipRepeater");
926+ compare(surfacePipRepeater.model, Math.min(3, LauncherModel.get(i).surfaceCount))
927+ }
928+ }
929 }
930 }

Subscribers

People subscribed via source and target branches