Merge lp:~macslow/unity8/use-set-progress-api into lp:unity8

Proposed by Mirco Müller
Status: Superseded
Proposed branch: lp:~macslow/unity8/use-set-progress-api
Merge into: lp:unity8
Diff against target: 1470 lines (+643/-69)
35 files modified
debian/control (+3/-3)
plugins/Greeter/Unity/Launcher/CMakeLists.txt (+1/-1)
plugins/Greeter/Unity/Launcher/launcheritem.cpp (+14/-0)
plugins/Greeter/Unity/Launcher/launcheritem.h (+4/-0)
plugins/Greeter/Unity/Launcher/launchermodelas.cpp (+29/-12)
plugins/Greeter/Unity/Launcher/launchermodelas.h (+1/-0)
plugins/Unity/Launcher/CMakeLists.txt (+1/-1)
plugins/Unity/Launcher/asadapter.cpp (+1/-0)
plugins/Unity/Launcher/dbusinterface.cpp (+39/-13)
plugins/Unity/Launcher/dbusinterface.h (+2/-0)
plugins/Unity/Launcher/launcheritem.cpp (+23/-0)
plugins/Unity/Launcher/launcheritem.h (+3/-0)
plugins/Unity/Launcher/launchermodel.cpp (+32/-0)
plugins/Unity/Launcher/launchermodel.h (+2/-0)
qml/Launcher/LauncherDelegate.qml (+101/-15)
qml/Launcher/LauncherPanel.qml (+74/-4)
qml/Launcher/graphics/progressbar-fill@30.sci (+0/-5)
qml/Launcher/graphics/progressbar-trough@30.sci (+0/-5)
tests/mocks/Unity/Launcher/CMakeLists.txt (+1/-1)
tests/mocks/Unity/Launcher/MockLauncherItem.cpp (+19/-0)
tests/mocks/Unity/Launcher/MockLauncherItem.h (+3/-0)
tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+50/-0)
tests/mocks/Unity/Launcher/MockLauncherModel.h (+4/-0)
tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt (+1/-1)
tests/plugins/Greeter/Unity/Launcher/launchermodelastest.cpp (+3/-0)
tests/plugins/Unity/Launcher/CMakeLists.txt (+1/-1)
tests/plugins/Unity/Launcher/launchermodeltest.cpp (+23/-7)
tests/qmltests/Launcher/tst_Launcher.qml (+181/-0)
tests/scripts/README (+9/-0)
tests/scripts/alert-launcher-icon.sh (+3/-0)
tests/scripts/get-progress.sh (+3/-0)
tests/scripts/list-launcher-icons.sh (+3/-0)
tests/scripts/set-count-visible.sh (+3/-0)
tests/scripts/set-count.sh (+3/-0)
tests/scripts/set-progress.sh (+3/-0)
To merge this branch: bzr merge lp:~macslow/unity8/use-set-progress-api
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Michael Zanetti (community) Approve
Lukáš Tinkl (community) Approve
Nick Dedekind (community) Needs Fixing
Review via email: mp+262448@code.launchpad.net

This proposal has been superseded by a proposal from 2015-07-23.

Commit message

Added corresponding tests and visual tweaks to a launcher-item's progress-overlay.

Description of the change

Added corresponding tests and visual tweaks to a launcher-item's progress-overlay.

For the reviewers convenience here's a screencast of the branch in action on a device: https://www.youtube.com/watch?v=wdP0nYn__uk

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

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

* Did you make sure that your branch does not contain spurious tags?
Yes.

* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Not applicable.

* If you changed the UI, has there been a design review?
Yes.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote :

As I commented on the related unity-api branch, I don't think we need to define an API for that. Unity8 itself doesn't ever set the progress.

* You can then completely revert the change in launchermodeas.

* I haven't tested it yet, but reading through the code it seems you didn't wire up the Set method on D-Bus.

* in asadapter.cpp you need to sync the progress value to AS too.

* in launchermodelas.cpp you need to read the change from AS and set that to the LauncherItems

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

See inline comments

review: Needs Fixing (code-review)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Small comment, otherwise code looks

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

Having a "progressVisible" property only for the test is a bit of overkill. Can you go in on the "progressOverlay" named object with findChild and change visibility.

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

*check visiblilty

Revision history for this message
Mirco Müller (macslow) wrote :

> Having a "progressVisible" property only for the test is a bit of overkill.
> Can you go in on the "progressOverlay" named object with findChild and change
> visibility.

This and inline comment addressed with r1837.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Approving, looks good now

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

No

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

Yes

* Did you make sure that your branch does not contain spurious tags?

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

review: Approve
Revision history for this message
Michael Zanetti (mzanetti) wrote :

> * Did you perform an exploratory manual test run of your code change and any related functionality?
> Yes.

So you did that? Both? How come it doesn't work then?

review: Needs Fixing
1838. By Mirco Müller

Fixed a missing signal-connect and added some handy shell-scripts for easier runtime-debugging of DBus-APIs on the device.

1839. By Mirco Müller

Make sure all changes are carried with the dataChanged signal.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1840. By Mirco Müller

Fixed whitespaces in scripts... added better explanation to helper-script README.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1841. By Mirco Müller

Merged with trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1842. By Mirco Müller

Merged with trunk.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1843. By Mirco Müller

Merged with trunk.

1844. By Mirco Müller

There's no need for the adjusted width anymore for the new progress-bar visuals.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1845. By Mirco Müller

Moving count-emblem to the bottom of launcher-icon to comply with latest design.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote :

"progress" doesn't show up in introspection:

# qdbus com.canonical.Unity /com/canonical/Unity/Launcher/webbrowser_2Dapp
property readwrite int com.canonical.Unity.Launcher.Item.count
property readwrite bool com.canonical.Unity.Launcher.Item.countVisible
signal void org.freedesktop.DBus.Properties.PropertiesChanged(QString interface_name, QVariantMap changed_properties, QStringList invalidated_properties)
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()
method QString org.freedesktop.DBus.Peer.GetMachineId()
method void org.freedesktop.DBus.Peer.Ping()

====

There are some minor inline comments

1846. By Mirco Müller

Made sure progress is properly exposed in DBus-introspection and fixed other suggestions from MP-comments.

Revision history for this message
Michael Zanetti (mzanetti) wrote :

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

as much as it could

 * Did you make sure that the branch does not contain spurious tags?

yes

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1847. By Mirco Müller

Merged launcher-icon-wobble branch and solved all conflicts.

1848. By Mirco Müller

Limit dateChanged only to property that actually changed in the mock.

1849. By Mirco Müller

Merged again with launcher-icon-wobble branch.

1850. By Mirco Müller

Fixed alertViaCountAndCountVisible qmltest.

1851. By Mirco Müller

