Merge lp:~macslow/unity8/launcher-icon-wobble into lp:unity8
- launcher-icon-wobble
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Michael Zanetti |
Approved revision: | 1840 |
Merged at revision: | 1887 |
Proposed branch: | lp:~macslow/unity8/launcher-icon-wobble |
Merge into: | lp:unity8 |
Diff against target: |
1177 lines (+539/-43) 27 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 (+7/-0) plugins/Greeter/Unity/Launcher/launchermodelas.h (+1/-0) plugins/Unity/Launcher/CMakeLists.txt (+1/-1) plugins/Unity/Launcher/dbusinterface.cpp (+38/-20) plugins/Unity/Launcher/dbusinterface.h (+1/-0) plugins/Unity/Launcher/launcheritem.cpp (+23/-0) plugins/Unity/Launcher/launcheritem.h (+3/-0) plugins/Unity/Launcher/launchermodel.cpp (+32/-2) plugins/Unity/Launcher/launchermodel.h (+3/-1) qml/Launcher/LauncherDelegate.qml (+87/-1) qml/Launcher/LauncherPanel.qml (+75/-4) 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 (+40/-0) tests/mocks/Unity/Launcher/MockLauncherModel.h (+3/-0) tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt (+1/-1) tests/plugins/Unity/Launcher/CMakeLists.txt (+1/-1) tests/plugins/Unity/Launcher/launchermodeltest.cpp (+23/-7) tests/qmltests/Launcher/tst_Launcher.qml (+144/-0) tests/scripts/README (+5/-0) tests/scripts/alert-launcher-icon.sh (+3/-0) tests/scripts/list-launcher-icons.sh (+3/-0) |
To merge this branch: | bzr merge lp:~macslow/unity8/launcher-icon-wobble |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Michael Zanetti (community) | Approve | ||
Albert Astals Cid (community) | tags clean & merges fine | Abstain | |
Review via email: mp+262355@code.launchpad.net |
Commit message
Implemented alert/wiggle feature for launcher-icons.
Description of the change
Implemented alert/wiggle feature for launcher-icons. See http://
* Are there any related MPs required for this MP to build/function as expected? Please list.
Yes.
The branch lp:~macslow/unity-api/launcher-icon-wobble needs to be merged to lp:lp:unity-api first before this can work properly.
* 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.
Lukáš Tinkl (lukas-kde) wrote : | # |
Mirco Müller (macslow) wrote : | # |
> Quick code review, see the inline comments (there are quite some conflicts
> btw)
I'm on it.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1801
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1802
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1804
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
Reading through the animation (line 327 - 343 in the diff), it seems it has a jump from +wiggleAngle to -wiggleAngle. It goes quite fast in the animation so it doesn't look obviously wrong, but looking closely one can see the jump. Is this intended?
Michael Zanetti (mzanetti) wrote : | # |
99 +#include <iostream>
129 + std::cout << "LauncherItem:
We probably don't need this.
=========
526 + panel.visible = true
Two issues here: panel is not within the scope of this QML context (file). Afaict you want to operator on "root" here anyways. But, more importantly, you cannot use an assignent here. This breaks any binding that is acting on "panel.visible" and thus break the optimization of making the launcher invisible when it's outside of the screen. You can see that by running
QSG_VISUALIZE=
As soon as you wobble an item once, the launcher never goes away again, wasting graphics resources.
=======
minor thing: in tryLauncher, can you make the TextField Layout.fillWidth: true, otherwise it's really hard to type in an index > 9.
====
can you add a test that first make an item wiggle & peek, then dragLauncherInt
=======
Doesn't work on index 0 and index 9. Probably because of the "focused" arrow that's painted on those?
Think it's worth adding a test that tries to wiggle all the items one after another, just to make sure we catch all combinations like these?
Michael Zanetti (mzanetti) wrote : | # |
> Doesn't work on index 0 and index 9. Probably because of the "focused" arrow
> that's painted on those?
I just realize this is intended because the focused app never should wiggle, so ignore this...
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1805
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
You have bad tags
Mirco Müller (macslow) wrote : | # |
> You have bad tags
Argl... before I merged my branch with trunk, I checked for stale tags and did not find any. I wonder where these came from... cleaning up now.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1807
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1808
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
The question about the jump in the animation is still open.
===
Also it feels a bit strange that only one icon will wiggle until you revealed the launcher. is that intentional?
Michael Zanetti (mzanetti) wrote : | # |
Oh, also, shouldn't this automatically wiggle when a count emblem changes? Mind hooking it up to that? I think it's just a matter of calling setAlerting(appId, true) in the right places of LauncherModel:
Mirco Müller (macslow) wrote : | # |
> The question about the jump in the animation is still open.
What "jump" do you refer to here? In which context?
> Also it feels a bit strange that only one icon will wiggle until you revealed
> the launcher. is that intentional?
Yes, for the moment. Along the way Design changed some requirements and disambiguated specs upon seeing the implementation in action in presented screencasts. It was agreed to merge what we currently have - to not defer this any longer - and implement the new peeking-policy in a second step. With this new peeking-policy the "wiggle-lock" (requiring a launcher-reveal to unlock) will be loosened up considerably.
Mirco Müller (macslow) wrote : | # |
> Oh, also, shouldn't this automatically wiggle when a count emblem changes?
> Mind hooking it up to that? I think it's just a matter of calling
> setAlerting(appId, true) in the right places of
> LauncherModel:
Sure that's a easy change. Did you verify this with Design? If not I can do that too.
Michael Zanetti (mzanetti) wrote : | # |
> > The question about the jump in the animation is still open.
>
> What "jump" do you refer to here? In which context?
>
Reading through the animation (line 327 - 343 in the diff), it seems it has a jump from +wiggleAngle to -wiggleAngle. It goes quite fast in the animation so it doesn't look obviously wrong, but looking closely one can see the jump. Is this intended?
Michael Zanetti (mzanetti) wrote : | # |
You also need to increase the version dependency in debian/control to depend on the updated libunity-api-dev package
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1809
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1811
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
ok. looks good now.
* 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.
no, unity-api dep bumped
* Did you make sure that the branch does not contain spurious tags?
yes
Michael Zanetti (mzanetti) wrote : | # |
Hmm, seems to not quite work yet.
Testing this in the silo I couldn't get the icon to wobble on incoming notifications.
I did a little digging on why, see inline comments.
Mirco Müller (macslow) wrote : | # |
> Hmm, seems to not quite work yet.
>
> Testing this in the silo I couldn't get the icon to wobble on incoming
> notifications.
>
> I did a little digging on why, see inline comments.
All those are addressed now in r1812.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1812
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
fails tests now :/
Mirco Müller (macslow) wrote : | # |
The reason CI failed is because "libunity-api-dev (>= 7.98)" can't be satisfied yet, as lp:~macslow/unity-api/launcher-icon-wobble is not yet merged to lp:unity-api.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1813
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
Still not working. Icons don't wobble when a notification comes in. I've removed it from the silo.
Mirco Müller (macslow) wrote : | # |
Looking into it.
Albert Astals Cid (aacid) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1815
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
Text conflict in debian/control
1 conflicts encountered.
Mirco Müller (macslow) wrote : | # |
> Text conflict in debian/control
> 1 conflicts encountered.
Fixed with r1816.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1816
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1816
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
still not working :(
* the wiggle animation only works once
* the peeking doesn't work at all (even breaks dragging the launcher)
* You're reaching out of context again from within the LauncherDelegat
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1817
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Mirco Müller (macslow) wrote : | # |
Addressed all but the peeking-animation not working at runtime. Still digging into that.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1819
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Mirco Müller (macslow) wrote : | # |
wiggle-animation working on the device: https:/
Mirco Müller (macslow) wrote : | # |
peeking-animation working on the device: https:/
Michael Zanetti (mzanetti) : | # |
Mirco Müller (macslow) wrote : | # |
Almost everything is addressed in r1825... remaining bits in the works.
Mirco Müller (macslow) wrote : | # |
Everything from the MP-comments addressed in r1828. Still need to update the launcher-icon related qmltests.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1828
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1830
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1831. By Mirco Müller
-
Removed newly added progress-bar assets to make room for reverting initially deleted ones in r1780.
- 1832. By Mirco Müller
-
Reverted deletion of progress-bar assets in r1780.
Mirco Müller (macslow) wrote : | # |
Addressed all issues but the DBus alerting-flag vs DBus alerting-method one.
- 1833. By Mirco Müller
-
Fixed suggestions from MP-comments.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1832
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1833
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1834. By Mirco Müller
-
Changed DBus-interface for launcher-item from alert-flag to alert-method upon request in MP-comment.
- 1835. By Mirco Müller
-
Added some handy shell-scripts for easier runtime-debugging of DBus-APIs on the device.
- 1836. By Mirco Müller
-
Fixed launcher-model unit-test.
- 1837. By Mirco Müller
-
Added unit-test for new DBus-API Alert() of launcher-model.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1834
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
I really was about to approve but because Jenkins doesn't run the tests on this branch I decided to run them manually and it seems there's one that reliably fails in "make xvfbtestLauncher". It does pass in "make testLauncher" tho, so I suspect a missing waitForRendering() somewhere...
FAIL! : qmltestrunner:
Actual (): -64
Expected (): 0
Loc: [/home/
Apart from that it seems to work fine now and I'm happy with the code.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1837
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1838. By Mirco Müller
-
Merged with trunk.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1838
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
Text conflict in qml/Launcher/
1 conflicts encountered.
- 1839. By Mirco Müller
-
Merged with trunk and fixed conflicts.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1839
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1840. By Mirco Müller
-
Fixed failures of xvfbtestLauncher run.
Albert Astals Cid (aacid) : | # |
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.
no, would require unity-api, but tests verified manually.
* Did you make sure that the branch does not contain spurious tags?
yes
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1839
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1840
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1841. By Mirco Müller
-
Merged mzanetti's branch fixing issues for launcher-icons of apps not pinned or running.
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2015-07-09 20:22:36 +0000 |
3 | +++ debian/control 2015-07-25 11:34:57 +0000 |
4 | @@ -30,7 +30,7 @@ |
5 | libqt5xmlpatterns5-dev, |
6 | libsystemsettings-dev, |
7 | libudev-dev, |
8 | - libunity-api-dev (>= 7.97), |
9 | + libunity-api-dev (>= 7.98), |
10 | libusermetricsoutput1-dev, |
11 | libxcb1-dev, |
12 | pkg-config, |
13 | @@ -101,7 +101,7 @@ |
14 | qtdeclarative5-ubuntu-telephony0.1, |
15 | qtdeclarative5-ubuntu-web-plugin, |
16 | ubuntu-system-settings, |
17 | - unity-launcher-impl-4, |
18 | + unity-launcher-impl-7, |
19 | unity8-common (= ${source:Version}), |
20 | unity8-private (= ${binary:Version}), |
21 | unity8-private | unity-launcher-impl, |
22 | @@ -191,7 +191,7 @@ |
23 | ${misc:Depends}, |
24 | ${shlibs:Depends}, |
25 | Provides: unity-launcher-impl, |
26 | - unity-launcher-impl-4, |
27 | + unity-launcher-impl-7, |
28 | Description: Unity 8 private libs |
29 | The Unity 8 shell is the primary user interface for Ubuntu devices. |
30 | . |
31 | |
32 | === modified file 'plugins/Greeter/Unity/Launcher/CMakeLists.txt' |
33 | --- plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-04-24 09:53:37 +0000 |
34 | +++ plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-07-25 11:34:57 +0000 |
35 | @@ -1,4 +1,4 @@ |
36 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6) |
37 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
38 | pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6) |
39 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
40 | |
41 | |
42 | === modified file 'plugins/Greeter/Unity/Launcher/launcheritem.cpp' |
43 | --- plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-02-11 14:02:24 +0000 |
44 | +++ plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-07-25 11:34:57 +0000 |
45 | @@ -31,6 +31,7 @@ |
46 | m_count(0), |
47 | m_countVisible(false), |
48 | m_focused(false), |
49 | + m_alerting(false), |
50 | m_quickList(new QuickListModel(this)) |
51 | { |
52 | QuickListEntry nameAction; |
53 | @@ -165,6 +166,19 @@ |
54 | } |
55 | } |
56 | |
57 | +bool LauncherItem::alerting() const |
58 | +{ |
59 | + return m_alerting; |
60 | +} |
61 | + |
62 | +void LauncherItem::setAlerting(bool alerting) |
63 | +{ |
64 | + if (m_alerting != alerting) { |
65 | + m_alerting = alerting; |
66 | + Q_EMIT alertingChanged(alerting); |
67 | + } |
68 | +} |
69 | + |
70 | unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const |
71 | { |
72 | return m_quickList; |
73 | |
74 | === modified file 'plugins/Greeter/Unity/Launcher/launcheritem.h' |
75 | --- plugins/Greeter/Unity/Launcher/launcheritem.h 2015-02-11 14:02:24 +0000 |
76 | +++ plugins/Greeter/Unity/Launcher/launcheritem.h 2015-07-25 11:34:57 +0000 |
77 | @@ -41,6 +41,7 @@ |
78 | int count() const override; |
79 | bool countVisible() const override; |
80 | bool focused() const override; |
81 | + bool alerting() const override; |
82 | |
83 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
84 | |
85 | @@ -54,6 +55,8 @@ |
86 | void setCount(int count); |
87 | void setCountVisible(bool countVisible); |
88 | void setFocused(bool focused); |
89 | + void setAlerting(bool alerting); |
90 | + |
91 | |
92 | private: |
93 | QString m_appId; |
94 | @@ -66,6 +69,7 @@ |
95 | int m_count; |
96 | bool m_countVisible; |
97 | bool m_focused; |
98 | + bool m_alerting; |
99 | QuickListModel *m_quickList; |
100 | |
101 | friend class LauncherModel; |
102 | |
103 | === modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.cpp' |
104 | --- plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-02-11 14:02:24 +0000 |
105 | +++ plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-07-25 11:34:57 +0000 |
106 | @@ -72,6 +72,13 @@ |
107 | return QVariant(); |
108 | } |
109 | |
110 | +void LauncherModel::setAlerting(const QString &appId, bool alerting) |
111 | +{ |
112 | + Q_UNUSED(appId) |
113 | + Q_UNUSED(alerting) |
114 | + qWarning() << "This is a read only implementation. Cannot set alert-state of items."; |
115 | +} |
116 | + |
117 | unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const |
118 | { |
119 | if (index < 0 || index >= m_list.count()) { |
120 | |
121 | === modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.h' |
122 | --- plugins/Greeter/Unity/Launcher/launchermodelas.h 2015-04-30 09:31:51 +0000 |
123 | +++ plugins/Greeter/Unity/Launcher/launchermodelas.h 2015-07-25 11:34:57 +0000 |
124 | @@ -41,6 +41,7 @@ |
125 | |
126 | QVariant data(const QModelIndex &index, int role) const override; |
127 | |
128 | + Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override; |
129 | Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override; |
130 | Q_INVOKABLE void move(int oldIndex, int newIndex) override; |
131 | Q_INVOKABLE void pin(const QString &appId, int index = -1) override; |
132 | |
133 | === modified file 'plugins/Unity/Launcher/CMakeLists.txt' |
134 | --- plugins/Unity/Launcher/CMakeLists.txt 2015-04-24 09:53:37 +0000 |
135 | +++ plugins/Unity/Launcher/CMakeLists.txt 2015-07-25 11:34:57 +0000 |
136 | @@ -1,4 +1,4 @@ |
137 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6) |
138 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
139 | pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6) |
140 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
141 | |
142 | |
143 | === modified file 'plugins/Unity/Launcher/dbusinterface.cpp' |
144 | --- plugins/Unity/Launcher/dbusinterface.cpp 2015-06-11 23:45:12 +0000 |
145 | +++ plugins/Unity/Launcher/dbusinterface.cpp 2015-07-25 11:34:57 +0000 |
146 | @@ -62,6 +62,7 @@ |
147 | "<interface name=\"com.canonical.Unity.Launcher.Item\">" |
148 | "<property name=\"count\" type=\"i\" access=\"readwrite\" />" |
149 | "<property name=\"countVisible\" type=\"b\" access=\"readwrite\" />" |
150 | + "<method name=\"Alert\" />" |
151 | "</interface>"; |
152 | return nodeiface; |
153 | } |
154 | @@ -122,36 +123,53 @@ |
155 | return false; |
156 | } |
157 | |
158 | - // First handle methods of the Launcher interface |
159 | - if (message.interface() == "com.canonical.Unity.Launcher") { |
160 | - if (message.member() == "Refresh") { |
161 | - QDBusMessage reply = message.createReply(); |
162 | - Q_EMIT refreshCalled(); |
163 | - return connection.send(reply); |
164 | - } |
165 | - } |
166 | - |
167 | - // Now handle dynamic properties (for launcher emblems) |
168 | - if (message.interface() != "org.freedesktop.DBus.Properties") { |
169 | - return false; |
170 | - } |
171 | - |
172 | - if (message.member() != "GetAll" && message.arguments()[0].toString() != "com.canonical.Unity.Launcher.Item") { |
173 | - return false; |
174 | - } |
175 | - |
176 | /* Break down the path to just the app id */ |
177 | + bool validpath = true; |
178 | QString pathtemp = message.path(); |
179 | if (!pathtemp.startsWith("/com/canonical/Unity/Launcher/")) { |
180 | - return false; |
181 | + validpath = false; |
182 | } |
183 | pathtemp.remove("/com/canonical/Unity/Launcher/"); |
184 | if (pathtemp.indexOf('/') >= 0) { |
185 | - return false; |
186 | + validpath = false; |
187 | } |
188 | |
189 | /* Find ourselves an appid */ |
190 | QString appid = decodeAppId(pathtemp); |
191 | + |
192 | + // First handle methods of the Launcher interface |
193 | + if (message.interface() == "com.canonical.Unity.Launcher") { |
194 | + if (message.member() == "Refresh") { |
195 | + QDBusMessage reply = message.createReply(); |
196 | + Q_EMIT refreshCalled(); |
197 | + return connection.send(reply); |
198 | + } |
199 | + } else if (message.interface() == "com.canonical.Unity.Launcher.Item") { |
200 | + // Handle methods of the Launcher-Item interface |
201 | + if (message.member() == "Alert" && validpath) { |
202 | + QDBusMessage reply = message.createReply(); |
203 | + Q_EMIT alertCalled(appid); |
204 | + return connection.send(reply); |
205 | + } |
206 | + } |
207 | + |
208 | + // Now handle dynamic properties (for launcher emblems) |
209 | + if (message.interface() != "org.freedesktop.DBus.Properties") { |
210 | + return false; |
211 | + } |
212 | + |
213 | + if (message.member() == "Get" && (message.arguments().count() != 2 || message.arguments()[0].toString() != "com.canonical.Unity.Launcher.Item")) { |
214 | + return false; |
215 | + } |
216 | + |
217 | + if (message.member() == "Set" && (message.arguments().count() != 3 || message.arguments()[0].toString() != "com.canonical.Unity.Launcher.Item")) { |
218 | + return false; |
219 | + } |
220 | + |
221 | + if (!validpath) { |
222 | + return false; |
223 | + } |
224 | + |
225 | int index = m_launcherModel->findApplication(appid); |
226 | LauncherItem *item = static_cast<LauncherItem*>(m_launcherModel->get(index)); |
227 | |
228 | |
229 | === modified file 'plugins/Unity/Launcher/dbusinterface.h' |
230 | --- plugins/Unity/Launcher/dbusinterface.h 2015-06-11 23:45:12 +0000 |
231 | +++ plugins/Unity/Launcher/dbusinterface.h 2015-07-25 11:34:57 +0000 |
232 | @@ -37,6 +37,7 @@ |
233 | void countChanged(const QString &appId, int count); |
234 | void countVisibleChanged(const QString &appId, bool countVisible); |
235 | void refreshCalled(); |
236 | + void alertCalled(const QString &appId); |
237 | |
238 | private: |
239 | static QString decodeAppId(const QString& path); |
240 | |
241 | === modified file 'plugins/Unity/Launcher/launcheritem.cpp' |
242 | --- plugins/Unity/Launcher/launcheritem.cpp 2014-11-19 17:43:09 +0000 |
243 | +++ plugins/Unity/Launcher/launcheritem.cpp 2015-07-25 11:34:57 +0000 |
244 | @@ -34,6 +34,7 @@ |
245 | m_count(0), |
246 | m_countVisible(false), |
247 | m_focused(false), |
248 | + m_alerting(false), |
249 | m_quickList(new QuickListModel(this)) |
250 | { |
251 | QuickListEntry nameAction; |
252 | @@ -150,6 +151,9 @@ |
253 | if (m_count != count) { |
254 | m_count = count; |
255 | Q_EMIT countChanged(count); |
256 | + if (m_countVisible) { |
257 | + setAlerting(true); |
258 | + } |
259 | } |
260 | } |
261 | |
262 | @@ -163,6 +167,9 @@ |
263 | if (m_countVisible != countVisible) { |
264 | m_countVisible = countVisible; |
265 | Q_EMIT countVisibleChanged(countVisible); |
266 | + if (countVisible) { |
267 | + setAlerting(true); |
268 | + } |
269 | } |
270 | } |
271 | |
272 | @@ -175,10 +182,26 @@ |
273 | { |
274 | if (m_focused != focused) { |
275 | m_focused = focused; |
276 | + if (focused) { |
277 | + setAlerting(false); |
278 | + } |
279 | Q_EMIT focusedChanged(focused); |
280 | } |
281 | } |
282 | |
283 | +bool LauncherItem::alerting() const |
284 | +{ |
285 | + return m_alerting; |
286 | +} |
287 | + |
288 | +void LauncherItem::setAlerting(bool alerting) |
289 | +{ |
290 | + if (m_alerting != alerting) { |
291 | + m_alerting = alerting; |
292 | + Q_EMIT alertingChanged(alerting); |
293 | + } |
294 | +} |
295 | + |
296 | unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const |
297 | { |
298 | return m_quickList; |
299 | |
300 | === modified file 'plugins/Unity/Launcher/launcheritem.h' |
301 | --- plugins/Unity/Launcher/launcheritem.h 2014-09-02 18:22:37 +0000 |
302 | +++ plugins/Unity/Launcher/launcheritem.h 2015-07-25 11:34:57 +0000 |
303 | @@ -44,6 +44,7 @@ |
304 | int count() const override; |
305 | bool countVisible() const override; |
306 | bool focused() const override; |
307 | + bool alerting() const override; |
308 | |
309 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
310 | |
311 | @@ -57,6 +58,7 @@ |
312 | void setCount(int count); |
313 | void setCountVisible(bool countVisible); |
314 | void setFocused(bool focused); |
315 | + void setAlerting(bool alerting); |
316 | |
317 | private: |
318 | QString m_appId; |
319 | @@ -69,6 +71,7 @@ |
320 | int m_count; |
321 | bool m_countVisible; |
322 | bool m_focused; |
323 | + bool m_alerting; |
324 | QuickListModel *m_quickList; |
325 | |
326 | friend class LauncherModel; |
327 | |
328 | === modified file 'plugins/Unity/Launcher/launchermodel.cpp' |
329 | --- plugins/Unity/Launcher/launchermodel.cpp 2015-03-30 17:36:42 +0000 |
330 | +++ plugins/Unity/Launcher/launchermodel.cpp 2015-07-25 11:34:57 +0000 |
331 | @@ -41,6 +41,7 @@ |
332 | connect(m_dbusIface, &DBusInterface::countChanged, this, &LauncherModel::countChanged); |
333 | connect(m_dbusIface, &DBusInterface::countVisibleChanged, this, &LauncherModel::countVisibleChanged); |
334 | connect(m_dbusIface, &DBusInterface::refreshCalled, this, &LauncherModel::refresh); |
335 | + connect(m_dbusIface, &DBusInterface::alertCalled, this, &LauncherModel::alert); |
336 | |
337 | connect(m_settings, &GSettings::changed, this, &LauncherModel::refresh); |
338 | |
339 | @@ -82,11 +83,25 @@ |
340 | return item->progress(); |
341 | case RoleFocused: |
342 | return item->focused(); |
343 | + case RoleAlerting: |
344 | + return item->alerting(); |
345 | } |
346 | |
347 | return QVariant(); |
348 | } |
349 | |
350 | +void LauncherModel::setAlerting(const QString &appId, bool alerting) { |
351 | + int index = findApplication(appId); |
352 | + if (index >= 0) { |
353 | + QModelIndex modelIndex = this->index(index); |
354 | + LauncherItem *item = m_list.at(index); |
355 | + if (!item->focused()) { |
356 | + item->setAlerting(alerting); |
357 | + Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RoleAlerting); |
358 | + } |
359 | + } |
360 | +} |
361 | + |
362 | unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const |
363 | { |
364 | if (index < 0 || index >= m_list.count()) { |
365 | @@ -334,17 +349,23 @@ |
366 | if (idx >= 0) { |
367 | LauncherItem *item = m_list.at(idx); |
368 | item->setCount(count); |
369 | + if (item->countVisible()) { |
370 | + setAlerting(item->appId(), true); |
371 | + } |
372 | Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleCount); |
373 | m_asAdapter->syncItems(m_list); |
374 | } |
375 | } |
376 | |
377 | -void LauncherModel::countVisibleChanged(const QString &appId, int countVisible) |
378 | +void LauncherModel::countVisibleChanged(const QString &appId, bool countVisible) |
379 | { |
380 | int idx = findApplication(appId); |
381 | if (idx >= 0) { |
382 | LauncherItem *item = m_list.at(idx); |
383 | item->setCountVisible(countVisible); |
384 | + if (countVisible) { |
385 | + setAlerting(item->appId(), true); |
386 | + } |
387 | Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleCountVisible); |
388 | |
389 | // If countVisible goes to false, and the item is neither pinned nor recent we can drop it |
390 | @@ -364,7 +385,6 @@ |
391 | beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); |
392 | m_list.append(item); |
393 | endInsertRows(); |
394 | - Q_EMIT hint(); |
395 | } |
396 | } |
397 | m_asAdapter->syncItems(m_list); |
398 | @@ -453,6 +473,16 @@ |
399 | m_asAdapter->syncItems(m_list); |
400 | } |
401 | |
402 | +void LauncherModel::alert(const QString &appId) |
403 | +{ |
404 | + int idx = findApplication(appId); |
405 | + if (idx >= 0) { |
406 | + LauncherItem *item = m_list.at(idx); |
407 | + setAlerting(item->appId(), true); |
408 | + Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleAlerting); |
409 | + } |
410 | +} |
411 | + |
412 | void LauncherModel::applicationAdded(const QModelIndex &parent, int row) |
413 | { |
414 | Q_UNUSED(parent); |
415 | |
416 | === modified file 'plugins/Unity/Launcher/launchermodel.h' |
417 | --- plugins/Unity/Launcher/launchermodel.h 2015-04-30 09:31:51 +0000 |
418 | +++ plugins/Unity/Launcher/launchermodel.h 2015-07-25 11:34:57 +0000 |
419 | @@ -45,6 +45,7 @@ |
420 | |
421 | QVariant data(const QModelIndex &index, int role) const override; |
422 | |
423 | + Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override; |
424 | Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override; |
425 | Q_INVOKABLE void move(int oldIndex, int newIndex) override; |
426 | Q_INVOKABLE void pin(const QString &appId, int index = -1) override; |
427 | @@ -63,6 +64,7 @@ |
428 | public Q_SLOTS: |
429 | void requestRemove(const QString &appId) override; |
430 | Q_INVOKABLE void refresh(); |
431 | + Q_INVOKABLE void alert(const QString &appId); |
432 | |
433 | private: |
434 | void storeAppList(); |
435 | @@ -71,7 +73,7 @@ |
436 | |
437 | private Q_SLOTS: |
438 | void countChanged(const QString &appId, int count); |
439 | - void countVisibleChanged(const QString &appId, int count); |
440 | + void countVisibleChanged(const QString &appId, bool count); |
441 | void progressChanged(const QString &appId, int progress); |
442 | |
443 | void applicationAdded(const QModelIndex &parent, int row); |
444 | |
445 | === modified file 'qml/Launcher/LauncherDelegate.qml' |
446 | --- qml/Launcher/LauncherDelegate.qml 2014-10-14 12:28:07 +0000 |
447 | +++ qml/Launcher/LauncherDelegate.qml 2015-07-25 11:34:57 +0000 |
448 | @@ -15,7 +15,7 @@ |
449 | */ |
450 | |
451 | import QtQuick 2.0 |
452 | -import Ubuntu.Components 0.1 |
453 | +import Ubuntu.Components 1.1 |
454 | |
455 | Item { |
456 | id: root |
457 | @@ -27,6 +27,8 @@ |
458 | property bool itemFocused: false |
459 | property real maxAngle: 0 |
460 | property bool inverted: false |
461 | + property bool alerting: false |
462 | + readonly property alias wiggling: wiggleAnim.running |
463 | |
464 | readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight |
465 | readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight |
466 | @@ -39,6 +41,82 @@ |
467 | property real offset: 0 |
468 | property real itemOpacity: 1 |
469 | property real brightness: 0 |
470 | + property double maxWiggleAngle: 5.0 |
471 | + |
472 | + QtObject { |
473 | + id: priv |
474 | + |
475 | + readonly property int wiggleDuration: UbuntuAnimation.SnapDuration |
476 | + property real wiggleAngle: 0 |
477 | + } |
478 | + |
479 | + SequentialAnimation { |
480 | + id: wiggleAnim |
481 | + |
482 | + running: alerting |
483 | + loops: 1 |
484 | + alwaysRunToEnd: true |
485 | + |
486 | + NumberAnimation { |
487 | + target: priv |
488 | + property: "wiggleAngle" |
489 | + from: 0 |
490 | + to: maxWiggleAngle |
491 | + duration: priv.wiggleDuration |
492 | + easing.type: Easing.InQuad |
493 | + } |
494 | + |
495 | + NumberAnimation { |
496 | + target: priv |
497 | + property: "wiggleAngle" |
498 | + from: maxWiggleAngle |
499 | + to: -maxWiggleAngle |
500 | + duration: priv.wiggleDuration |
501 | + easing.type: Easing.InOutQuad |
502 | + } |
503 | + |
504 | + NumberAnimation { |
505 | + target: priv |
506 | + property: "wiggleAngle" |
507 | + from: -maxWiggleAngle |
508 | + to: maxWiggleAngle |
509 | + duration: priv.wiggleDuration |
510 | + easing.type: Easing.InOutQuad |
511 | + } |
512 | + |
513 | + NumberAnimation { |
514 | + target: priv |
515 | + property: "wiggleAngle" |
516 | + from: maxWiggleAngle |
517 | + to: -maxWiggleAngle |
518 | + duration: priv.wiggleDuration |
519 | + easing.type: Easing.InOutQuad |
520 | + } |
521 | + |
522 | + NumberAnimation { |
523 | + target: priv |
524 | + property: "wiggleAngle" |
525 | + from: -maxWiggleAngle |
526 | + to: maxWiggleAngle |
527 | + duration: priv.wiggleDuration |
528 | + easing.type: Easing.InOutQuad |
529 | + } |
530 | + |
531 | + NumberAnimation { |
532 | + target: priv |
533 | + property: "wiggleAngle" |
534 | + from: maxWiggleAngle |
535 | + to: 0 |
536 | + duration: priv.wiggleDuration |
537 | + easing.type: Easing.OutQuad |
538 | + } |
539 | + |
540 | + UbuntuNumberAnimation { |
541 | + target: root |
542 | + property: "alerting" |
543 | + to: 0 |
544 | + } |
545 | + } |
546 | |
547 | Item { |
548 | id: iconItem |
549 | @@ -167,6 +245,14 @@ |
550 | } |
551 | |
552 | transform: [ |
553 | + // The rotation about the icon's center/z-axis for the wiggle |
554 | + // needs to happen here too, because there's no other way to |
555 | + // align the wiggle with the icon-folding otherwise |
556 | + Rotation { |
557 | + axis { x: 0; y: 0; z: 1 } |
558 | + origin { x: iconItem.width / 2; y: iconItem.height / 2; z: 0 } |
559 | + angle: priv.wiggleAngle |
560 | + }, |
561 | // Rotating 3 times at top/bottom because that increases the perspective. |
562 | // This is a hack, but as QML does not support real 3D coordinates |
563 | // getting a higher perspective can only be done by a hack. This is the most |
564 | |
565 | === modified file 'qml/Launcher/LauncherPanel.qml' |
566 | --- qml/Launcher/LauncherPanel.qml 2015-07-01 11:39:49 +0000 |
567 | +++ qml/Launcher/LauncherPanel.qml 2015-07-25 11:34:57 +0000 |
568 | @@ -86,6 +86,7 @@ |
569 | height: parent.height - dashItem.height - parent.spacing*2 |
570 | |
571 | Item { |
572 | + id: launcherListViewItem |
573 | anchors.fill: parent |
574 | clip: true |
575 | |
576 | @@ -109,6 +110,9 @@ |
577 | preferredHighlightBegin: (height - itemHeight) / 2 |
578 | preferredHighlightEnd: (height + itemHeight) / 2 |
579 | |
580 | + // for the single peeking icon, when alert-state is set on delegate |
581 | + property int peekingIndex: -1 |
582 | + |
583 | // The size of the area the ListView is extended to make sure items are not |
584 | // destroyed when dragging them outside the list. This needs to be at least |
585 | // itemHeight to prevent folded items from disappearing and DragArea limits |
586 | @@ -159,6 +163,17 @@ |
587 | to: launcherListView.contentHeight - launcherListView.height + launcherListView.originY - launcherListView.topMargin |
588 | } |
589 | |
590 | + UbuntuNumberAnimation { |
591 | + id: moveAnimation |
592 | + target: launcherListView |
593 | + property: "contentY" |
594 | + function moveTo(contentY) { |
595 | + from = launcherListView.contentY; |
596 | + to = contentY; |
597 | + start(); |
598 | + } |
599 | + } |
600 | + |
601 | displaced: Transition { |
602 | NumberAnimation { properties: "x,y"; duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
603 | } |
604 | @@ -180,10 +195,67 @@ |
605 | progress: model.progress |
606 | itemFocused: model.focused |
607 | inverted: root.inverted |
608 | + alerting: model.alerting |
609 | z: -Math.abs(offset) |
610 | maxAngle: 55 |
611 | property bool dragging: false |
612 | |
613 | + SequentialAnimation { |
614 | + id: peekingAnimation |
615 | + |
616 | + // revealing |
617 | + PropertyAction { target: root; property: "visible"; value: (launcher.visibleWidth === 0) ? 1 : 0 } |
618 | + PropertyAction { target: launcherListViewItem; property: "clip"; value: 0 } |
619 | + |
620 | + UbuntuNumberAnimation { |
621 | + target: launcherDelegate |
622 | + alwaysRunToEnd: true |
623 | + loops: 1 |
624 | + properties: "x" |
625 | + to: (units.gu(.5) + launcherListView.width * .5) * (root.inverted ? -1 : 1) |
626 | + duration: UbuntuAnimation.BriskDuration |
627 | + } |
628 | + |
629 | + // hiding |
630 | + UbuntuNumberAnimation { |
631 | + target: launcherDelegate |
632 | + alwaysRunToEnd: true |
633 | + loops: 1 |
634 | + properties: "x" |
635 | + to: 0 |
636 | + duration: UbuntuAnimation.BriskDuration |
637 | + } |
638 | + |
639 | + PropertyAction { target: launcherListViewItem; property: "clip"; value: 1 } |
640 | + PropertyAction { target: root; property: "visible"; value: (launcher.visibleWidth === 0) ? 0 : 1 } |
641 | + } |
642 | + |
643 | + onAlertingChanged: { |
644 | + if(alerting) { |
645 | + if (!dragging && (launcherListView.peekingIndex === -1 || launcher.visibleWidth > 0)) { |
646 | + var itemPosition = index * launcherListView.itemHeight; |
647 | + var height = launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin |
648 | + var distanceToEnd = index == 0 || index == launcherListView.count - 1 ? 0 : launcherListView.itemHeight |
649 | + if (itemPosition + launcherListView.itemHeight + distanceToEnd > launcherListView.contentY + launcherListView.topMargin + height) { |
650 | + moveAnimation.moveTo(itemPosition + launcherListView.itemHeight - launcherListView.topMargin - height + distanceToEnd); |
651 | + } else if (itemPosition - distanceToEnd < launcherListView.contentY + launcherListView.topMargin) { |
652 | + moveAnimation.moveTo(itemPosition - distanceToEnd - launcherListView.topMargin); |
653 | + } |
654 | + if (!dragging && launcher.state !== "visible") { |
655 | + peekingAnimation.start() |
656 | + } |
657 | + } |
658 | + |
659 | + if (launcherListView.peekingIndex === -1) { |
660 | + launcherListView.peekingIndex = index |
661 | + } |
662 | + } else { |
663 | + if (launcherListView.peekingIndex === index) { |
664 | + launcherListView.peekingIndex = -1 |
665 | + } |
666 | + } |
667 | + } |
668 | + |
669 | ThinDivider { |
670 | id: dropIndicator |
671 | objectName: "dropIndicator" |
672 | @@ -521,7 +593,7 @@ |
673 | Image { |
674 | anchors { |
675 | left: parent.left |
676 | - leftMargin: quickList.item ? (quickList.item.width - units.gu(1)) / 2 - width / 2 : 0 |
677 | + leftMargin: quickList.item !== undefined ? (quickList.item.width - units.gu(1)) / 2 - width / 2 : 0 |
678 | verticalCenter: parent.verticalCenter |
679 | verticalCenterOffset: (parent.height / 2 + units.dp(3)) * (quickList.offset > 0 ? 1 : -1) * (root.inverted ? 1 : -1) |
680 | } |
681 | @@ -564,10 +636,9 @@ |
682 | |
683 | // internal |
684 | property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1) |
685 | - property int offset: item ? itemCenter + (item.height/2) + height + units.gu(1) > parent.height ? |
686 | + property int offset: item !== undefined ? (itemCenter + (item.height/2) + height + units.gu(1) > parent.height ? |
687 | -(item.height/2) - height - units.gu(.5) : |
688 | - (item.height/2) + units.gu(.5) : |
689 | - 0 |
690 | + (item.height/2) + units.gu(.5)) : 0 |
691 | |
692 | Column { |
693 | id: quickListColumn |
694 | |
695 | === modified file 'tests/mocks/Unity/Launcher/CMakeLists.txt' |
696 | --- tests/mocks/Unity/Launcher/CMakeLists.txt 2015-04-13 09:33:28 +0000 |
697 | +++ tests/mocks/Unity/Launcher/CMakeLists.txt 2015-07-25 11:34:57 +0000 |
698 | @@ -1,4 +1,4 @@ |
699 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6) |
700 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
701 | |
702 | include_directories( |
703 | ${CMAKE_CURRENT_SOURCE_DIR} |
704 | |
705 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp' |
706 | --- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2014-09-03 13:30:52 +0000 |
707 | +++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-07-25 11:34:57 +0000 |
708 | @@ -37,6 +37,7 @@ |
709 | m_count(0), |
710 | m_countVisible(false), |
711 | m_focused(false), |
712 | + m_alerting(false), |
713 | m_quickList(new MockQuickListModel(this)) |
714 | { |
715 | |
716 | @@ -129,6 +130,9 @@ |
717 | { |
718 | m_count = count; |
719 | Q_EMIT countChanged(count); |
720 | + if (m_countVisible) { |
721 | + setAlerting(true); |
722 | + } |
723 | } |
724 | } |
725 | |
726 | @@ -142,6 +146,9 @@ |
727 | if (m_countVisible != countVisible) { |
728 | m_countVisible = countVisible; |
729 | Q_EMIT countVisibleChanged(countVisible); |
730 | + if (countVisible) { |
731 | + setAlerting(true); |
732 | + } |
733 | } |
734 | } |
735 | |
736 | @@ -159,6 +166,18 @@ |
737 | } |
738 | } |
739 | |
740 | +bool MockLauncherItem::alerting() const |
741 | +{ |
742 | + return m_alerting; |
743 | +} |
744 | + |
745 | +void MockLauncherItem::setAlerting(bool alerting) |
746 | +{ |
747 | + if (m_alerting != alerting) { |
748 | + m_alerting = alerting; |
749 | + Q_EMIT alertingChanged(alerting); |
750 | + } |
751 | +} |
752 | |
753 | unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const |
754 | { |
755 | |
756 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h' |
757 | --- tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-04-30 09:31:51 +0000 |
758 | +++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-07-25 11:34:57 +0000 |
759 | @@ -44,6 +44,7 @@ |
760 | int count() const override; |
761 | bool countVisible() const override; |
762 | bool focused() const override; |
763 | + bool alerting() const override; |
764 | |
765 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
766 | |
767 | @@ -55,6 +56,7 @@ |
768 | void setCount(int count); |
769 | void setCountVisible(bool countVisible); |
770 | void setFocused(bool focused); |
771 | + void setAlerting(bool alerting); |
772 | |
773 | QString m_appId; |
774 | QString m_desktopFile; |
775 | @@ -67,6 +69,7 @@ |
776 | int m_count; |
777 | bool m_countVisible; |
778 | bool m_focused; |
779 | + bool m_alerting; |
780 | MockQuickListModel *m_quickList; |
781 | |
782 | friend class MockLauncherModel; |
783 | |
784 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp' |
785 | --- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-03-06 04:44:11 +0000 |
786 | +++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-07-25 11:34:57 +0000 |
787 | @@ -34,6 +34,7 @@ |
788 | item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this); |
789 | item->setProgress(50); |
790 | item->setCountVisible(true); |
791 | + item->setAlerting(false); |
792 | m_list.append(item); |
793 | item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this); |
794 | m_list.append(item); |
795 | @@ -43,25 +44,30 @@ |
796 | item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this); |
797 | item->setCount(1); |
798 | item->setCountVisible(true); |
799 | + item->setAlerting(false); |
800 | m_list.append(item); |
801 | item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this); |
802 | item->setCount(12); |
803 | item->setCountVisible(true); |
804 | + item->setAlerting(false); |
805 | item->setPinned(true); |
806 | m_list.append(item); |
807 | item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail", this); |
808 | item->setCount(123); |
809 | item->setCountVisible(true); |
810 | + item->setAlerting(false); |
811 | m_list.append(item); |
812 | item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather", this); |
813 | item->setCount(1234567890); |
814 | item->setCountVisible(true); |
815 | + item->setAlerting(false); |
816 | item->setPinned(true); |
817 | m_list.append(item); |
818 | item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad", this); |
819 | item->setProgress(50); |
820 | item->setCount(5); |
821 | item->setCountVisible(true); |
822 | + item->setAlerting(false); |
823 | item->setFocused(true); |
824 | item->setPinned(true); |
825 | m_list.append(item); |
826 | @@ -105,6 +111,8 @@ |
827 | return item->countVisible(); |
828 | case RoleFocused: |
829 | return item->focused(); |
830 | + case RoleAlerting: |
831 | + return item->alerting(); |
832 | } |
833 | |
834 | return QVariant(); |
835 | @@ -119,6 +127,18 @@ |
836 | return m_list.at(index); |
837 | } |
838 | |
839 | +void MockLauncherModel::setAlerting(const QString &appId, bool alerting) { |
840 | + int index = findApp(appId); |
841 | + if (index >= 0) { |
842 | + QModelIndex modelIndex = this->index(index); |
843 | + MockLauncherItem *item = m_list.at(index); |
844 | + if (!item->focused()) { |
845 | + item->setAlerting(alerting); |
846 | + Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RoleAlerting); |
847 | + } |
848 | + } |
849 | +} |
850 | + |
851 | void MockLauncherModel::move(int oldIndex, int newIndex) |
852 | { |
853 | // Make sure its not moved outside the lists |
854 | @@ -226,6 +246,26 @@ |
855 | Q_EMIT hint(); |
856 | } |
857 | |
858 | +void MockLauncherModel::setCount(const QString &appId, int count) |
859 | +{ |
860 | + int index = findApp(appId); |
861 | + if (index >= 0) { |
862 | + m_list.at(index)->setCount(count); |
863 | + QModelIndex modelIndex = this->index(index); |
864 | + Q_EMIT dataChanged(modelIndex, modelIndex); |
865 | + } |
866 | +} |
867 | + |
868 | +void MockLauncherModel::setCountVisible(const QString &appId, bool countVisible) |
869 | +{ |
870 | + int index = findApp(appId); |
871 | + if (index >= 0) { |
872 | + m_list.at(index)->setCountVisible(countVisible); |
873 | + QModelIndex modelIndex = this->index(index); |
874 | + Q_EMIT dataChanged(modelIndex, modelIndex); |
875 | + } |
876 | +} |
877 | + |
878 | unity::shell::application::ApplicationManagerInterface *MockLauncherModel::applicationManager() const |
879 | { |
880 | return nullptr; |
881 | |
882 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.h' |
883 | --- tests/mocks/Unity/Launcher/MockLauncherModel.h 2015-04-30 09:31:51 +0000 |
884 | +++ tests/mocks/Unity/Launcher/MockLauncherModel.h 2015-07-25 11:34:57 +0000 |
885 | @@ -38,6 +38,7 @@ |
886 | |
887 | QVariant data(const QModelIndex& index, int role) const override; |
888 | |
889 | + Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override; |
890 | Q_INVOKABLE unity::shell::launcher::LauncherItemInterface *get(int index) const override; |
891 | Q_INVOKABLE void move(int oldIndex, int newIndex) override; |
892 | Q_INVOKABLE void pin(const QString &appId, int index = -1) override; |
893 | @@ -54,6 +55,8 @@ |
894 | |
895 | // For testing |
896 | Q_INVOKABLE void emitHint(); |
897 | + Q_INVOKABLE void setCount(const QString &appId, int count); |
898 | + Q_INVOKABLE void setCountVisible(const QString &appId, bool countVisible); |
899 | |
900 | Q_SIGNALS: |
901 | void quickListTriggered(const QString &appId, int index); |
902 | |
903 | === modified file 'tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt' |
904 | --- tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-06-17 12:14:27 +0000 |
905 | +++ tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-07-25 11:34:57 +0000 |
906 | @@ -1,4 +1,4 @@ |
907 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6) |
908 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
909 | pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=6) |
910 | |
911 | include_directories( |
912 | |
913 | === modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt' |
914 | --- tests/plugins/Unity/Launcher/CMakeLists.txt 2015-06-17 12:14:27 +0000 |
915 | +++ tests/plugins/Unity/Launcher/CMakeLists.txt 2015-07-25 11:34:57 +0000 |
916 | @@ -1,5 +1,5 @@ |
917 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
918 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=6) |
919 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
920 | |
921 | include_directories( |
922 | ${CMAKE_CURRENT_SOURCE_DIR} |
923 | |
924 | === modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp' |
925 | --- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-06-12 16:07:43 +0000 |
926 | +++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-07-25 11:34:57 +0000 |
927 | @@ -368,11 +368,18 @@ |
928 | } |
929 | |
930 | void testCountEmblems() { |
931 | + QSignalSpy spy(launcherModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))); |
932 | + |
933 | // Call GetAll on abs-icon |
934 | QDBusInterface interface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher/abs_2Dicon", "org.freedesktop.DBus.Properties"); |
935 | QDBusReply<QVariantMap> reply = interface.call("GetAll"); |
936 | QVariantMap map = reply.value(); |
937 | |
938 | + // Check that the alerting-status is still false, and the item on the upper side of the API |
939 | + int index = launcherModel->findApplication("abs-icon"); |
940 | + QCOMPARE(index >= 0, true); |
941 | + QVERIFY(launcherModel->get(index)->alerting() == false); |
942 | + |
943 | // Make sure GetAll returns a map with count and countVisible props |
944 | QCOMPARE(map.contains("count"), true); |
945 | QCOMPARE(map.contains("countVisible"), true); |
946 | @@ -393,13 +400,8 @@ |
947 | QCOMPARE(map.value("count").toInt(), 55); |
948 | QCOMPARE(map.value("countVisible").toBool(), true); |
949 | |
950 | - // Now the item on the upper side of the API |
951 | - int index = launcherModel->findApplication("abs-icon"); |
952 | - QCOMPARE(index >= 0, true); |
953 | - |
954 | - // And make sure values have changed there as well |
955 | - QCOMPARE(launcherModel->get(index)->countVisible(), true); |
956 | - QCOMPARE(launcherModel->get(index)->count(), 55); |
957 | + // Finally check, that the change to "count" implicitly also set the alerting-state to true |
958 | + QVERIFY(launcherModel->get(index)->alerting() == true); |
959 | } |
960 | |
961 | void testCountEmblemAddsRemovesItem_data() { |
962 | @@ -459,6 +461,20 @@ |
963 | QCOMPARE(index == -1, !isRunning && !isPinned && !startWhenVisible); |
964 | } |
965 | |
966 | + void testAlert() { |
967 | + // Check that the alerting-status is still false |
968 | + int index = launcherModel->findApplication("abs-icon"); |
969 | + QCOMPARE(index >= 0, true); |
970 | + QVERIFY(launcherModel->get(index)->alerting() == false); |
971 | + |
972 | + // Call Alert() on "abs-icon" |
973 | + QDBusInterface interface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher/abs_2Dicon", "com.canonical.Unity.Launcher.Item"); |
974 | + interface.call("Alert"); |
975 | + |
976 | + // Check that the alerting-status is now true |
977 | + QVERIFY(launcherModel->get(index)->alerting() == true); |
978 | + } |
979 | + |
980 | void testRefreshAfterDeletedDesktopFiles_data() { |
981 | QTest::addColumn<bool>("deleted"); |
982 | QTest::newRow("have .desktop files") << false; |
983 | |
984 | === modified file 'tests/qmltests/Launcher/tst_Launcher.qml' |
985 | --- tests/qmltests/Launcher/tst_Launcher.qml 2015-04-24 09:53:37 +0000 |
986 | +++ tests/qmltests/Launcher/tst_Launcher.qml 2015-07-25 11:34:57 +0000 |
987 | @@ -93,6 +93,31 @@ |
988 | onClicked: launcherLoader.item.inverted = !launcherLoader.item.inverted |
989 | Layout.fillWidth: true |
990 | } |
991 | + |
992 | + Row { |
993 | + spacing: units.gu(1) |
994 | + |
995 | + Button { |
996 | + text: "set alert" |
997 | + onClicked: LauncherModel.setAlerting(LauncherModel.get(parseInt(appIdEntry.displayText)).appId, true) |
998 | + } |
999 | + |
1000 | + TextArea { |
1001 | + id: appIdEntry |
1002 | + anchors.verticalCenter: parent.verticalCenter |
1003 | + width: units.gu(5) |
1004 | + height: units.gu(4) |
1005 | + autoSize: true |
1006 | + text: "2" |
1007 | + maximumLineCount: 1 |
1008 | + Layout.fillWidth: true |
1009 | + } |
1010 | + |
1011 | + Button { |
1012 | + text: "unset alert" |
1013 | + onClicked: LauncherModel.setAlerting(LauncherModel.get(parseInt(appIdEntry.displayText)).appId, false) |
1014 | + } |
1015 | + } |
1016 | } |
1017 | |
1018 | SignalSpy { |
1019 | @@ -169,6 +194,16 @@ |
1020 | tryCompare(panel, "x", -panel.width, 1000); |
1021 | } |
1022 | |
1023 | + function waitForWiggleToStart(appIcon) { |
1024 | + verify(appIcon != undefined) |
1025 | + tryCompare(appIcon, "wiggling", true, 1000, "wiggle-anim should not be in stopped state") |
1026 | + } |
1027 | + |
1028 | + function waitForWiggleToStop(appIcon) { |
1029 | + verify(appIcon != undefined) |
1030 | + tryCompare(appIcon, "wiggling", false, 1000, "wiggle-anim should not be in running state") |
1031 | + } |
1032 | + |
1033 | function positionLauncherListAtBeginning() { |
1034 | var listView = testCase.findChild(launcherLoader.item, "launcherListView"); |
1035 | listView.contentY = -listView.topMargin; |
1036 | @@ -636,5 +671,114 @@ |
1037 | tryCompare(launcher, "state", "", 1000, "Launcher didn't hide after moving mouse away from it"); |
1038 | waitUntilLauncherDisappears(); |
1039 | } |
1040 | + |
1041 | + function test_alertPeekingIcon() { |
1042 | + var listView = findChild(launcher, "launcherListView") |
1043 | + verify(listView != undefined) |
1044 | + LauncherModel.setAlerting(LauncherModel.get(5).appId, true) |
1045 | + tryCompare(listView, "peekingIndex", 5, 1000, "Wrong appId set as peeking-index") |
1046 | + LauncherModel.setAlerting(LauncherModel.get(5).appId, false) |
1047 | + tryCompare(listView, "peekingIndex", -1, 1000, "peeking-index should be -1") |
1048 | + } |
1049 | + |
1050 | + function test_alertHidingIcon() { |
1051 | + var listView = findChild(launcher, "launcherListView") |
1052 | + verify(listView != undefined) |
1053 | + var appIcon6 = findChild(launcher, "launcherDelegate6") |
1054 | + verify(appIcon6 != undefined) |
1055 | + LauncherModel.setAlerting(LauncherModel.get(6).appId, true) |
1056 | + waitForWiggleToStart(appIcon6) |
1057 | + LauncherModel.setAlerting(LauncherModel.get(6).appId, false) |
1058 | + waitForWiggleToStop(appIcon6) |
1059 | + tryCompare(appIcon6, "x", 0, 1000, "x-value of appId #6 should not be non-zero") |
1060 | + waitForRendering(listView) |
1061 | + } |
1062 | + |
1063 | + function test_alertIgnoreFocusedApp() { |
1064 | + LauncherModel.setAlerting(LauncherModel.get(0).appId, true) |
1065 | + compare(LauncherModel.get(0).alerting, false, "Focused app should not have the alert-state set") |
1066 | + } |
1067 | + |
1068 | + function test_alertOnlyOnePeekingIcon() { |
1069 | + var listView = findChild(launcher, "launcherListView") |
1070 | + verify(listView != undefined) |
1071 | + LauncherModel.setAlerting(LauncherModel.get(3).appId, true) |
1072 | + LauncherModel.setAlerting(LauncherModel.get(1).appId, true) |
1073 | + LauncherModel.setAlerting(LauncherModel.get(5).appId, true) |
1074 | + tryCompare(listView, "peekingIndex", 3, 1000, "Wrong appId set as peeking-index") |
1075 | + LauncherModel.setAlerting(LauncherModel.get(1).appId, false) |
1076 | + LauncherModel.setAlerting(LauncherModel.get(3).appId, false) |
1077 | + LauncherModel.setAlerting(LauncherModel.get(5).appId, false) |
1078 | + tryCompare(listView, "peekingIndex", -1, 1000, "peeking-index should be -1") |
1079 | + waitForRendering(listView) |
1080 | + } |
1081 | + |
1082 | + function test_alertMultipleApps() { |
1083 | + LauncherModel.setAlerting(LauncherModel.get(1).appId, true) |
1084 | + LauncherModel.setAlerting(LauncherModel.get(3).appId, true) |
1085 | + LauncherModel.setAlerting(LauncherModel.get(5).appId, true) |
1086 | + LauncherModel.setAlerting(LauncherModel.get(7).appId, true) |
1087 | + compare(LauncherModel.get(1).alerting, true, "Alert-state of appId #1 should not be false") |
1088 | + compare(LauncherModel.get(3).alerting, true, "Alert-state of appId #3 should not be false") |
1089 | + compare(LauncherModel.get(5).alerting, true, "Alert-state of appId #5 should not be false") |
1090 | + compare(LauncherModel.get(7).alerting, true, "Alert-state of appId #7 should not be false") |
1091 | + LauncherModel.setAlerting(LauncherModel.get(1).appId, false) |
1092 | + LauncherModel.setAlerting(LauncherModel.get(3).appId, false) |
1093 | + LauncherModel.setAlerting(LauncherModel.get(5).appId, false) |
1094 | + LauncherModel.setAlerting(LauncherModel.get(7).appId, false) |
1095 | + compare(LauncherModel.get(1).alerting, false, "Alert-state of appId #1 should not be true") |
1096 | + compare(LauncherModel.get(3).alerting, false, "Alert-state of appId #1 should not be true") |
1097 | + compare(LauncherModel.get(5).alerting, false, "Alert-state of appId #1 should not be true") |
1098 | + compare(LauncherModel.get(7).alerting, false, "Alert-state of appId #1 should not be true") |
1099 | + } |
1100 | + |
1101 | + function test_alertMoveIconIntoView() { |
1102 | + dragLauncherIntoView(); |
1103 | + var appIcon1 = findChild(launcher, "launcherDelegate1"); |
1104 | + var appIcon7 = findChild(launcher, "launcherDelegate7"); |
1105 | + LauncherModel.setAlerting(LauncherModel.get(1).appId, true) |
1106 | + tryCompare(appIcon1, "angle", 0, 1000, "angle of appId #1 should not be non-zero") |
1107 | + waitForWiggleToStart(appIcon1) |
1108 | + LauncherModel.setAlerting(LauncherModel.get(7).appId, true) |
1109 | + tryCompare(appIcon7, "angle", 0, 1000, "angle of appId #7 should not be non-zero") |
1110 | + waitForWiggleToStart(appIcon7) |
1111 | + LauncherModel.setAlerting(LauncherModel.get(1).appId, false) |
1112 | + waitForWiggleToStop(appIcon1) |
1113 | + LauncherModel.setAlerting(LauncherModel.get(7).appId, false) |
1114 | + waitForWiggleToStop(appIcon7) |
1115 | + } |
1116 | + |
1117 | + function test_alertWigglePeekDrag() { |
1118 | + var appIcon5 = findChild(launcher, "launcherDelegate5"); |
1119 | + var listView = findChild(launcher, "launcherListView") |
1120 | + verify(listView != undefined) |
1121 | + LauncherModel.setAlerting(LauncherModel.get(5).appId, true) |
1122 | + tryCompare(listView, "peekingIndex", 5, 1000, "Wrong appId set as peeking-index") |
1123 | + waitForWiggleToStart(appIcon5) |
1124 | + tryCompare(appIcon5, "wiggling", true, 1000, "appId #6 should not be still") |
1125 | + dragLauncherIntoView(); |
1126 | + tryCompare(listView, "peekingIndex", -1, 1000, "peeking-index should be -1") |
1127 | + LauncherModel.setAlerting(LauncherModel.get(5).appId, false) |
1128 | + waitForWiggleToStop(appIcon5) |
1129 | + tryCompare(appIcon5, "wiggling", false, 1000, "appId #1 should not be wiggling") |
1130 | + } |
1131 | + |
1132 | + function test_alertViaCountAndCountVisible() { |
1133 | + dragLauncherIntoView(); |
1134 | + var appIcon1 = findChild(launcher, "launcherDelegate1") |
1135 | + var oldCount = LauncherModel.get(1).count |
1136 | + LauncherModel.setCount(LauncherModel.get(1).appId, 42) |
1137 | + tryCompare(appIcon1, "wiggling", false, 1000, "appId #1 should be still") |
1138 | + LauncherModel.setCountVisible(LauncherModel.get(1).appId, 1) |
1139 | + tryCompare(appIcon1, "wiggling", true, 1000, "appId #1 should not be still") |
1140 | + LauncherModel.setAlerting(LauncherModel.get(1).appId, false) |
1141 | + waitForWiggleToStop(appIcon1) |
1142 | + LauncherModel.setCount(LauncherModel.get(1).appId, 4711) |
1143 | + tryCompare(appIcon1, "wiggling", true, 1000, "appId #1 should not be still") |
1144 | + LauncherModel.setAlerting(LauncherModel.get(1).appId, false) |
1145 | + waitForWiggleToStop(appIcon1) |
1146 | + LauncherModel.setCountVisible(LauncherModel.get(1).appId, 0) |
1147 | + LauncherModel.setCount(LauncherModel.get(1).appId, oldCount) |
1148 | + } |
1149 | } |
1150 | } |
1151 | |
1152 | === added directory 'tests/scripts' |
1153 | === added file 'tests/scripts/README' |
1154 | --- tests/scripts/README 1970-01-01 00:00:00 +0000 |
1155 | +++ tests/scripts/README 2015-07-25 11:34:57 +0000 |
1156 | @@ -0,0 +1,5 @@ |
1157 | +This directory holds a few handy shell-scripts to simplify runtime-testing of DBus-APIs (requires qdbus-qt5 to be installed). |
1158 | + |
1159 | +launcher-icon related: |
1160 | + * list-launcher-icons.sh - get all icons of unity8-launcher |
1161 | + * alert-launcher-icon.sh - trigger alert/wiggle of unfocused launcher-icon |
1162 | |
1163 | === added file 'tests/scripts/alert-launcher-icon.sh' |
1164 | --- tests/scripts/alert-launcher-icon.sh 1970-01-01 00:00:00 +0000 |
1165 | +++ tests/scripts/alert-launcher-icon.sh 2015-07-25 11:34:57 +0000 |
1166 | @@ -0,0 +1,3 @@ |
1167 | +#!/bin/sh |
1168 | + |
1169 | +qdbus com.canonical.Unity.Launcher /com/canonical/Unity/Launcher/$1 com.canonical.Unity.Launcher.Item.Alert |
1170 | |
1171 | === added file 'tests/scripts/list-launcher-icons.sh' |
1172 | --- tests/scripts/list-launcher-icons.sh 1970-01-01 00:00:00 +0000 |
1173 | +++ tests/scripts/list-launcher-icons.sh 2015-07-25 11:34:57 +0000 |
1174 | @@ -0,0 +1,3 @@ |
1175 | +#!/bin/sh |
1176 | + |
1177 | +qdbus com.canonical.Unity | grep Launcher | cut -f6 -d/ |
Quick code review, see the inline comments (there are quite some conflicts btw)