Sorted out another issue with alertViaCountAndCountVisible qmltest.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2015-07-09 20:22:36 +0000
+++ debian/control 2015-07-23 11:13:36 +0000
@@ -30,7 +30,7 @@
30 libqt5xmlpatterns5-dev,30 libqt5xmlpatterns5-dev,
31 libsystemsettings-dev,31 libsystemsettings-dev,
32 libudev-dev,32 libudev-dev,
33 libunity-api-dev (>= 7.97),33 libunity-api-dev (>= 7.98),
34 libusermetricsoutput1-dev,34 libusermetricsoutput1-dev,
35 libxcb1-dev,35 libxcb1-dev,
36 pkg-config,36 pkg-config,
@@ -101,7 +101,7 @@
101 qtdeclarative5-ubuntu-telephony0.1,101 qtdeclarative5-ubuntu-telephony0.1,
102 qtdeclarative5-ubuntu-web-plugin,102 qtdeclarative5-ubuntu-web-plugin,
103 ubuntu-system-settings,103 ubuntu-system-settings,
104 unity-launcher-impl-4,104 unity-launcher-impl-7,
105 unity8-common (= ${source:Version}),105 unity8-common (= ${source:Version}),
106 unity8-private (= ${binary:Version}),106 unity8-private (= ${binary:Version}),
107 unity8-private | unity-launcher-impl,107 unity8-private | unity-launcher-impl,
@@ -191,7 +191,7 @@
191 ${misc:Depends},191 ${misc:Depends},
192 ${shlibs:Depends},192 ${shlibs:Depends},
193Provides: unity-launcher-impl,193Provides: unity-launcher-impl,
194 unity-launcher-impl-4,194 unity-launcher-impl-7,
195Description: Unity 8 private libs195Description: Unity 8 private libs
196 The Unity 8 shell is the primary user interface for Ubuntu devices.196 The Unity 8 shell is the primary user interface for Ubuntu devices.
197 .197 .
198198
=== modified file 'plugins/Greeter/Unity/Launcher/CMakeLists.txt'
--- plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-04-24 09:53:37 +0000
+++ plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-07-23 11:13:36 +0000
@@ -1,4 +1,4 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6)1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6)2pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6)
3pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)3pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
44
55
=== modified file 'plugins/Greeter/Unity/Launcher/launcheritem.cpp'
--- plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-02-11 14:02:24 +0000
+++ plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-07-23 11:13:36 +0000
@@ -31,6 +31,7 @@
31 m_count(0),31 m_count(0),
32 m_countVisible(false),32 m_countVisible(false),
33 m_focused(false),33 m_focused(false),
34 m_alerting(false),
34 m_quickList(new QuickListModel(this))35 m_quickList(new QuickListModel(this))
35{36{
36 QuickListEntry nameAction;37 QuickListEntry nameAction;
@@ -165,6 +166,19 @@
165 }166 }
166}167}
167168
169bool LauncherItem::alerting() const
170{
171 return m_alerting;
172}
173
174void LauncherItem::setAlerting(bool alerting)
175{
176 if (m_alerting != alerting) {
177 m_alerting = alerting;
178 Q_EMIT alertingChanged(alerting);
179 }
180}
181
168unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const182unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
169{183{
170 return m_quickList;184 return m_quickList;
171185
=== modified file 'plugins/Greeter/Unity/Launcher/launcheritem.h'
--- plugins/Greeter/Unity/Launcher/launcheritem.h 2015-02-11 14:02:24 +0000
+++ plugins/Greeter/Unity/Launcher/launcheritem.h 2015-07-23 11:13:36 +0000
@@ -41,6 +41,7 @@
41 int count() const override;41 int count() const override;
42 bool countVisible() const override;42 bool countVisible() const override;
43 bool focused() const override;43 bool focused() const override;
44 bool alerting() const override;
4445
45 unity::shell::launcher::QuickListModelInterface *quickList() const override;46 unity::shell::launcher::QuickListModelInterface *quickList() const override;
4647
@@ -54,6 +55,8 @@
54 void setCount(int count);55 void setCount(int count);
55 void setCountVisible(bool countVisible);56 void setCountVisible(bool countVisible);
56 void setFocused(bool focused);57 void setFocused(bool focused);
58 void setAlerting(bool alerting);
59
5760
58private:61private:
59 QString m_appId;62 QString m_appId;
@@ -66,6 +69,7 @@
66 int m_count;69 int m_count;
67 bool m_countVisible;70 bool m_countVisible;
68 bool m_focused;71 bool m_focused;
72 bool m_alerting;
69 QuickListModel *m_quickList;73 QuickListModel *m_quickList;
7074
71 friend class LauncherModel;75 friend class LauncherModel;
7276
=== modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.cpp'
--- plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-02-11 14:02:24 +0000
+++ plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-07-23 11:13:36 +0000
@@ -72,6 +72,13 @@
72 return QVariant();72 return QVariant();
73}73}
7474
75void LauncherModel::setAlerting(const QString &appId, bool alerting)
76{
77 Q_UNUSED(appId)
78 Q_UNUSED(alerting)
79 qWarning() << "This is a read only implementation. Cannot set alert-state of items.";
80}
81
75unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const82unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
76{83{
77 if (index < 0 || index >= m_list.count()) {84 if (index < 0 || index >= m_list.count()) {
@@ -200,16 +207,24 @@
200 Q_FOREACH (LauncherItem* item, m_list) {207 Q_FOREACH (LauncherItem* item, m_list) {
201 bool found = false;208 bool found = false;
202 Q_FOREACH(const QVariant &asItem, items) {209 Q_FOREACH(const QVariant &asItem, items) {
203 if (asItem.toMap().value("id").toString() == item->appId()) {210 QVariantMap cachedMap = asItem.toMap();
211 if (cachedMap.value("id").toString() == item->appId()) {
204 // Only keep and update it if we either show unpinned or it is pinned212 // Only keep and update it if we either show unpinned or it is pinned
205 if (!m_onlyPinned || asItem.toMap().value("pinned").toBool()) {213 if (!m_onlyPinned || cachedMap.value("pinned").toBool()) {
206 found = true;214 found = true;
207 item->setName(asItem.toMap().value("name").toString());215 item->setName(cachedMap.value("name").toString());
208 item->setIcon(asItem.toMap().value("icon").toString());216 item->setIcon(cachedMap.value("icon").toString());
209 item->setCount(asItem.toMap().value("count").toInt());217 item->setCount(cachedMap.value("count").toInt());
210 item->setCountVisible(asItem.toMap().value("countVisible").toBool());218 item->setCountVisible(cachedMap.value("countVisible").toBool());
219 item->setProgress(cachedMap.value("progress").toInt());
211 int idx = m_list.indexOf(item);220 int idx = m_list.indexOf(item);
212 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleName << RoleIcon);221 Q_EMIT dataChanged(index(idx),
222 index(idx),
223 {RoleName,
224 RoleIcon,
225 RoleCount,
226 RoleCountVisible,
227 RoleProgress});
213 }228 }
214 break;229 break;
215 }230 }
@@ -247,14 +262,16 @@
247 }262 }
248263
249 if (itemIndex == -1) {264 if (itemIndex == -1) {
265 QVariantMap chachedMap = entry.toMap();
250 // Need to add it. Just add it into the addedIndex to keep same ordering as the list in AS.266 // Need to add it. Just add it into the addedIndex to keep same ordering as the list in AS.
251 LauncherItem *item = new LauncherItem(entry.toMap().value("id").toString(),267 LauncherItem *item = new LauncherItem(chachedMap.value("id").toString(),
252 entry.toMap().value("name").toString(),268 chachedMap.value("name").toString(),
253 entry.toMap().value("icon").toString(),269 chachedMap.value("icon").toString(),
254 this);270 this);
255 item->setPinned(true);271 item->setPinned(true);
256 item->setCount(entry.toMap().value("count").toInt());272 item->setCount(chachedMap.value("count").toInt());
257 item->setCountVisible(entry.toMap().value("countVisible").toBool());273 item->setCountVisible(chachedMap.value("countVisible").toBool());
274 item->setProgress(chachedMap.value("progress").toInt());
258 beginInsertRows(QModelIndex(), newPosition, newPosition);275 beginInsertRows(QModelIndex(), newPosition, newPosition);
259 m_list.insert(newPosition, item);276 m_list.insert(newPosition, item);
260 endInsertRows();277 endInsertRows();
261278
=== modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.h'
--- plugins/Greeter/Unity/Launcher/launchermodelas.h 2015-04-30 09:31:51 +0000
+++ plugins/Greeter/Unity/Launcher/launchermodelas.h 2015-07-23 11:13:36 +0000
@@ -41,6 +41,7 @@
4141
42 QVariant data(const QModelIndex &index, int role) const override;42 QVariant data(const QModelIndex &index, int role) const override;
4343
44 Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override;
44 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override;45 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override;
45 Q_INVOKABLE void move(int oldIndex, int newIndex) override;46 Q_INVOKABLE void move(int oldIndex, int newIndex) override;
46 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;47 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;
4748
=== modified file 'plugins/Unity/Launcher/CMakeLists.txt'
--- plugins/Unity/Launcher/CMakeLists.txt 2015-04-24 09:53:37 +0000
+++ plugins/Unity/Launcher/CMakeLists.txt 2015-07-23 11:13:36 +0000
@@ -1,4 +1,4 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6)1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6)2pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6)
3pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)3pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
44
55
=== modified file 'plugins/Unity/Launcher/asadapter.cpp'
--- plugins/Unity/Launcher/asadapter.cpp 2015-02-11 14:13:26 +0000
+++ plugins/Unity/Launcher/asadapter.cpp 2015-07-23 11:13:36 +0000
@@ -56,5 +56,6 @@
56 details.insert("count", item->count());56 details.insert("count", item->count());
57 details.insert("countVisible", item->countVisible());57 details.insert("countVisible", item->countVisible());
58 details.insert("pinned", item->pinned());58 details.insert("pinned", item->pinned());
59 details.insert("progress", item->progress());
59 return details;60 return details;
60}61}
6162
=== modified file 'plugins/Unity/Launcher/dbusinterface.cpp'
--- plugins/Unity/Launcher/dbusinterface.cpp 2015-06-11 23:45:12 +0000
+++ plugins/Unity/Launcher/dbusinterface.cpp 2015-07-23 11:13:36 +0000
@@ -62,6 +62,8 @@
62 "<interface name=\"com.canonical.Unity.Launcher.Item\">"62 "<interface name=\"com.canonical.Unity.Launcher.Item\">"
63 "<property name=\"count\" type=\"i\" access=\"readwrite\" />"63 "<property name=\"count\" type=\"i\" access=\"readwrite\" />"
64 "<property name=\"countVisible\" type=\"b\" access=\"readwrite\" />"64 "<property name=\"countVisible\" type=\"b\" access=\"readwrite\" />"
65 "<property name=\"progress\" type=\"i\" access=\"readwrite\" />"
66 "<method name=\"Alert\" />"
65 "</interface>";67 "</interface>";
66 return nodeiface;68 return nodeiface;
67}69}
@@ -122,6 +124,20 @@
122 return false;124 return false;
123 }125 }
124126
127 /* Break down the path to just the app id */
128 bool validpath = true;
129 QString pathtemp = message.path();
130 if (!pathtemp.startsWith("/com/canonical/Unity/Launcher/")) {
131 validpath = false;
132 }
133 pathtemp.remove("/com/canonical/Unity/Launcher/");
134 if (pathtemp.indexOf('/') >= 0) {
135 validpath = false;
136 }
137
138 /* Find ourselves an appid */
139 QString appid = decodeAppId(pathtemp);
140
125 // First handle methods of the Launcher interface141 // First handle methods of the Launcher interface
126 if (message.interface() == "com.canonical.Unity.Launcher") {142 if (message.interface() == "com.canonical.Unity.Launcher") {
127 if (message.member() == "Refresh") {143 if (message.member() == "Refresh") {
@@ -129,6 +145,13 @@
129 Q_EMIT refreshCalled();145 Q_EMIT refreshCalled();
130 return connection.send(reply);146 return connection.send(reply);
131 }147 }
148 } else if (message.interface() == "com.canonical.Unity.Launcher.Item") {
149 // Handle methods of the Launcher-Item interface
150 if (message.member() == "Alert" && validpath) {
151 QDBusMessage reply = message.createReply();
152 Q_EMIT alertCalled(appid);
153 return connection.send(reply);
154 }
132 }155 }
133156
134 // Now handle dynamic properties (for launcher emblems)157 // Now handle dynamic properties (for launcher emblems)
@@ -140,50 +163,53 @@
140 return false;163 return false;
141 }164 }
142165
143 /* Break down the path to just the app id */166 if (!validpath) {
144 QString pathtemp = message.path();
145 if (!pathtemp.startsWith("/com/canonical/Unity/Launcher/")) {
146 return false;
147 }
148 pathtemp.remove("/com/canonical/Unity/Launcher/");
149 if (pathtemp.indexOf('/') >= 0) {
150 return false;167 return false;
151 }168 }
152169
153 /* Find ourselves an appid */
154 QString appid = decodeAppId(pathtemp);
155 int index = m_launcherModel->findApplication(appid);170 int index = m_launcherModel->findApplication(appid);
156 LauncherItem *item = static_cast<LauncherItem*>(m_launcherModel->get(index));171 LauncherItem *item = static_cast<LauncherItem*>(m_launcherModel->get(index));
157172
158 QVariantList retval;173 QVariantList retval;
159 if (message.member() == "Get") {174 if (message.member() == "Get") {
175 QString cachedString = message.arguments()[1].toString();
160 if (!item) {176 if (!item) {
161 return false;177 return false;
162 }178 }
163 if (message.arguments()[1].toString() == "count") {179 if (cachedString == "count") {
164 retval.append(QVariant::fromValue(QDBusVariant(item->count())));180 retval.append(QVariant::fromValue(QDBusVariant(item->count())));
165 } else if (message.arguments()[1].toString() == "countVisible") {181 } else if (cachedString == "countVisible") {
166 retval.append(QVariant::fromValue(QDBusVariant(item->countVisible())));182 retval.append(QVariant::fromValue(QDBusVariant(item->countVisible())));
183 } else if (cachedString == "progress") {
184 retval.append(QVariant::fromValue(QDBusVariant(item->progress())));
167 }185 }
168 } else if (message.member() == "Set") {186 } else if (message.member() == "Set") {
169 if (message.arguments()[1].toString() == "count") {187 QString cachedString = message.arguments()[1].toString();
188 if (cachedString == "count") {
170 int newCount = message.arguments()[2].value<QDBusVariant>().variant().toInt();189 int newCount = message.arguments()[2].value<QDBusVariant>().variant().toInt();
171 if (!item || newCount != item->count()) {190 if (!item || newCount != item->count()) {
172 Q_EMIT countChanged(appid, newCount);191 Q_EMIT countChanged(appid, newCount);
173 notifyPropertyChanged("com.canonical.Unity.Launcher.Item", encodeAppId(appid), "count", QVariant(newCount));192 notifyPropertyChanged("com.canonical.Unity.Launcher.Item", encodeAppId(appid), "count", QVariant(newCount));
174 }193 }
175 } else if (message.arguments()[1].toString() == "countVisible") {194 } else if (cachedString == "countVisible") {
176 bool newVisible = message.arguments()[2].value<QDBusVariant>().variant().toBool();195 bool newVisible = message.arguments()[2].value<QDBusVariant>().variant().toBool();
177 if (!item || newVisible != item->countVisible()) {196 if (!item || newVisible != item->countVisible()) {
178 Q_EMIT countVisibleChanged(appid, newVisible);197 Q_EMIT countVisibleChanged(appid, newVisible);
179 notifyPropertyChanged("com.canonical.Unity.Launcher.Item", encodeAppId(appid), "countVisible", newVisible);198 notifyPropertyChanged("com.canonical.Unity.Launcher.Item", encodeAppId(appid), "countVisible", newVisible);
180 }199 }
200 } else if (cachedString == "progress") {
201 int newProgress = message.arguments()[2].value<QDBusVariant>().variant().toInt();
202 if (!item || newProgress != item->progress()) {
203 Q_EMIT progressChanged(appid, newProgress);
204 notifyPropertyChanged("com.canonical.Unity.Launcher.Item", encodeAppId(appid), "progress", QVariant(newProgress));
205 }
181 }206 }
182 } else if (message.member() == "GetAll") {207 } else if (message.member() == "GetAll") {
183 if (item) {208 if (item) {
184 QVariantMap all;209 QVariantMap all;
185 all.insert("count", item->count());210 all.insert("count", item->count());
186 all.insert("countVisible", item->countVisible());211 all.insert("countVisible", item->countVisible());
212 all.insert("progress", item->progress());
187 retval.append(all);213 retval.append(all);
188 }214 }
189 } else {215 } else {
190216
=== modified file 'plugins/Unity/Launcher/dbusinterface.h'
--- plugins/Unity/Launcher/dbusinterface.h 2015-06-11 23:45:12 +0000
+++ plugins/Unity/Launcher/dbusinterface.h 2015-07-23 11:13:36 +0000
@@ -36,7 +36,9 @@
36Q_SIGNALS:36Q_SIGNALS:
37 void countChanged(const QString &appId, int count);37 void countChanged(const QString &appId, int count);
38 void countVisibleChanged(const QString &appId, bool countVisible);38 void countVisibleChanged(const QString &appId, bool countVisible);
39 void progressChanged(const QString &appId, int progress);
39 void refreshCalled();40 void refreshCalled();
41 void alertCalled(const QString &appId);
4042
41private:43private:
42 static QString decodeAppId(const QString& path);44 static QString decodeAppId(const QString& path);
4345
=== modified file 'plugins/Unity/Launcher/launcheritem.cpp'
--- plugins/Unity/Launcher/launcheritem.cpp 2014-11-19 17:43:09 +0000
+++ plugins/Unity/Launcher/launcheritem.cpp 2015-07-23 11:13:36 +0000
@@ -34,6 +34,7 @@
34 m_count(0),34 m_count(0),
35 m_countVisible(false),35 m_countVisible(false),
36 m_focused(false),36 m_focused(false),
37 m_alerting(false),
37 m_quickList(new QuickListModel(this))38 m_quickList(new QuickListModel(this))
38{39{
39 QuickListEntry nameAction;40 QuickListEntry nameAction;
@@ -150,6 +151,9 @@
150 if (m_count != count) {151 if (m_count != count) {
151 m_count = count;152 m_count = count;
152 Q_EMIT countChanged(count);153 Q_EMIT countChanged(count);
154 if (m_countVisible) {
155 setAlerting(true);
156 }
153 }157 }
154}158}
155159
@@ -163,6 +167,9 @@
163 if (m_countVisible != countVisible) {167 if (m_countVisible != countVisible) {
164 m_countVisible = countVisible;168 m_countVisible = countVisible;
165 Q_EMIT countVisibleChanged(countVisible);169 Q_EMIT countVisibleChanged(countVisible);
170 if (countVisible) {
171 setAlerting(true);
172 }
166 }173 }
167}174}
168175
@@ -175,10 +182,26 @@
175{182{
176 if (m_focused != focused) {183 if (m_focused != focused) {
177 m_focused = focused;184 m_focused = focused;
185 if (focused) {
186 setAlerting(false);
187 }
178 Q_EMIT focusedChanged(focused);188 Q_EMIT focusedChanged(focused);
179 }189 }
180}190}
181191
192bool LauncherItem::alerting() const
193{
194 return m_alerting;
195}
196
197void LauncherItem::setAlerting(bool alerting)
198{
199 if (m_alerting != alerting) {
200 m_alerting = alerting;
201 Q_EMIT alertingChanged(alerting);
202 }
203}
204
182unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const205unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
183{206{
184 return m_quickList;207 return m_quickList;
185208
=== modified file 'plugins/Unity/Launcher/launcheritem.h'
--- plugins/Unity/Launcher/launcheritem.h 2014-09-02 18:22:37 +0000
+++ plugins/Unity/Launcher/launcheritem.h 2015-07-23 11:13:36 +0000
@@ -44,6 +44,7 @@
44 int count() const override;44 int count() const override;
45 bool countVisible() const override;45 bool countVisible() const override;
46 bool focused() const override;46 bool focused() const override;
47 bool alerting() const override;
4748
48 unity::shell::launcher::QuickListModelInterface *quickList() const override;49 unity::shell::launcher::QuickListModelInterface *quickList() const override;
4950
@@ -57,6 +58,7 @@
57 void setCount(int count);58 void setCount(int count);
58 void setCountVisible(bool countVisible);59 void setCountVisible(bool countVisible);
59 void setFocused(bool focused);60 void setFocused(bool focused);
61 void setAlerting(bool alerting);
6062
61private:63private:
62 QString m_appId;64 QString m_appId;
@@ -69,6 +71,7 @@
69 int m_count;71 int m_count;
70 bool m_countVisible;72 bool m_countVisible;
71 bool m_focused;73 bool m_focused;
74 bool m_alerting;
72 QuickListModel *m_quickList;75 QuickListModel *m_quickList;
7376
74 friend class LauncherModel;77 friend class LauncherModel;
7578
=== modified file 'plugins/Unity/Launcher/launchermodel.cpp'
--- plugins/Unity/Launcher/launchermodel.cpp 2015-03-30 17:36:42 +0000
+++ plugins/Unity/Launcher/launchermodel.cpp 2015-07-23 11:13:36 +0000
@@ -40,7 +40,9 @@
40{40{
41 connect(m_dbusIface, &DBusInterface::countChanged, this, &LauncherModel::countChanged);41 connect(m_dbusIface, &DBusInterface::countChanged, this, &LauncherModel::countChanged);
42 connect(m_dbusIface, &DBusInterface::countVisibleChanged, this, &LauncherModel::countVisibleChanged);42 connect(m_dbusIface, &DBusInterface::countVisibleChanged, this, &LauncherModel::countVisibleChanged);
43 connect(m_dbusIface, &DBusInterface::progressChanged, this, &LauncherModel::progressChanged);
43 connect(m_dbusIface, &DBusInterface::refreshCalled, this, &LauncherModel::refresh);44 connect(m_dbusIface, &DBusInterface::refreshCalled, this, &LauncherModel::refresh);
45 connect(m_dbusIface, &DBusInterface::alertCalled, this, &LauncherModel::alert);
4446
45 connect(m_settings, &GSettings::changed, this, &LauncherModel::refresh);47 connect(m_settings, &GSettings::changed, this, &LauncherModel::refresh);
4648
@@ -82,11 +84,25 @@
82 return item->progress();84 return item->progress();
83 case RoleFocused:85 case RoleFocused:
84 return item->focused();86 return item->focused();
87 case RoleAlerting:
88 return item->alerting();
85 }89 }
8690
87 return QVariant();91 return QVariant();
88}92}
8993
94void LauncherModel::setAlerting(const QString &appId, bool alerting) {
95 int index = findApplication(appId);
96 if (index >= 0) {
97 QModelIndex modelIndex = this->index(index);
98 LauncherItem *item = m_list.at(index);
99 if (!item->focused()) {
100 item->setAlerting(alerting);
101 Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RoleAlerting);
102 }
103 }
104}
105
90unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const106unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
91{107{
92 if (index < 0 || index >= m_list.count()) {108 if (index < 0 || index >= m_list.count()) {
@@ -334,6 +350,9 @@
334 if (idx >= 0) {350 if (idx >= 0) {
335 LauncherItem *item = m_list.at(idx);351 LauncherItem *item = m_list.at(idx);
336 item->setCount(count);352 item->setCount(count);
353 if (item->countVisible()) {
354 setAlerting(item->appId(), true);
355 }
337 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleCount);356 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleCount);
338 m_asAdapter->syncItems(m_list);357 m_asAdapter->syncItems(m_list);
339 }358 }
@@ -345,6 +364,9 @@
345 if (idx >= 0) {364 if (idx >= 0) {
346 LauncherItem *item = m_list.at(idx);365 LauncherItem *item = m_list.at(idx);
347 item->setCountVisible(countVisible);366 item->setCountVisible(countVisible);
367 if (countVisible) {
368 setAlerting(item->appId(), true);
369 }
348 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleCountVisible);370 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleCountVisible);
349371
350 // If countVisible goes to false, and the item is neither pinned nor recent we can drop it372 // If countVisible goes to false, and the item is neither pinned nor recent we can drop it
@@ -453,6 +475,16 @@
453 m_asAdapter->syncItems(m_list);475 m_asAdapter->syncItems(m_list);
454}476}
455477
478void LauncherModel::alert(const QString &appId)
479{
480 int idx = findApplication(appId);
481 if (idx >= 0) {
482 LauncherItem *item = m_list.at(idx);
483 setAlerting(item->appId(), true);
484 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleAlerting);
485 }
486}
487
456void LauncherModel::applicationAdded(const QModelIndex &parent, int row)488void LauncherModel::applicationAdded(const QModelIndex &parent, int row)
457{489{
458 Q_UNUSED(parent);490 Q_UNUSED(parent);
459491
=== modified file 'plugins/Unity/Launcher/launchermodel.h'
--- plugins/Unity/Launcher/launchermodel.h 2015-04-30 09:31:51 +0000
+++ plugins/Unity/Launcher/launchermodel.h 2015-07-23 11:13:36 +0000
@@ -45,6 +45,7 @@
4545
46 QVariant data(const QModelIndex &index, int role) const override;46 QVariant data(const QModelIndex &index, int role) const override;
4747
48 Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override;
48 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override;49 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override;
49 Q_INVOKABLE void move(int oldIndex, int newIndex) override;50 Q_INVOKABLE void move(int oldIndex, int newIndex) override;
50 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;51 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;
@@ -63,6 +64,7 @@
63public Q_SLOTS:64public Q_SLOTS:
64 void requestRemove(const QString &appId) override;65 void requestRemove(const QString &appId) override;
65 Q_INVOKABLE void refresh();66 Q_INVOKABLE void refresh();
67 Q_INVOKABLE void alert(const QString &appId);
6668
67private:69private:
68 void storeAppList();70 void storeAppList();
6971
=== modified file 'qml/Launcher/LauncherDelegate.qml'
--- qml/Launcher/LauncherDelegate.qml 2014-10-14 12:28:07 +0000
+++ qml/Launcher/LauncherDelegate.qml 2015-07-23 11:13:36 +0000
@@ -15,7 +15,7 @@
15 */15 */
1616
17import QtQuick 2.017import QtQuick 2.0
18import Ubuntu.Components 0.118import Ubuntu.Components 1.1
1919
20Item {20Item {
21 id: root21 id: root
@@ -27,6 +27,8 @@
27 property bool itemFocused: false27 property bool itemFocused: false
28 property real maxAngle: 028 property real maxAngle: 0
29 property bool inverted: false29 property bool inverted: false
30 property bool alerting: false
31 readonly property alias wiggling: wiggleAnim.running
3032
31 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight33 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
32 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight34 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
@@ -39,6 +41,82 @@
39 property real offset: 041 property real offset: 0
40 property real itemOpacity: 142 property real itemOpacity: 1
41 property real brightness: 043 property real brightness: 0
44 property double maxWiggleAngle: 5.0
45
46 QtObject {
47 id: priv
48
49 readonly property int wiggleDuration: UbuntuAnimation.SnapDuration
50 property real wiggleAngle: 0
51 }
52
53 SequentialAnimation {
54 id: wiggleAnim
55
56 running: alerting
57 loops: 1
58 alwaysRunToEnd: true
59
60 NumberAnimation {
61 target: priv
62 property: "wiggleAngle"
63 from: 0
64 to: maxWiggleAngle
65 duration: priv.wiggleDuration
66 easing.type: Easing.InQuad
67 }
68
69 NumberAnimation {
70 target: priv
71 property: "wiggleAngle"
72 from: maxWiggleAngle
73 to: -maxWiggleAngle
74 duration: priv.wiggleDuration
75 easing.type: Easing.InOutQuad
76 }
77
78 NumberAnimation {
79 target: priv
80 property: "wiggleAngle"
81 from: -maxWiggleAngle
82 to: maxWiggleAngle
83 duration: priv.wiggleDuration
84 easing.type: Easing.InOutQuad
85 }
86
87 NumberAnimation {
88 target: priv
89 property: "wiggleAngle"
90 from: maxWiggleAngle
91 to: -maxWiggleAngle
92 duration: priv.wiggleDuration
93 easing.type: Easing.InOutQuad
94 }
95
96 NumberAnimation {
97 target: priv
98 property: "wiggleAngle"
99 from: -maxWiggleAngle
100 to: maxWiggleAngle
101 duration: priv.wiggleDuration
102 easing.type: Easing.InOutQuad
103 }
104
105 NumberAnimation {
106 target: priv
107 property: "wiggleAngle"
108 from: maxWiggleAngle
109 to: 0
110 duration: priv.wiggleDuration
111 easing.type: Easing.OutQuad
112 }
113
114 UbuntuNumberAnimation {
115 target: root
116 property: "alerting"
117 to: 0
118 }
119 }
42120
43 Item {121 Item {
44 id: iconItem122 id: iconItem
@@ -75,7 +153,7 @@
75 objectName: "countEmblem"153 objectName: "countEmblem"
76 anchors {154 anchors {
77 right: parent.right155 right: parent.right
78 top: parent.top156 bottom: parent.bottom
79 margins: units.dp(3)157 margins: units.dp(3)
80 }158 }
81 width: Math.min(root.itemWidth, Math.max(units.gu(2), countLabel.implicitWidth + units.gu(1)))159 width: Math.min(root.itemWidth, Math.max(units.gu(2), countLabel.implicitWidth + units.gu(1)))
@@ -100,23 +178,21 @@
100 }178 }
101 }179 }
102180
103 BorderImage {181 UbuntuShape {
104 id: progressOverlay182 id: progressOverlay
105 objectName: "progressOverlay"183 objectName: "progressOverlay"
184
106 anchors {185 anchors {
107 left: iconItem.left186 left: iconItem.left
108 right: iconItem.right187 right: iconItem.right
109 bottom: iconItem.bottom188 verticalCenter: parent.verticalCenter
110 leftMargin: units.gu(1)189 leftMargin: units.gu(1.5)
111 rightMargin: units.gu(1)190 rightMargin: units.gu(1.5)
112 bottomMargin: units.gu(1)
113 }191 }
114 height: units.gu(1.5)192 height: units.gu(1)
115 visible: root.progress > -1193 visible: root.progress > -1
116 source: "graphics/progressbar-trough.sci"194 color: UbuntuColors.darkGrey
117195 borderSource: "none"
118 // For fill calculation we need to remove the 2 units of border defined in .sci file
119 property int adjustedWidth: width - units.gu(2)
120196
121 Item {197 Item {
122 anchors {198 anchors {
@@ -124,20 +200,22 @@
124 top: parent.top200 top: parent.top
125 bottom: parent.bottom201 bottom: parent.bottom
126 }202 }
127 width: Math.min(100, root.progress) / 100 * parent.adjustedWidth + units.gu(1)203 width: Math.min(100, root.progress) / 100 * parent.width
128 clip: true204 clip: true
129205
130 BorderImage {206 UbuntuShape {
131 anchors {207 anchors {
132 left: parent.left208 left: parent.left
133 top: parent.top209 top: parent.top
134 bottom: parent.bottom210 bottom: parent.bottom
135 }211 }
212 color: "white"
213 borderSource: "none"
136 width: progressOverlay.width214 width: progressOverlay.width
137 source: "graphics/progressbar-fill.sci"
138 }215 }
139 }216 }
140 }217 }
218
141 Image {219 Image {
142 objectName: "focusedHighlight"220 objectName: "focusedHighlight"
143 anchors {221 anchors {
@@ -167,6 +245,14 @@
167 }245 }
168246
169 transform: [247 transform: [
248 // The rotation about the icon's center/z-axis for the wiggle
249 // needs to happen here too, because there's no other way to
250 // align the wiggle with the icon-folding otherwise
251 Rotation {
252 axis { x: 0; y: 0; z: 1 }
253 origin { x: iconItem.width / 2; y: iconItem.height / 2; z: 0 }
254 angle: priv.wiggleAngle
255 },
170 // Rotating 3 times at top/bottom because that increases the perspective.256 // Rotating 3 times at top/bottom because that increases the perspective.
171 // This is a hack, but as QML does not support real 3D coordinates257 // This is a hack, but as QML does not support real 3D coordinates
172 // getting a higher perspective can only be done by a hack. This is the most258 // getting a higher perspective can only be done by a hack. This is the most
173259
=== modified file 'qml/Launcher/LauncherPanel.qml'
--- qml/Launcher/LauncherPanel.qml 2015-07-01 11:39:49 +0000
+++ qml/Launcher/LauncherPanel.qml 2015-07-23 11:13:36 +0000
@@ -86,6 +86,7 @@
86 height: parent.height - dashItem.height - parent.spacing*286 height: parent.height - dashItem.height - parent.spacing*2
8787
88 Item {88 Item {
89 id: launcherListViewItem
89 anchors.fill: parent90 anchors.fill: parent
90 clip: true91 clip: true
9192
@@ -109,12 +110,21 @@
109 preferredHighlightBegin: (height - itemHeight) / 2110 preferredHighlightBegin: (height - itemHeight) / 2
110 preferredHighlightEnd: (height + itemHeight) / 2111 preferredHighlightEnd: (height + itemHeight) / 2
111112
113 // for the single peeking icon, when alert-state is set on delegate
114 property int peekingIndex: -1
115
112 // The size of the area the ListView is extended to make sure items are not116 // The size of the area the ListView is extended to make sure items are not
113 // destroyed when dragging them outside the list. This needs to be at least117 // destroyed when dragging them outside the list. This needs to be at least
114 // itemHeight to prevent folded items from disappearing and DragArea limits118 // itemHeight to prevent folded items from disappearing and DragArea limits
115 // need to be smaller than this size to avoid breakage.119 // need to be smaller than this size to avoid breakage.
116 property int extensionSize: 0120 property int extensionSize: 0
117121
122 // These properties are needed to facilitate implicitly unfolding the
123 // launcher to the peeking icon, if it is not already fully flat
124 // and in view for the user
125 property real moveToIndexYFrom
126 property real moveToIndexYTo
127
118 // Setting extensionSize after the list has been populated because it has128 // Setting extensionSize after the list has been populated because it has
119 // the potential to mess up with the intial positioning in combination129 // the potential to mess up with the intial positioning in combination
120 // with snapping to the center of the list. This catches all the cases130 // with snapping to the center of the list. This catches all the cases
@@ -128,6 +138,14 @@
128 flick(0, clickFlickSpeed)138 flick(0, clickFlickSpeed)
129 }139 }
130140
141 UbuntuNumberAnimation {
142 id: moveToIndexAnimation
143 target: launcherListView
144 property: "contentY"
145 from: launcherListView.moveToIndexYFrom
146 to: launcherListView.moveToIndexYTo
147 }
148
131 // The height of the area where icons start getting folded149 // The height of the area where icons start getting folded
132 property int foldingStartHeight: units.gu(6.5)150 property int foldingStartHeight: units.gu(6.5)
133 // The height of the area where the items reach the final folding angle151 // The height of the area where the items reach the final folding angle
@@ -180,10 +198,63 @@
180 progress: model.progress198 progress: model.progress
181 itemFocused: model.focused199 itemFocused: model.focused
182 inverted: root.inverted200 inverted: root.inverted
201 alerting: model.alerting
183 z: -Math.abs(offset)202 z: -Math.abs(offset)
184 maxAngle: 55203 maxAngle: 55
185 property bool dragging: false204 property bool dragging: false
186205
206 SequentialAnimation {
207 id: peekingAnimation
208
209 // revealing
210 PropertyAction { target: root; property: "visible"; value: (launcher.visibleWidth === 0) ? 1 : 0 }
211 PropertyAction { target: launcherListViewItem; property: "clip"; value: 0 }
212
213 UbuntuNumberAnimation {
214 target: launcherDelegate
215 alwaysRunToEnd: true
216 loops: 1
217 properties: "x"
218 to: (units.gu(.5) + launcherListView.width * .5) * (root.inverted ? -1 : 1)
219 duration: UbuntuAnimation.BriskDuration
220 }
221
222 // hiding
223 UbuntuNumberAnimation {
224 target: launcherDelegate
225 alwaysRunToEnd: true
226 loops: 1
227 properties: "x"
228 to: 0
229 duration: UbuntuAnimation.BriskDuration
230 }
231
232 PropertyAction { target: launcherListViewItem; property: "clip"; value: 1 }
233 PropertyAction { target: root; property: "visible"; value: (launcher.visibleWidth === 0) ? 0 : 1 }
234 }
235
236 onAlertingChanged: {
237 if(alerting) {
238 if (!dragging && (launcherListView.peekingIndex === -1 || launcher.visibleWidth > 0)) {
239 launcherListView.moveToIndexYFrom = launcherListView.contentY
240 launcherListView.positionViewAtIndex(index, ListView.Center)
241 launcherListView.moveToIndexYTo = launcherListView.contentY
242 moveToIndexAnimation.start()
243 if (!dragging && launcher.state !== "visible") {
244 peekingAnimation.start()
245 }
246 }
247
248 if (launcherListView.peekingIndex === -1) {
249 launcherListView.peekingIndex = index
250 }
251 } else {
252 if (launcherListView.peekingIndex === index) {
253 launcherListView.peekingIndex = -1
254 }
255 }
256 }
257
187 ThinDivider {258 ThinDivider {
188 id: dropIndicator259 id: dropIndicator
189 objectName: "dropIndicator"260 objectName: "dropIndicator"
@@ -521,7 +592,7 @@
521 Image {592 Image {
522 anchors {593 anchors {
523 left: parent.left594 left: parent.left
524 leftMargin: quickList.item ? (quickList.item.width - units.gu(1)) / 2 - width / 2 : 0595 leftMargin: quickList.item !== undefined ? (quickList.item.width - units.gu(1)) / 2 - width / 2 : 0
525 verticalCenter: parent.verticalCenter596 verticalCenter: parent.verticalCenter
526 verticalCenterOffset: (parent.height / 2 + units.dp(3)) * (quickList.offset > 0 ? 1 : -1) * (root.inverted ? 1 : -1)597 verticalCenterOffset: (parent.height / 2 + units.dp(3)) * (quickList.offset > 0 ? 1 : -1) * (root.inverted ? 1 : -1)
527 }598 }
@@ -564,10 +635,9 @@
564635
565 // internal636 // internal
566 property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1)637 property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1)
567 property int offset: item ? itemCenter + (item.height/2) + height + units.gu(1) > parent.height ?638 property int offset: item !== undefined ? (itemCenter + (item.height/2) + height + units.gu(1) > parent.height ?
568 -(item.height/2) - height - units.gu(.5) :639 -(item.height/2) - height - units.gu(.5) :
569 (item.height/2) + units.gu(.5) :640 (item.height/2) + units.gu(.5)) : 0
570 0
571641
572 Column {642 Column {
573 id: quickListColumn643 id: quickListColumn
574644
=== removed file 'qml/Launcher/graphics/progressbar-fill@30.png'
575Binary files qml/Launcher/graphics/progressbar-fill@30.png 2013-08-19 19:34:03 +0000 and qml/Launcher/graphics/progressbar-fill@30.png 1970-01-01 00:00:00 +0000 differ645Binary files qml/Launcher/graphics/progressbar-fill@30.png 2013-08-19 19:34:03 +0000 and qml/Launcher/graphics/progressbar-fill@30.png 1970-01-01 00:00:00 +0000 differ
=== removed file 'qml/Launcher/graphics/progressbar-fill@30.sci'
--- qml/Launcher/graphics/progressbar-fill@30.sci 2013-08-19 19:34:03 +0000
+++ qml/Launcher/graphics/progressbar-fill@30.sci 1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
1border.left: 36
2border.top: 16
3border.bottom: 28
4border.right: 36
5source: progressbar-fill@30.png
6\ No newline at end of file0\ No newline at end of file
71
=== removed file 'qml/Launcher/graphics/progressbar-trough@30.png'
8Binary files qml/Launcher/graphics/progressbar-trough@30.png 2013-08-19 19:34:03 +0000 and qml/Launcher/graphics/progressbar-trough@30.png 1970-01-01 00:00:00 +0000 differ2Binary files qml/Launcher/graphics/progressbar-trough@30.png 2013-08-19 19:34:03 +0000 and qml/Launcher/graphics/progressbar-trough@30.png 1970-01-01 00:00:00 +0000 differ
=== removed file 'qml/Launcher/graphics/progressbar-trough@30.sci'
--- qml/Launcher/graphics/progressbar-trough@30.sci 2013-08-19 19:34:03 +0000
+++ qml/Launcher/graphics/progressbar-trough@30.sci 1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
1border.left: 36
2border.top: 16
3border.bottom: 26
4border.right: 36
5source: progressbar-trough@30.png
6\ No newline at end of file0\ No newline at end of file
71
=== modified file 'tests/mocks/Unity/Launcher/CMakeLists.txt'
--- tests/mocks/Unity/Launcher/CMakeLists.txt 2015-04-13 09:33:28 +0000
+++ tests/mocks/Unity/Launcher/CMakeLists.txt 2015-07-23 11:13:36 +0000
@@ -1,4 +1,4 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6)1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
22
3include_directories(3include_directories(
4 ${CMAKE_CURRENT_SOURCE_DIR}4 ${CMAKE_CURRENT_SOURCE_DIR}
55
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp'
--- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2014-09-03 13:30:52 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-07-23 11:13:36 +0000
@@ -37,6 +37,7 @@
37 m_count(0),37 m_count(0),
38 m_countVisible(false),38 m_countVisible(false),
39 m_focused(false),39 m_focused(false),
40 m_alerting(false),
40 m_quickList(new MockQuickListModel(this))41 m_quickList(new MockQuickListModel(this))
41{42{
4243
@@ -129,6 +130,9 @@
129 {130 {
130 m_count = count;131 m_count = count;
131 Q_EMIT countChanged(count);132 Q_EMIT countChanged(count);
133 if (m_countVisible) {
134 setAlerting(true);
135 }
132 }136 }
133}137}
134138
@@ -142,6 +146,9 @@
142 if (m_countVisible != countVisible) {146 if (m_countVisible != countVisible) {
143 m_countVisible = countVisible;147 m_countVisible = countVisible;
144 Q_EMIT countVisibleChanged(countVisible);148 Q_EMIT countVisibleChanged(countVisible);
149 if (countVisible) {
150 setAlerting(true);
151 }
145 }152 }
146}153}
147154
@@ -159,6 +166,18 @@
159 }166 }
160}167}
161168
169bool MockLauncherItem::alerting() const
170{
171 return m_alerting;
172}
173
174void MockLauncherItem::setAlerting(bool alerting)
175{
176 if (m_alerting != alerting) {
177 m_alerting = alerting;
178 Q_EMIT alertingChanged(alerting);
179 }
180}
162181
163unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const182unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const
164{183{
165184
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h'
--- tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-04-30 09:31:51 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-07-23 11:13:36 +0000
@@ -44,6 +44,7 @@
44 int count() const override;44 int count() const override;
45 bool countVisible() const override;45 bool countVisible() const override;
46 bool focused() const override;46 bool focused() const override;
47 bool alerting() const override;
4748
48 unity::shell::launcher::QuickListModelInterface *quickList() const override;49 unity::shell::launcher::QuickListModelInterface *quickList() const override;
4950
@@ -55,6 +56,7 @@
55 void setCount(int count);56 void setCount(int count);
56 void setCountVisible(bool countVisible);57 void setCountVisible(bool countVisible);
57 void setFocused(bool focused);58 void setFocused(bool focused);
59 void setAlerting(bool alerting);
5860
59 QString m_appId;61 QString m_appId;
60 QString m_desktopFile;62 QString m_desktopFile;
@@ -67,6 +69,7 @@
67 int m_count;69 int m_count;
68 bool m_countVisible;70 bool m_countVisible;
69 bool m_focused;71 bool m_focused;
72 bool m_alerting;
70 MockQuickListModel *m_quickList;73 MockQuickListModel *m_quickList;
7174
72 friend class MockLauncherModel;75 friend class MockLauncherModel;
7376
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp'
--- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-03-06 04:44:11 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-07-23 11:13:36 +0000
@@ -34,6 +34,7 @@
34 item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this);34 item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this);
35 item->setProgress(50);35 item->setProgress(50);
36 item->setCountVisible(true);36 item->setCountVisible(true);
37 item->setAlerting(false);
37 m_list.append(item);38 m_list.append(item);
38 item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this);39 item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this);
39 m_list.append(item);40 m_list.append(item);
@@ -43,25 +44,30 @@
43 item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this);44 item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this);
44 item->setCount(1);45 item->setCount(1);
45 item->setCountVisible(true);46 item->setCountVisible(true);
47 item->setAlerting(false);
46 m_list.append(item);48 m_list.append(item);
47 item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this);49 item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this);
48 item->setCount(12);50 item->setCount(12);
49 item->setCountVisible(true);51 item->setCountVisible(true);
52 item->setAlerting(false);
50 item->setPinned(true);53 item->setPinned(true);
51 m_list.append(item);54 m_list.append(item);
52 item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail", this);55 item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail", this);
53 item->setCount(123);56 item->setCount(123);
54 item->setCountVisible(true);57 item->setCountVisible(true);
58 item->setAlerting(false);
55 m_list.append(item);59 m_list.append(item);
56 item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather", this);60 item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather", this);
57 item->setCount(1234567890);61 item->setCount(1234567890);
58 item->setCountVisible(true);62 item->setCountVisible(true);
63 item->setAlerting(false);
59 item->setPinned(true);64 item->setPinned(true);
60 m_list.append(item);65 m_list.append(item);
61 item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad", this);66 item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad", this);
62 item->setProgress(50);67 item->setProgress(50);
63 item->setCount(5);68 item->setCount(5);
64 item->setCountVisible(true);69 item->setCountVisible(true);
70 item->setAlerting(false);
65 item->setFocused(true);71 item->setFocused(true);
66 item->setPinned(true);72 item->setPinned(true);
67 m_list.append(item);73 m_list.append(item);
@@ -105,6 +111,8 @@
105 return item->countVisible();111 return item->countVisible();
106 case RoleFocused:112 case RoleFocused:
107 return item->focused();113 return item->focused();
114 case RoleAlerting:
115 return item->alerting();
108 }116 }
109117
110 return QVariant();118 return QVariant();
@@ -119,6 +127,18 @@
119 return m_list.at(index);127 return m_list.at(index);
120}128}
121129
130void MockLauncherModel::setAlerting(const QString &appId, bool alerting) {
131 int index = findApp(appId);
132 if (index >= 0) {
133 QModelIndex modelIndex = this->index(index);
134 MockLauncherItem *item = m_list.at(index);
135 if (!item->focused()) {
136 item->setAlerting(alerting);
137 Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RoleAlerting);
138 }
139 }
140}
141
122void MockLauncherModel::move(int oldIndex, int newIndex)142void MockLauncherModel::move(int oldIndex, int newIndex)
123{143{
124 // Make sure its not moved outside the lists144 // Make sure its not moved outside the lists
@@ -195,6 +215,16 @@
195 return -1;215 return -1;
196}216}
197217
218void MockLauncherModel::setProgress(const QString &appId, int progress)
219{
220 int index = findApp(appId);
221 if (index >= 0) {
222 m_list.at(index)->setProgress(progress);
223 QModelIndex modelIndex = this->index(index);
224 Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RoleProgress);
225 }
226}
227
198void MockLauncherModel::setUser(const QString &username)228void MockLauncherModel::setUser(const QString &username)
199{229{
200 Q_UNUSED(username)230 Q_UNUSED(username)
@@ -226,6 +256,26 @@
226 Q_EMIT hint();256 Q_EMIT hint();
227}257}
228258
259void MockLauncherModel::setCount(const QString &appId, int count)
260{
261 int index = findApp(appId);
262 if (index >= 0) {
263 m_list.at(index)->setCount(count);
264 QModelIndex modelIndex = this->index(index);
265 Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RoleCount);
266 }
267}
268
269void MockLauncherModel::setCountVisible(const QString &appId, bool countVisible)
270{
271 int index = findApp(appId);
272 if (index >= 0) {
273 m_list.at(index)->setCountVisible(countVisible);
274 QModelIndex modelIndex = this->index(index);
275 Q_EMIT dataChanged(modelIndex, modelIndex);
276 }
277}
278
229unity::shell::application::ApplicationManagerInterface *MockLauncherModel::applicationManager() const279unity::shell::application::ApplicationManagerInterface *MockLauncherModel::applicationManager() const
230{280{
231 return nullptr;281 return nullptr;
232282
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.h'
--- tests/mocks/Unity/Launcher/MockLauncherModel.h 2015-04-30 09:31:51 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherModel.h 2015-07-23 11:13:36 +0000
@@ -38,6 +38,7 @@
3838
39 QVariant data(const QModelIndex& index, int role) const override;39 QVariant data(const QModelIndex& index, int role) const override;
4040
41 Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override;
41 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface *get(int index) const override;42 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface *get(int index) const override;
42 Q_INVOKABLE void move(int oldIndex, int newIndex) override;43 Q_INVOKABLE void move(int oldIndex, int newIndex) override;
43 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;44 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;
@@ -54,6 +55,9 @@
5455
55 // For testing56 // For testing
56 Q_INVOKABLE void emitHint();57 Q_INVOKABLE void emitHint();
58 Q_INVOKABLE void setProgress(const QString &appId, int progress);
59 Q_INVOKABLE void setCount(const QString &appId, int count);
60 Q_INVOKABLE void setCountVisible(const QString &appId, bool countVisible);
5761
58Q_SIGNALS:62Q_SIGNALS:
59 void quickListTriggered(const QString &appId, int index);63 void quickListTriggered(const QString &appId, int index);
6064
=== modified file 'tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt'
--- tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-06-17 12:14:27 +0000
+++ tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-07-23 11:13:36 +0000
@@ -1,4 +1,4 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6)1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6)2pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6)
33
4include_directories(4include_directories(
55
=== modified file 'tests/plugins/Greeter/Unity/Launcher/launchermodelastest.cpp'
--- tests/plugins/Greeter/Unity/Launcher/launchermodelastest.cpp 2015-02-11 14:11:26 +0000
+++ tests/plugins/Greeter/Unity/Launcher/launchermodelastest.cpp 2015-07-23 11:13:36 +0000
@@ -43,6 +43,7 @@
43 item.insert("name", "Item 1");43 item.insert("name", "Item 1");
44 item.insert("icon", "fake.svg");44 item.insert("icon", "fake.svg");
45 item.insert("count", 0);45 item.insert("count", 0);
46 item.insert("progress", 0);
46 item.insert("countVisible", false);47 item.insert("countVisible", false);
47 item.insert("pinned", true);48 item.insert("pinned", true);
48 list.append(item);49 list.append(item);
@@ -67,6 +68,7 @@
67 inSync &= model->get(i)->name() == list.at(i).value("name").toString();68 inSync &= model->get(i)->name() == list.at(i).value("name").toString();
68 inSync &= model->get(i)->icon() == list.at(i).value("icon").toString();69 inSync &= model->get(i)->icon() == list.at(i).value("icon").toString();
69 inSync &= model->get(i)->count() == list.at(i).value("count").toInt();70 inSync &= model->get(i)->count() == list.at(i).value("count").toInt();
71 inSync &= model->get(i)->progress() == list.at(i).value("progress").toInt();
70 inSync &= model->get(i)->countVisible() == list.at(i).value("countVisible").toBool();72 inSync &= model->get(i)->countVisible() == list.at(i).value("countVisible").toBool();
71 }73 }
72 return inSync;74 return inSync;
@@ -111,6 +113,7 @@
111 newEntry.insert("name", "New app");113 newEntry.insert("name", "New app");
112 newEntry.insert("icon", "some-icon.svg");114 newEntry.insert("icon", "some-icon.svg");
113 newEntry.insert("count", 0);115 newEntry.insert("count", 0);
116 newEntry.insert("progress", 42);
114 newEntry.insert("countVisible", false);117 newEntry.insert("countVisible", false);
115 newEntry.insert("pinned", true);118 newEntry.insert("pinned", true);
116 newList.append(newEntry);119 newList.append(newEntry);
117120
=== modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt'
--- tests/plugins/Unity/Launcher/CMakeLists.txt 2015-06-17 12:14:27 +0000
+++ tests/plugins/Unity/Launcher/CMakeLists.txt 2015-07-23 11:13:36 +0000
@@ -1,5 +1,5 @@
1pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)1pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
2pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6)2pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
33
4include_directories(4include_directories(
5 ${CMAKE_CURRENT_SOURCE_DIR}5 ${CMAKE_CURRENT_SOURCE_DIR}
66
=== modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp'
--- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-06-12 16:07:43 +0000
+++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-07-23 11:13:36 +0000
@@ -368,11 +368,18 @@
368 }368 }
369369
370 void testCountEmblems() {370 void testCountEmblems() {
371 QSignalSpy spy(launcherModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
372
371 // Call GetAll on abs-icon373 // Call GetAll on abs-icon
372 QDBusInterface interface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher/abs_2Dicon", "org.freedesktop.DBus.Properties");374 QDBusInterface interface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher/abs_2Dicon", "org.freedesktop.DBus.Properties");
373 QDBusReply<QVariantMap> reply = interface.call("GetAll");375 QDBusReply<QVariantMap> reply = interface.call("GetAll");
374 QVariantMap map = reply.value();376 QVariantMap map = reply.value();
375377
378 // Check that the alerting-status is still false, and the item on the upper side of the API
379 int index = launcherModel->findApplication("abs-icon");
380 QCOMPARE(index >= 0, true);
381 QVERIFY(launcherModel->get(index)->alerting() == false);
382
376 // Make sure GetAll returns a map with count and countVisible props383 // Make sure GetAll returns a map with count and countVisible props
377 QCOMPARE(map.contains("count"), true);384 QCOMPARE(map.contains("count"), true);
378 QCOMPARE(map.contains("countVisible"), true);385 QCOMPARE(map.contains("countVisible"), true);
@@ -393,13 +400,8 @@
393 QCOMPARE(map.value("count").toInt(), 55);400 QCOMPARE(map.value("count").toInt(), 55);
394 QCOMPARE(map.value("countVisible").toBool(), true);401 QCOMPARE(map.value("countVisible").toBool(), true);
395402
396 // Now the item on the upper side of the API403 // Finally check, that the change to "count" implicitly also set the alerting-state to true
397 int index = launcherModel->findApplication("abs-icon");404 QVERIFY(launcherModel->get(index)->alerting() == true);
398 QCOMPARE(index >= 0, true);
399
400 // And make sure values have changed there as well
401 QCOMPARE(launcherModel->get(index)->countVisible(), true);
402 QCOMPARE(launcherModel->get(index)->count(), 55);
403 }405 }
404406
405 void testCountEmblemAddsRemovesItem_data() {407 void testCountEmblemAddsRemovesItem_data() {
@@ -459,6 +461,20 @@
459 QCOMPARE(index == -1, !isRunning && !isPinned && !startWhenVisible);461 QCOMPARE(index == -1, !isRunning && !isPinned && !startWhenVisible);
460 }462 }
461463
464 void testAlert() {
465 // Check that the alerting-status is still false
466 int index = launcherModel->findApplication("abs-icon");
467 QCOMPARE(index >= 0, true);
468 QVERIFY(launcherModel->get(index)->alerting() == false);
469
470 // Call Alert() on "abs-icon"
471 QDBusInterface interface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher/abs_2Dicon", "com.canonical.Unity.Launcher.Item");
472 interface.call("Alert");
473
474 // Check that the alerting-status is now true
475 QVERIFY(launcherModel->get(index)->alerting() == true);
476 }
477
462 void testRefreshAfterDeletedDesktopFiles_data() {478 void testRefreshAfterDeletedDesktopFiles_data() {
463 QTest::addColumn<bool>("deleted");479 QTest::addColumn<bool>("deleted");
464 QTest::newRow("have .desktop files") << false;480 QTest::newRow("have .desktop files") << false;
465481
=== modified file 'tests/qmltests/Launcher/tst_Launcher.qml'
--- tests/qmltests/Launcher/tst_Launcher.qml 2015-04-24 09:53:37 +0000
+++ tests/qmltests/Launcher/tst_Launcher.qml 2015-07-23 11:13:36 +0000
@@ -93,6 +93,57 @@
93 onClicked: launcherLoader.item.inverted = !launcherLoader.item.inverted93 onClicked: launcherLoader.item.inverted = !launcherLoader.item.inverted
94 Layout.fillWidth: true94 Layout.fillWidth: true
95 }95 }
96
97 Row {
98 spacing: units.gu(1)
99
100 Button {
101 text: "35% bar"
102 onClicked: LauncherModel.setProgress(LauncherModel.get(parseInt(appIdEntryBar.displayText)).appId, 35)
103 Layout.fillWidth: true
104 }
105
106 TextArea {
107 id: appIdEntryBar
108 anchors.verticalCenter: parent.verticalCenter
109 width: units.gu(4)
110 height: units.gu(4)
111 autoSize: true
112 text: "2"
113 maximumLineCount: 1
114 }
115
116 Button {
117 text: "no bar"
118 onClicked: LauncherModel.setProgress(LauncherModel.get(parseInt(appIdEntryBar.displayText)).appId, -1)
119 Layout.fillWidth: true
120 }
121 }
122
123 Row {
124 spacing: units.gu(1)
125
126 Button {
127 text: "set alert"
128 onClicked: LauncherModel.setAlerting(LauncherModel.get(parseInt(appIdEntryAlert.displayText)).appId, true)
129 }
130
131 TextArea {
132 id: appIdEntryAlert
133 anchors.verticalCenter: parent.verticalCenter
134 width: units.gu(5)
135 height: units.gu(4)
136 autoSize: true
137 text: "2"
138 maximumLineCount: 1
139 Layout.fillWidth: true
140 }
141
142 Button {
143 text: "unset alert"
144 onClicked: LauncherModel.setAlerting(LauncherModel.get(parseInt(appIdEntryAlert.displayText)).appId, false)
145 }
146 }
96 }147 }
97148
98 SignalSpy {149 SignalSpy {
@@ -169,6 +220,16 @@
169 tryCompare(panel, "x", -panel.width, 1000);220 tryCompare(panel, "x", -panel.width, 1000);
170 }221 }
171222
223 function waitForWiggleToStart(appIcon) {
224 verify(appIcon != undefined)
225 tryCompare(appIcon, "wiggling", true, 1000, "wiggle-anim should not be in stopped state")
226 }
227
228 function waitForWiggleToStop(appIcon) {
229 verify(appIcon != undefined)
230 tryCompare(appIcon, "wiggling", false, 1000, "wiggle-anim should not be in running state")
231 }
232
172 function positionLauncherListAtBeginning() {233 function positionLauncherListAtBeginning() {
173 var listView = testCase.findChild(launcherLoader.item, "launcherListView");234 var listView = testCase.findChild(launcherLoader.item, "launcherListView");
174 listView.contentY = -listView.topMargin;235 listView.contentY = -listView.topMargin;
@@ -636,5 +697,125 @@
636 tryCompare(launcher, "state", "", 1000, "Launcher didn't hide after moving mouse away from it");697 tryCompare(launcher, "state", "", 1000, "Launcher didn't hide after moving mouse away from it");
637 waitUntilLauncherDisappears();698 waitUntilLauncherDisappears();
638 }699 }
700
701 function test_progressChangeViaModel() {
702 dragLauncherIntoView();
703 var item = findChild(launcher, "launcherDelegate0")
704 verify(item != undefined)
705 LauncherModel.setProgress(LauncherModel.get(0).appId, -1)
706 compare(findChild(item, "progressOverlay").visible, false)
707 LauncherModel.setProgress(LauncherModel.get(0).appId, 20)
708 compare(findChild(item, "progressOverlay").visible, true)
709 LauncherModel.setProgress(LauncherModel.get(0).appId, 0)
710 }
711
712 function test_alertPeekingIcon() {
713 var listView = findChild(launcher, "launcherListView")
714 verify(listView != undefined)
715 LauncherModel.setAlerting(LauncherModel.get(5).appId, true)
716 tryCompare(listView, "peekingIndex", 5, 1000, "Wrong appId set as peeking-index")
717 LauncherModel.setAlerting(LauncherModel.get(5).appId, false)
718 tryCompare(listView, "peekingIndex", -1, 1000, "peeking-index should be -1")
719 }
720
721 function test_alertHidingIcon() {
722 var listView = findChild(launcher, "launcherListView")
723 verify(listView != undefined)
724 var appIcon6 = findChild(launcher, "launcherDelegate6")
725 verify(appIcon6 != undefined)
726 LauncherModel.setAlerting(LauncherModel.get(6).appId, true)
727 waitForWiggleToStart(appIcon6)
728 LauncherModel.setAlerting(LauncherModel.get(6).appId, false)
729 waitForWiggleToStop(appIcon6)
730 tryCompare(appIcon6, "x", 0, 1000, "x-value of appId #6 should not be non-zero")
731 waitForRendering(listView)
732 }
733
734 function test_alertIgnoreFocusedApp() {
735 LauncherModel.setAlerting(LauncherModel.get(0).appId, true)
736 compare(LauncherModel.get(0).alerting, false, "Focused app should not have the alert-state set")
737 }
738
739 function test_alertOnlyOnePeekingIcon() {
740 var listView = findChild(launcher, "launcherListView")
741 verify(listView != undefined)
742 LauncherModel.setAlerting(LauncherModel.get(3).appId, true)
743 LauncherModel.setAlerting(LauncherModel.get(1).appId, true)
744 LauncherModel.setAlerting(LauncherModel.get(5).appId, true)
745 tryCompare(listView, "peekingIndex", 3, 1000, "Wrong appId set as peeking-index")
746 LauncherModel.setAlerting(LauncherModel.get(1).appId, false)
747 LauncherModel.setAlerting(LauncherModel.get(3).appId, false)
748 LauncherModel.setAlerting(LauncherModel.get(5).appId, false)
749 tryCompare(listView, "peekingIndex", -1, 1000, "peeking-index should be -1")
750 waitForRendering(listView)
751 }
752
753 function test_alertMultipleApps() {
754 LauncherModel.setAlerting(LauncherModel.get(1).appId, true)
755 LauncherModel.setAlerting(LauncherModel.get(3).appId, true)
756 LauncherModel.setAlerting(LauncherModel.get(5).appId, true)
757 LauncherModel.setAlerting(LauncherModel.get(7).appId, true)
758 compare(LauncherModel.get(1).alerting, true, "Alert-state of appId #1 should not be false")
759 compare(LauncherModel.get(3).alerting, true, "Alert-state of appId #3 should not be false")
760 compare(LauncherModel.get(5).alerting, true, "Alert-state of appId #5 should not be false")
761 compare(LauncherModel.get(7).alerting, true, "Alert-state of appId #7 should not be false")
762 LauncherModel.setAlerting(LauncherModel.get(1).appId, false)
763 LauncherModel.setAlerting(LauncherModel.get(3).appId, false)
764 LauncherModel.setAlerting(LauncherModel.get(5).appId, false)
765 LauncherModel.setAlerting(LauncherModel.get(7).appId, false)
766 compare(LauncherModel.get(1).alerting, false, "Alert-state of appId #1 should not be true")
767 compare(LauncherModel.get(3).alerting, false, "Alert-state of appId #1 should not be true")
768 compare(LauncherModel.get(5).alerting, false, "Alert-state of appId #1 should not be true")
769 compare(LauncherModel.get(7).alerting, false, "Alert-state of appId #1 should not be true")
770 }
771
772 function test_alertMoveIconIntoView() {
773 dragLauncherIntoView();
774 var appIcon1 = findChild(launcher, "launcherDelegate1");
775 var appIcon7 = findChild(launcher, "launcherDelegate7");
776 LauncherModel.setAlerting(LauncherModel.get(1).appId, true)
777 tryCompare(appIcon1, "angle", 0, 1000, "angle of appId #1 should not be non-zero")
778 waitForWiggleToStart(appIcon1)
779 LauncherModel.setAlerting(LauncherModel.get(7).appId, true)
780 tryCompare(appIcon7, "angle", 0, 1000, "angle of appId #7 should not be non-zero")
781 waitForWiggleToStart(appIcon7)
782 LauncherModel.setAlerting(LauncherModel.get(1).appId, false)
783 waitForWiggleToStop(appIcon1)
784 LauncherModel.setAlerting(LauncherModel.get(7).appId, false)
785 waitForWiggleToStop(appIcon7)
786 }
787
788 function test_alertWigglePeekDrag() {
789 var appIcon5 = findChild(launcher, "launcherDelegate5");
790 var listView = findChild(launcher, "launcherListView")
791 verify(listView != undefined)
792 LauncherModel.setAlerting(LauncherModel.get(5).appId, true)
793 tryCompare(listView, "peekingIndex", 5, 1000, "Wrong appId set as peeking-index")
794 waitForWiggleToStart(appIcon5)
795 tryCompare(appIcon5, "wiggling", true, 1000, "appId #6 should not be still")
796 dragLauncherIntoView();
797 tryCompare(listView, "peekingIndex", -1, 1000, "peeking-index should be -1")
798 LauncherModel.setAlerting(LauncherModel.get(5).appId, false)
799 waitForWiggleToStop(appIcon5)
800 tryCompare(appIcon5, "wiggling", false, 1000, "appId #1 should not be wiggling")
801 }
802
803 function test_alertViaCountAndCountVisible() {
804 dragLauncherIntoView();
805 var appIcon1 = findChild(launcher, "launcherDelegate1")
806 var oldCount = LauncherModel.get(1).count
807 LauncherModel.setCount(LauncherModel.get(1).appId, 42)
808 tryCompare(appIcon1, "wiggling", false, 1000, "appId #1 should be still")
809 LauncherModel.setCountVisible(LauncherModel.get(1).appId, 1)
810 tryCompare(appIcon1, "wiggling", true, 1000, "appId #1 should not be still")
811 LauncherModel.setAlerting(LauncherModel.get(1).appId, false)
812 waitForWiggleToStop(appIcon1)
813 LauncherModel.setCount(LauncherModel.get(1).appId, 4711)
814 tryCompare(appIcon1, "wiggling", true, 1000, "appId #1 should not be still")
815 LauncherModel.setAlerting(LauncherModel.get(1).appId, false)
816 waitForWiggleToStop(appIcon1)
817 LauncherModel.setCountVisible(LauncherModel.get(1).appId, 0)
818 LauncherModel.setCount(LauncherModel.get(1).appId, oldCount)
819 }
639 }820 }
640}821}
641822
=== added directory 'tests/scripts'
=== added file 'tests/scripts/README'
--- tests/scripts/README 1970-01-01 00:00:00 +0000
+++ tests/scripts/README 2015-07-23 11:13:36 +0000
@@ -0,0 +1,9 @@
1This directory holds a few handy shell-scripts to simplify runtime-testing of DBus-APIs (requires qdbus-qt5 to be installed).
2
3launcher-icon related:
4 * list-launcher-icons.sh - get all icons of unity8-launcher
5 * alert-launcher-icon.sh - trigger alert/wiggle of unfocused launcher-icon
6 * get-progress.sh - get progress-value of a launcher-icon
7 * set-progress.sh - set progress-value of a launcher-icon
8 * set-count.sh - set the count of a launcher-icon
9 * set-count-visible.sh - set the count-visible flag of a launcher-icon
010
=== added file 'tests/scripts/alert-launcher-icon.sh'
--- tests/scripts/alert-launcher-icon.sh 1970-01-01 00:00:00 +0000
+++ tests/scripts/alert-launcher-icon.sh 2015-07-23 11:13:36 +0000
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3qdbus com.canonical.Unity.Launcher /com/canonical/Unity/Launcher/$1 com.canonical.Unity.Launcher.Item.Alert
04
=== added file 'tests/scripts/get-progress.sh'
--- tests/scripts/get-progress.sh 1970-01-01 00:00:00 +0000
+++ tests/scripts/get-progress.sh 2015-07-23 11:13:36 +0000
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3qdbus com.canonical.Unity.Launcher /com/canonical/Unity/Launcher/$1 org.freedesktop.DBus.Properties.Get com.canonical.Unity.Launcher.Item progress
04
=== added file 'tests/scripts/list-launcher-icons.sh'
--- tests/scripts/list-launcher-icons.sh 1970-01-01 00:00:00 +0000
+++ tests/scripts/list-launcher-icons.sh 2015-07-23 11:13:36 +0000
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3qdbus com.canonical.Unity | grep Launcher | cut -f6 -d/
04
=== added file 'tests/scripts/set-count-visible.sh'
--- tests/scripts/set-count-visible.sh 1970-01-01 00:00:00 +0000
+++ tests/scripts/set-count-visible.sh 2015-07-23 11:13:36 +0000
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3qdbus com.canonical.Unity.Launcher /com/canonical/Unity/Launcher/$1 org.freedesktop.DBus.Properties.Set com.canonical.Unity.Launcher.Item countVisible $2
04
=== added file 'tests/scripts/set-count.sh'
--- tests/scripts/set-count.sh 1970-01-01 00:00:00 +0000
+++ tests/scripts/set-count.sh 2015-07-23 11:13:36 +0000
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3qdbus com.canonical.Unity.Launcher /com/canonical/Unity/Launcher/$1 org.freedesktop.DBus.Properties.Set com.canonical.Unity.Launcher.Item count $2
04
=== added file 'tests/scripts/set-progress.sh'
--- tests/scripts/set-progress.sh 1970-01-01 00:00:00 +0000
+++ tests/scripts/set-progress.sh 2015-07-23 11:13:36 +0000
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3qdbus com.canonical.Unity.Launcher /com/canonical/Unity/Launcher/$1 org.freedesktop.DBus.Properties.Set com.canonical.Unity.Launcher.Item progress $2

Subscribers

People subscribed via source and target branches