Merge lp:~lukas-kde/unity8/closeAppsFromQuicklist into lp:unity8

Proposed by Lukáš Tinkl
Status: Merged
Approved by: Michael Zanetti
Approved revision: 1826
Merged at revision: 1889
Proposed branch: lp:~lukas-kde/unity8/closeAppsFromQuicklist
Merge into: lp:unity8
Prerequisite: lp:~macslow/unity8/use-set-progress-api
Diff against target: 788 lines (+198/-71)
17 files modified
plugins/Greeter/Unity/Launcher/launchermodelas.cpp (+13/-14)
plugins/Unity/Launcher/asadapter.cpp (+3/-2)
plugins/Unity/Launcher/asadapter.h (+1/-4)
plugins/Unity/Launcher/gsettings.cpp (+1/-1)
plugins/Unity/Launcher/launcheritem.cpp (+10/-0)
plugins/Unity/Launcher/launcheritem.h (+1/-0)
plugins/Unity/Launcher/launchermodel.cpp (+45/-24)
plugins/Unity/Launcher/quicklistentry.cpp (+6/-2)
plugins/Unity/Launcher/quicklistentry.h (+3/-1)
plugins/Unity/Launcher/quicklistmodel.cpp (+12/-1)
plugins/Unity/Launcher/quicklistmodel.h (+3/-1)
qml/Launcher/LauncherPanel.qml (+22/-13)
tests/mocks/Unity/Launcher/MockLauncherItem.cpp (+3/-0)
tests/mocks/Unity/Launcher/MockLauncherItem.h (+1/-0)
tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+4/-1)
tests/plugins/Unity/Launcher/launchermodeltest.cpp (+41/-0)
tests/qmltests/Launcher/tst_Launcher.qml (+29/-7)
To merge this branch: bzr merge lp:~lukas-kde/unity8/closeAppsFromQuicklist
Reviewer Review Type Date Requested Status
Michael Zanetti (community) Approve
Daniel d'Andrada Pending
PS Jenkins bot continuous-integration Pending
Albert Astals Cid tags clean & merges fine Pending
Review via email: mp+265669@code.launchpad.net

This proposal supersedes a proposal from 2015-06-18.

Commit message

launcher parity: close apps from quicklist

Description of the change

launcher parity: close apps from quicklist

- adds a Quit item to the launcher quicklist
- partially reverts the visual appearance to the old design of popup menus
- invokes the popup menu also on the right mouse click

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

N/A

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

No (however, there is a revert to the old design)

 * Did you have a look at the warnings when running tests? Can they be reduced?

Yes

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

I see you have lp:~lukas-kde/unity8/highdpi-mousetouchadaptor in this branch. Either remove those changes or make lp:~lukas-kde/unity8/highdpi-mousetouchadaptor a prerequisite.

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

In qml/Launcher/LauncherPanel.qml

"""
- __foregroundColor: "black"
+ __foregroundColor: Theme.palette.selected.backgroundText
"""

"Theme" is deprecated. Please use the context variable "theme" instead. We have tons of warnings on this already. See https://code.launchpad.net/~dandrader/unity8/deprecatedTheme/+merge/262216

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

I would like to see a qml test launches an app and then closes it using this "quit" quick list menu entry.

I should also be able to manually test this feature or try it out (eg, via "make tryShell"), without having to flash a device for that.

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

> I would like to see a qml test launches an app and then closes it using this
> "quit" quick list menu entry.

There is already a test for this, albeit not a QML one: launchermodeltest.cp, void testQuitMenuItem()

> I should also be able to manually test this feature or try it out (eg, via
> "make tryShell"), without having to flash a device for that.

Right, I'll see what I can do with that but I'd prefer doing that in a separate MP; it goes a bit beyond the scope of this review, none of the current quick list actions are testable from QML yet (Pin/Unpin etc).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Some inline comments.

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

> Some inline comments.

Should be fixed by r. 1812

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Hmm... testing it, the quicklist visuals seem to be the expected ones any more. Sorry if I gave bad advice on reverting the complete commit. We should only revert the positioning to what it was before, but not the coloring. Also the arrow points to the wrong direction. It should point from the menu box towards the clicked launcher item, not the other way round.

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

Ack, will fix

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

http://i.imgur.com/bGXaemm.png

Font is white on white, also I'm missing the close entry.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in qml/Launcher/LauncherPanel.qml
1 conflicts encountered.

review: Needs Fixing
Revision history for this message
Albert Astals Cid (aacid) : Posted in a previous version of this proposal
review: Abstain (tags clean & merges fine)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Looks ok and works, except the dbusinterface changes are not needed. Please drop them.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

 * 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 can, yes

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

yes

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

re-approving as per superseded MP.

Jenkins won't work on this any more as it now depends on a unity-api change...

review: Approve
1827. By Lukáš Tinkl

re-merge again on top of use-set-progress-api to fix failing QML tests

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.cpp'
--- plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-07-29 12:33:59 +0000
+++ plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-07-29 12:33:59 +0000
@@ -67,6 +67,8 @@
67 return item->progress();67 return item->progress();
68 case RoleFocused:68 case RoleFocused:
69 return item->focused();69 return item->focused();
70 case RoleRunning:
71 return item->running();
70 }72 }
7173
72 return QVariant();74 return QVariant();
@@ -217,14 +219,10 @@
217 item->setCount(cachedMap.value("count").toInt());219 item->setCount(cachedMap.value("count").toInt());
218 item->setCountVisible(cachedMap.value("countVisible").toBool());220 item->setCountVisible(cachedMap.value("countVisible").toBool());
219 item->setProgress(cachedMap.value("progress").toInt());221 item->setProgress(cachedMap.value("progress").toInt());
222 item->setRunning(cachedMap.value("running").toBool());
223
220 int idx = m_list.indexOf(item);224 int idx = m_list.indexOf(item);
221 Q_EMIT dataChanged(index(idx),225 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleIcon, RoleCount, RoleCountVisible, RoleRunning, RoleProgress});
222 index(idx),
223 {RoleName,
224 RoleIcon,
225 RoleCount,
226 RoleCountVisible,
227 RoleProgress});
228 }226 }
229 break;227 break;
230 }228 }
@@ -262,16 +260,17 @@
262 }260 }
263261
264 if (itemIndex == -1) {262 if (itemIndex == -1) {
265 QVariantMap chachedMap = entry.toMap();263 QVariantMap cachedMap = entry.toMap();
266 // Need to add it. Just add it into the addedIndex to keep same ordering as the list in AS.264 // Need to add it. Just add it into the addedIndex to keep same ordering as the list in AS.
267 LauncherItem *item = new LauncherItem(chachedMap.value("id").toString(),265 LauncherItem *item = new LauncherItem(cachedMap.value("id").toString(),
268 chachedMap.value("name").toString(),266 cachedMap.value("name").toString(),
269 chachedMap.value("icon").toString(),267 cachedMap.value("icon").toString(),
270 this);268 this);
271 item->setPinned(true);269 item->setPinned(true);
272 item->setCount(chachedMap.value("count").toInt());270 item->setCount(cachedMap.value("count").toInt());
273 item->setCountVisible(chachedMap.value("countVisible").toBool());271 item->setCountVisible(cachedMap.value("countVisible").toBool());
274 item->setProgress(chachedMap.value("progress").toInt());272 item->setProgress(cachedMap.value("progress").toInt());
273 item->setRunning(cachedMap.value("running").toBool());
275 beginInsertRows(QModelIndex(), newPosition, newPosition);274 beginInsertRows(QModelIndex(), newPosition, newPosition);
276 m_list.insert(newPosition, item);275 m_list.insert(newPosition, item);
277 endInsertRows();276 endInsertRows();
278277
=== modified file 'plugins/Unity/Launcher/asadapter.cpp'
--- plugins/Unity/Launcher/asadapter.cpp 2015-07-29 12:33:59 +0000
+++ plugins/Unity/Launcher/asadapter.cpp 2015-07-29 12:33:59 +0000
@@ -34,12 +34,12 @@
34 m_accounts->deleteLater();34 m_accounts->deleteLater();
35}35}
3636
37void ASAdapter::syncItems(QList<LauncherItem *> m_list)37void ASAdapter::syncItems(const QList<LauncherItem*> &list)
38{38{
39 if (m_accounts && !m_user.isEmpty()) {39 if (m_accounts && !m_user.isEmpty()) {
40 QList<QVariantMap> items;40 QList<QVariantMap> items;
4141
42 Q_FOREACH(LauncherItem *item, m_list) {42 Q_FOREACH(LauncherItem *item, list) {
43 items << itemToVariant(item);43 items << itemToVariant(item);
44 }44 }
4545
@@ -56,6 +56,7 @@
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("running", item->running());
59 details.insert("progress", item->progress());60 details.insert("progress", item->progress());
60 return details;61 return details;
61}62}
6263
=== modified file 'plugins/Unity/Launcher/asadapter.h'
--- plugins/Unity/Launcher/asadapter.h 2015-02-11 14:13:26 +0000
+++ plugins/Unity/Launcher/asadapter.h 2015-07-29 12:33:59 +0000
@@ -21,7 +21,6 @@
2121
22class LauncherItem;22class LauncherItem;
23class AccountsServiceDBusAdaptor;23class AccountsServiceDBusAdaptor;
24class QDBusInterface;
2524
26class ASAdapter25class ASAdapter
27{26{
@@ -29,7 +28,7 @@
29 ASAdapter();28 ASAdapter();
30 ~ASAdapter();29 ~ASAdapter();
3130
32 void syncItems(QList<LauncherItem*> m_list);31 void syncItems(const QList<LauncherItem*> &list);
3332
34private:33private:
35 QVariantMap itemToVariant(LauncherItem *item) const;34 QVariantMap itemToVariant(LauncherItem *item) const;
@@ -38,8 +37,6 @@
38 AccountsServiceDBusAdaptor *m_accounts;37 AccountsServiceDBusAdaptor *m_accounts;
39 QString m_user;38 QString m_user;
4039
41 QDBusInterface *m_userInterface;
42
43 friend class LauncherModelTest;40 friend class LauncherModelTest;
44};41};
4542
4643
=== modified file 'plugins/Unity/Launcher/gsettings.cpp'
--- plugins/Unity/Launcher/gsettings.cpp 2015-03-04 08:54:12 +0000
+++ plugins/Unity/Launcher/gsettings.cpp 2015-07-29 12:33:59 +0000
@@ -68,7 +68,7 @@
68void GSettings::onSettingsChanged(const QString &key)68void GSettings::onSettingsChanged(const QString &key)
69{69{
70 if (key == "items") {70 if (key == "items") {
71 QStringList cachedItems = m_gSettings->get("items").toStringList();71 const QStringList cachedItems = m_gSettings->get("items").toStringList();
72 if (m_cachedItems != cachedItems) {72 if (m_cachedItems != cachedItems) {
73 m_cachedItems = cachedItems;73 m_cachedItems = cachedItems;
74 Q_EMIT changed();74 Q_EMIT changed();
7575
=== modified file 'plugins/Unity/Launcher/launcheritem.cpp'
--- plugins/Unity/Launcher/launcheritem.cpp 2015-07-29 12:33:59 +0000
+++ plugins/Unity/Launcher/launcheritem.cpp 2015-07-29 12:33:59 +0000
@@ -41,10 +41,15 @@
41 nameAction.setActionId("launch_item");41 nameAction.setActionId("launch_item");
42 nameAction.setText(m_name);42 nameAction.setText(m_name);
43 m_quickList->appendAction(nameAction);43 m_quickList->appendAction(nameAction);
44
44 QuickListEntry pinningAction;45 QuickListEntry pinningAction;
45 pinningAction.setActionId("pin_item");46 pinningAction.setActionId("pin_item");
46 pinningAction.setText(gettext("Pin shortcut"));47 pinningAction.setText(gettext("Pin shortcut"));
47 m_quickList->appendAction(pinningAction);48 m_quickList->appendAction(pinningAction);
49
50 m_quitAction.setActionId("stop_item");
51 m_quitAction.setIcon("application-exit");
52 m_quitAction.setText(gettext("Quit"));
48}53}
4954
50QString LauncherItem::appId() const55QString LauncherItem::appId() const
@@ -111,6 +116,11 @@
111{116{
112 if (m_running != running) {117 if (m_running != running) {
113 m_running = running;118 m_running = running;
119 if (m_running) { // add the quit action
120 m_quickList->appendAction(m_quitAction);
121 } else { // remove the quit action
122 m_quickList->removeAction(m_quitAction);
123 }
114 Q_EMIT runningChanged(running);124 Q_EMIT runningChanged(running);
115 }125 }
116}126}
117127
=== modified file 'plugins/Unity/Launcher/launcheritem.h'
--- plugins/Unity/Launcher/launcheritem.h 2015-07-29 12:33:59 +0000
+++ plugins/Unity/Launcher/launcheritem.h 2015-07-29 12:33:59 +0000
@@ -73,6 +73,7 @@
73 bool m_focused;73 bool m_focused;
74 bool m_alerting;74 bool m_alerting;
75 QuickListModel *m_quickList;75 QuickListModel *m_quickList;
76 QuickListEntry m_quitAction;
7677
77 friend class LauncherModel;78 friend class LauncherModel;
78};79};
7980
=== modified file 'plugins/Unity/Launcher/launchermodel.cpp'
--- plugins/Unity/Launcher/launchermodel.cpp 2015-07-29 12:33:59 +0000
+++ plugins/Unity/Launcher/launchermodel.cpp 2015-07-29 12:33:59 +0000
@@ -36,7 +36,7 @@
36 m_settings(new GSettings(this)),36 m_settings(new GSettings(this)),
37 m_dbusIface(new DBusInterface(this)),37 m_dbusIface(new DBusInterface(this)),
38 m_asAdapter(new ASAdapter()),38 m_asAdapter(new ASAdapter()),
39 m_appManager(0)39 m_appManager(nullptr)
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);
@@ -86,6 +86,11 @@
86 return item->focused();86 return item->focused();
87 case RoleAlerting:87 case RoleAlerting:
88 return item->alerting();88 return item->alerting();
89 case RoleRunning:
90 return item->running();
91 default:
92 qWarning() << Q_FUNC_INFO << "missing role, implement me";
93 return QVariant();
89 }94 }
9095
91 return QVariant();96 return QVariant();
@@ -150,7 +155,7 @@
150 if (index == -1 || index == currentIndex) {155 if (index == -1 || index == currentIndex) {
151 m_list.at(currentIndex)->setPinned(true);156 m_list.at(currentIndex)->setPinned(true);
152 QModelIndex modelIndex = this->index(currentIndex);157 QModelIndex modelIndex = this->index(currentIndex);
153 Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RolePinned);158 Q_EMIT dataChanged(modelIndex, modelIndex, {RolePinned});
154 } else {159 } else {
155 move(currentIndex, index);160 move(currentIndex, index);
156 // move() will store the list to the backend itself, so just exit at this point.161 // move() will store the list to the backend itself, so just exit at this point.
@@ -163,7 +168,7 @@
163168
164 DesktopFileHandler desktopFile(appId);169 DesktopFileHandler desktopFile(appId);
165 if (!desktopFile.isValid()) {170 if (!desktopFile.isValid()) {
166 qWarning() << "Can't pin this application, there is no .destkop file available.";171 qWarning() << "Can't pin this application, there is no .desktop file available.";
167 return;172 return;
168 }173 }
169174
@@ -188,7 +193,7 @@
188193
189void LauncherModel::quickListActionInvoked(const QString &appId, int actionIndex)194void LauncherModel::quickListActionInvoked(const QString &appId, int actionIndex)
190{195{
191 int index = findApplication(appId);196 const int index = findApplication(appId);
192 if (index < 0) {197 if (index < 0) {
193 return;198 return;
194 }199 }
@@ -196,7 +201,7 @@
196 LauncherItem *item = m_list.at(index);201 LauncherItem *item = m_list.at(index);
197 QuickListModel *model = qobject_cast<QuickListModel*>(item->quickList());202 QuickListModel *model = qobject_cast<QuickListModel*>(item->quickList());
198 if (model) {203 if (model) {
199 QString actionId = model->get(actionIndex).actionId();204 const QString actionId = model->get(actionIndex).actionId();
200205
201 // Check if this is one of the launcher actions we handle ourselves206 // Check if this is one of the launcher actions we handle ourselves
202 if (actionId == "pin_item") {207 if (actionId == "pin_item") {
@@ -207,7 +212,10 @@
207 }212 }
208 } else if (actionId == "launch_item") {213 } else if (actionId == "launch_item") {
209 QDesktopServices::openUrl(getUrlForAppId(appId));214 QDesktopServices::openUrl(getUrlForAppId(appId));
210215 } else if (actionId == "stop_item") { // Quit
216 if (m_appManager) {
217 m_appManager->stopApplication(appId);
218 }
211 // Nope, we don't know this action, let the backend forward it to the application219 // Nope, we don't know this action, let the backend forward it to the application
212 } else {220 } else {
213 // TODO: forward quicklist action to app, possibly via m_dbusIface221 // TODO: forward quicklist action to app, possibly via m_dbusIface
@@ -305,7 +313,7 @@
305313
306void LauncherModel::unpin(const QString &appId)314void LauncherModel::unpin(const QString &appId)
307{315{
308 int index = findApplication(appId);316 const int index = findApplication(appId);
309 if (index < 0) {317 if (index < 0) {
310 return;318 return;
311 }319 }
@@ -314,7 +322,7 @@
314 if (m_list.at(index)->pinned()) {322 if (m_list.at(index)->pinned()) {
315 m_list.at(index)->setPinned(false);323 m_list.at(index)->setPinned(false);
316 QModelIndex modelIndex = this->index(index);324 QModelIndex modelIndex = this->index(index);
317 Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RolePinned);325 Q_EMIT dataChanged(modelIndex, modelIndex, {RolePinned});
318 }326 }
319 } else {327 } else {
320 beginRemoveRows(QModelIndex(), index, index);328 beginRemoveRows(QModelIndex(), index, index);
@@ -336,25 +344,25 @@
336344
337void LauncherModel::progressChanged(const QString &appId, int progress)345void LauncherModel::progressChanged(const QString &appId, int progress)
338{346{
339 int idx = findApplication(appId);347 const int idx = findApplication(appId);
340 if (idx >= 0) {348 if (idx >= 0) {
341 LauncherItem *item = m_list.at(idx);349 LauncherItem *item = m_list.at(idx);
342 item->setProgress(progress);350 item->setProgress(progress);
343 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleProgress);351 Q_EMIT dataChanged(index(idx), index(idx), {RoleProgress});
344 }352 }
345}353}
346354
347void LauncherModel::countChanged(const QString &appId, int count)355void LauncherModel::countChanged(const QString &appId, int count)
348{356{
349 int idx = findApplication(appId);357 const int idx = findApplication(appId);
350 if (idx >= 0) {358 if (idx >= 0) {
351 LauncherItem *item = m_list.at(idx);359 LauncherItem *item = m_list.at(idx);
352 item->setCount(count);360 item->setCount(count);
353 if (item->countVisible()) {361 if (item->countVisible()) {
354 setAlerting(item->appId(), true);362 setAlerting(item->appId(), true);
355 }363 }
356 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleCount);
357 m_asAdapter->syncItems(m_list);364 m_asAdapter->syncItems(m_list);
365 Q_EMIT dataChanged(index(idx), index(idx), {RoleCount});
358 }366 }
359}367}
360368
@@ -367,7 +375,7 @@
367 if (countVisible) {375 if (countVisible) {
368 setAlerting(item->appId(), true);376 setAlerting(item->appId(), true);
369 }377 }
370 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleCountVisible);378 Q_EMIT dataChanged(index(idx), index(idx), {RoleCountVisible});
371379
372 // If countVisible goes to false, and the item is neither pinned nor recent we can drop it380 // If countVisible goes to false, and the item is neither pinned nor recent we can drop it
373 if (!countVisible && !item->pinned() && !item->recent()) {381 if (!countVisible && !item->pinned() && !item->recent()) {
@@ -408,7 +416,8 @@
408 item->setName(desktopFile.displayName());416 item->setName(desktopFile.displayName());
409 item->setIcon(desktopFile.icon());417 item->setIcon(desktopFile.icon());
410 item->setPinned(item->pinned()); // update pinned text if needed418 item->setPinned(item->pinned()); // update pinned text if needed
411 Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleName << RoleIcon);419 item->setRunning(item->running());
420 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleIcon, RoleRunning});
412 }421 }
413 }422 }
414423
@@ -426,7 +435,7 @@
426435
427 // Now walk through settings and see if we need to add something436 // Now walk through settings and see if we need to add something
428 for (int settingsIndex = 0; settingsIndex < m_settings->storedApplications().count(); ++settingsIndex) {437 for (int settingsIndex = 0; settingsIndex < m_settings->storedApplications().count(); ++settingsIndex) {
429 QString entry = m_settings->storedApplications().at(settingsIndex);438 const QString entry = m_settings->storedApplications().at(settingsIndex);
430 int itemIndex = -1;439 int itemIndex = -1;
431 for (int i = 0; i < m_list.count(); ++i) {440 for (int i = 0; i < m_list.count(); ++i) {
432 if (m_list.at(i)->appId() == entry) {441 if (m_list.at(i)->appId() == entry) {
@@ -499,25 +508,27 @@
499 return;508 return;
500 }509 }
501510
502 int itemIndex = findApplication(app->appId());511 const int itemIndex = findApplication(app->appId());
503 if (itemIndex != -1) {512 if (itemIndex != -1) {
504 LauncherItem *item = m_list.at(itemIndex);513 LauncherItem *item = m_list.at(itemIndex);
505 if (!item->recent()) {514 if (!item->recent()) {
506 item->setRecent(true);515 item->setRecent(true);
507 m_asAdapter->syncItems(m_list);516 Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleRecent});
508 Q_EMIT dataChanged(index(itemIndex), index(itemIndex), QVector<int>() << RoleRecent);
509 }517 }
510 // Shall we paint some running/recent app highlight? If yes, do it here.518 item->setRunning(true);
519 // TODO Shall we paint some running/recent app highlight? If yes, do it here.
511 } else {520 } else {
512 LauncherItem *item = new LauncherItem(app->appId(), app->name(), app->icon().toString(), this);521 LauncherItem *item = new LauncherItem(app->appId(), app->name(), app->icon().toString(), this);
513 item->setRecent(true);522 item->setRecent(true);
523 item->setRunning(true);
514 item->setFocused(app->focused());524 item->setFocused(app->focused());
515525
516 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());526 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
517 m_list.append(item);527 m_list.append(item);
518 endInsertRows();528 endInsertRows();
519 m_asAdapter->syncItems(m_list);
520 }529 }
530 m_asAdapter->syncItems(m_list);
531 Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleRunning});
521}532}
522533
523void LauncherModel::applicationRemoved(const QModelIndex &parent, int row)534void LauncherModel::applicationRemoved(const QModelIndex &parent, int row)
@@ -532,25 +543,35 @@
532 }543 }
533 }544 }
534545
535 if (appIndex > -1 && !m_list.at(appIndex)->pinned()) {546 if (appIndex < 0) {
547 qWarning() << Q_FUNC_INFO << "appIndex not found";
548 return;
549 }
550
551 LauncherItem * item = m_list.at(appIndex);
552 item->setRunning(false);
553
554 if (!item->pinned()) {
536 beginRemoveRows(QModelIndex(), appIndex, appIndex);555 beginRemoveRows(QModelIndex(), appIndex, appIndex);
537 m_list.takeAt(appIndex)->deleteLater();556 m_list.takeAt(appIndex)->deleteLater();
538 endRemoveRows();557 endRemoveRows();
539 m_asAdapter->syncItems(m_list);558 m_asAdapter->syncItems(m_list);
559 Q_EMIT dataChanged(index(appIndex), index(appIndex), {RolePinned});
540 }560 }
561 Q_EMIT dataChanged(index(appIndex), index(appIndex), {RoleRunning});
541}562}
542563
543void LauncherModel::focusedAppIdChanged()564void LauncherModel::focusedAppIdChanged()
544{565{
545 QString appId = m_appManager->focusedApplicationId();566 const QString appId = m_appManager->focusedApplicationId();
546 for (int i = 0; i < m_list.count(); ++i) {567 for (int i = 0; i < m_list.count(); ++i) {
547 LauncherItem *item = m_list.at(i);568 LauncherItem *item = m_list.at(i);
548 if (!item->focused() && item->appId() == appId) {569 if (!item->focused() && item->appId() == appId) {
549 item->setFocused(true);570 item->setFocused(true);
550 Q_EMIT dataChanged(index(i), index(i), QVector<int>() << RoleFocused);571 Q_EMIT dataChanged(index(i), index(i), {RoleFocused});
551 } else if (item->focused() && item->appId() != appId) {572 } else if (item->focused() && item->appId() != appId) {
552 item->setFocused(false);573 item->setFocused(false);
553 Q_EMIT dataChanged(index(i), index(i), QVector<int>() << RoleFocused);574 Q_EMIT dataChanged(index(i), index(i), {RoleFocused});
554 }575 }
555 }576 }
556}577}
557578
=== modified file 'plugins/Unity/Launcher/quicklistentry.cpp'
--- plugins/Unity/Launcher/quicklistentry.cpp 2014-08-26 11:34:22 +0000
+++ plugins/Unity/Launcher/quicklistentry.cpp 2015-07-29 12:33:59 +0000
@@ -1,4 +1,4 @@
1/* Copyright (C) 2013 Canonical, Ltd.1/* Copyright (C) 2013, 2015 Canonical, Ltd.
2 *2 *
3 * Authors:3 * Authors:
4 * Michael Zanetti <michael.zanetti@canonical.com>4 * Michael Zanetti <michael.zanetti@canonical.com>
@@ -20,7 +20,6 @@
2020
21QuickListEntry::QuickListEntry()21QuickListEntry::QuickListEntry()
22{22{
23
24}23}
2524
26QString QuickListEntry::actionId() const25QString QuickListEntry::actionId() const
@@ -57,3 +56,8 @@
57{56{
58 return !m_actionId.isEmpty();57 return !m_actionId.isEmpty();
59}58}
59
60bool QuickListEntry::operator==(const QuickListEntry &other)
61{
62 return !other.actionId().isEmpty() && other.actionId() == m_actionId;
63}
6064
=== modified file 'plugins/Unity/Launcher/quicklistentry.h'
--- plugins/Unity/Launcher/quicklistentry.h 2014-08-26 11:34:22 +0000
+++ plugins/Unity/Launcher/quicklistentry.h 2015-07-29 12:33:59 +0000
@@ -1,4 +1,4 @@
1/* Copyright (C) 2013 Canonical, Ltd.1/* Copyright (C) 2013, 2015 Canonical, Ltd.
2 *2 *
3 * Authors:3 * Authors:
4 * Michael Zanetti <michael.zanetti@canonical.com>4 * Michael Zanetti <michael.zanetti@canonical.com>
@@ -37,6 +37,8 @@
3737
38 bool clickable() const;38 bool clickable() const;
3939
40 bool operator==(const QuickListEntry & other);
41
40private:42private:
41 QString m_actionId;43 QString m_actionId;
42 QString m_text;44 QString m_text;
4345
=== modified file 'plugins/Unity/Launcher/quicklistmodel.cpp'
--- plugins/Unity/Launcher/quicklistmodel.cpp 2013-10-02 11:00:53 +0000
+++ plugins/Unity/Launcher/quicklistmodel.cpp 2015-07-29 12:33:59 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2013 Canonical Ltd.2 * Copyright 2013, 2015 Canonical Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by5 * it under the terms of the GNU Lesser General Public License as published by
@@ -48,6 +48,17 @@
48 }48 }
49}49}
5050
51void QuickListModel::removeAction(const QuickListEntry &entry)
52{
53 const int start = m_list.indexOf(entry);
54 if (start > -1) {
55 beginRemoveRows(QModelIndex(), start, start);
56 m_list.removeOne(entry);
57 Q_EMIT dataChanged(index(start), index(start));
58 endRemoveRows();
59 }
60}
61
51QuickListEntry QuickListModel::get(int index) const62QuickListEntry QuickListModel::get(int index) const
52{63{
53 return m_list.at(index);64 return m_list.at(index);
5465
=== modified file 'plugins/Unity/Launcher/quicklistmodel.h'
--- plugins/Unity/Launcher/quicklistmodel.h 2015-04-30 09:31:51 +0000
+++ plugins/Unity/Launcher/quicklistmodel.h 2015-07-29 12:33:59 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2013 Canonical Ltd.2 * Copyright 201, 2015 Canonical Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by5 * it under the terms of the GNU Lesser General Public License as published by
@@ -46,6 +46,8 @@
46 */46 */
47 void updateAction(const QuickListEntry &entry);47 void updateAction(const QuickListEntry &entry);
4848
49 void removeAction(const QuickListEntry &entry);
50
49 QuickListEntry get(int index) const;51 QuickListEntry get(int index) const;
5052
51 int rowCount(const QModelIndex &parent = QModelIndex()) const override;53 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
5254
=== modified file 'qml/Launcher/LauncherPanel.qml'
--- qml/Launcher/LauncherPanel.qml 2015-07-29 12:33:59 +0000
+++ qml/Launcher/LauncherPanel.qml 2015-07-29 12:33:59 +0000
@@ -15,7 +15,7 @@
15 */15 */
1616
17import QtQuick 2.317import QtQuick 2.3
18import Ubuntu.Components 1.118import Ubuntu.Components 1.2
19import Ubuntu.Components.ListItems 1.0 as ListItems19import Ubuntu.Components.ListItems 1.0 as ListItems
20import Unity.Launcher 0.120import Unity.Launcher 0.1
21import Ubuntu.Components.Popups 0.121import Ubuntu.Components.Popups 0.1
@@ -358,6 +358,7 @@
358 MouseArea {358 MouseArea {
359 id: dndArea359 id: dndArea
360 objectName: "dndArea"360 objectName: "dndArea"
361 acceptedButtons: Qt.LeftButton | Qt.RightButton
361 anchors {362 anchors {
362 fill: parent363 fill: parent
363 topMargin: launcherListView.topMargin364 topMargin: launcherListView.topMargin
@@ -369,7 +370,7 @@
369 property int draggedIndex: -1370 property int draggedIndex: -1
370 property var selectedItem371 property var selectedItem
371 property bool preDragging: false372 property bool preDragging: false
372 property bool dragging: selectedItem !== undefined && selectedItem !== null && selectedItem.dragging373 property bool dragging: !!selectedItem && selectedItem.dragging
373 property bool postDragging: false374 property bool postDragging: false
374 property int startX375 property int startX
375 property int startY376 property int startY
@@ -387,6 +388,15 @@
387 return;388 return;
388 }389 }
389390
391 if (mouse.button & Qt.RightButton) { // context menu
392 // Opening QuickList
393 quickList.item = clickedItem;
394 quickList.model = launcherListView.model.get(index).quickList;
395 quickList.appId = launcherListView.model.get(index).appId;
396 quickList.state = "open";
397 return
398 }
399
390 // First/last item do the scrolling at more than 12 degrees400 // First/last item do the scrolling at more than 12 degrees
391 if (index == 0 || index == launcherListView.count - 1) {401 if (index == 0 || index == launcherListView.count - 1) {
392 if (clickedItem.angle > 12) {402 if (clickedItem.angle > 12) {
@@ -580,7 +590,7 @@
580 id: quickListShape590 id: quickListShape
581 objectName: "quickListShape"591 objectName: "quickListShape"
582 anchors.fill: quickList592 anchors.fill: quickList
583 opacity: quickList.state === "open" ? 0.96 : 0593 opacity: quickList.state === "open" ? 0.8 : 0
584 visible: opacity > 0594 visible: opacity > 0
585 rotation: root.rotation595 rotation: root.rotation
586596
@@ -592,15 +602,15 @@
592602
593 Image {603 Image {
594 anchors {604 anchors {
595 left: parent.left605 right: parent.left
596 leftMargin: quickList.item !== undefined ? (quickList.item.width - units.gu(1)) / 2 - width / 2 : 0606 rightMargin: -units.dp(4)
597 verticalCenter: parent.verticalCenter607 verticalCenter: parent.verticalCenter
598 verticalCenterOffset: (parent.height / 2 + units.dp(3)) * (quickList.offset > 0 ? 1 : -1) * (root.inverted ? 1 : -1)608 verticalCenterOffset: -quickList.offset * (root.inverted ? -1 : 1)
599 }609 }
600 height: units.gu(1)610 height: units.gu(1)
601 width: units.gu(2)611 width: units.gu(2)
602 source: "graphics/quicklist_tooltip.png"612 source: "graphics/quicklist_tooltip.png"
603 rotation: (quickList.offset > 0 ? 0 : 180) + (root.inverted ? 0 : 180)613 rotation: 90
604 }614 }
605615
606 InverseMouseArea {616 InverseMouseArea {
@@ -623,11 +633,11 @@
623 height: quickListColumn.height633 height: quickListColumn.height
624 visible: quickListShape.visible634 visible: quickListShape.visible
625 anchors {635 anchors {
626 left: root.inverted ? undefined : parent.left636 left: root.inverted ? undefined : parent.right
627 right: root.inverted ? parent.right : undefined637 right: root.inverted ? parent.left : undefined
628 margins: units.gu(1)638 margins: units.gu(1)
629 }639 }
630 y: itemCenter + offset640 y: itemCenter - (height / 2) + offset
631 rotation: root.rotation641 rotation: root.rotation
632642
633 property var model643 property var model
@@ -636,9 +646,8 @@
636646
637 // internal647 // internal
638 property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1)648 property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1)
639 property int offset: item !== undefined ? (itemCenter + (item.height/2) + height + units.gu(1) > parent.height ?649 property int offset: itemCenter + (height/2) + units.gu(1) > parent.height ? -itemCenter - (height/2) - units.gu(1) + parent.height :
640 -(item.height/2) - height - units.gu(.5) :650 itemCenter - (height/2) < units.gu(1) ? (height/2) - itemCenter + units.gu(1) : 0
641 (item.height/2) + units.gu(.5)) : 0
642651
643 Column {652 Column {
644 id: quickListColumn653 id: quickListColumn
645654
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp'
--- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-07-29 12:33:59 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-07-29 12:33:59 +0000
@@ -40,7 +40,10 @@
40 m_alerting(false),40 m_alerting(false),
41 m_quickList(new MockQuickListModel(this))41 m_quickList(new MockQuickListModel(this))
42{42{
43}
4344
45MockLauncherItem::~MockLauncherItem()
46{
44}47}
4548
46QString MockLauncherItem::appId() const49QString MockLauncherItem::appId() const
4750
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h'
--- tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-07-29 12:33:59 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-07-29 12:33:59 +0000
@@ -31,6 +31,7 @@
31 Q_OBJECT31 Q_OBJECT
32public:32public:
33 MockLauncherItem(const QString &appId, const QString& desktopFile, const QString& name, const QString& icon, QObject* parent = 0);33 MockLauncherItem(const QString &appId, const QString& desktopFile, const QString& name, const QString& icon, QObject* parent = 0);
34 ~MockLauncherItem();
3435
35 QString appId() const override;36 QString appId() const override;
36 QString desktopFile() const;37 QString desktopFile() const;
3738
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp'
--- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-07-29 12:33:59 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-07-29 12:33:59 +0000
@@ -44,6 +44,7 @@
44 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);
45 item->setCount(1);45 item->setCount(1);
46 item->setCountVisible(true);46 item->setCountVisible(true);
47 item->setRunning(true);
47 item->setAlerting(false);48 item->setAlerting(false);
48 m_list.append(item);49 m_list.append(item);
49 item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this);50 item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this);
@@ -194,7 +195,9 @@
194 int index = findApp(appId);195 int index = findApp(appId);
195 if (index >= 0) {196 if (index >= 0) {
196 beginRemoveRows(QModelIndex(), index, 0);197 beginRemoveRows(QModelIndex(), index, 0);
197 m_list.takeAt(index)->deleteLater();198 MockLauncherItem * item = m_list.takeAt(index);
199 item->setRunning(false);
200 item->deleteLater();
198 endRemoveRows();201 endRemoveRows();
199 }202 }
200}203}
201204
=== modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp'
--- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-07-29 12:33:59 +0000
+++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-07-29 12:33:59 +0000
@@ -68,6 +68,7 @@
68 Q_OBJECT68 Q_OBJECT
69public:69public:
70 MockAppManager(QObject *parent = 0): ApplicationManagerInterface(parent) {}70 MockAppManager(QObject *parent = 0): ApplicationManagerInterface(parent) {}
71 ~MockAppManager() {}
71 int rowCount(const QModelIndex &) const override { return m_list.count(); }72 int rowCount(const QModelIndex &) const override { return m_list.count(); }
72 QVariant data(const QModelIndex &, int ) const override { return QVariant(); }73 QVariant data(const QModelIndex &, int ) const override { return QVariant(); }
73 QString focusedApplicationId() const override {74 QString focusedApplicationId() const override {
@@ -325,6 +326,46 @@
325 QCOMPARE(launcherModel->get(0)->appId(), QLatin1String("abs-icon"));326 QCOMPARE(launcherModel->get(0)->appId(), QLatin1String("abs-icon"));
326 }327 }
327328
329 void testQuitMenuItem() {
330 // we have 2 apps running, both should have the Quit action in its quick list
331 QCOMPARE(launcherModel->rowCount(), 2);
332
333 // stop the second one keeping it pinned so that it doesn't go away
334 launcherModel->pin("no-icon");
335 appManager->stopApplication("no-icon");
336
337 // find the first Quit item, should be there
338 QuickListModel *model = qobject_cast<QuickListModel*>(launcherModel->get(0)->quickList());
339 int quitActionIndex = -1;
340 for (int i = 0; i < model->rowCount(); ++i) {
341 if (model->get(i).actionId() == "stop_item") {
342 quitActionIndex = i;
343 break;
344 }
345 }
346 QVERIFY(quitActionIndex >= 0);
347
348 // find the second Quit item, should NOT be there, the app is stopped
349 QuickListModel *model2 = qobject_cast<QuickListModel*>(launcherModel->get(1)->quickList());
350 int quitActionIndex2 = -1;
351 for (int i = 0; i < model2->rowCount(); ++i) {
352 if (model2->get(i).actionId() == "stop_item") {
353 quitActionIndex2 = i;
354 break;
355 }
356 }
357 QVERIFY(quitActionIndex2 == -1);
358
359 // trigger the first quit item quicklist action
360 launcherModel->quickListActionInvoked(launcherModel->get(0)->appId(), quitActionIndex);
361 // first app should be gone...
362 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
363 // ... the second app (now at index 0) should still be there, pinned and stopped
364 QCOMPARE(launcherModel->get(0)->appId(), QStringLiteral("no-icon"));
365 QCOMPARE(launcherModel->get(0)->pinned(), true);
366 QCOMPARE(launcherModel->get(0)->running(), false);
367 }
368
328 void testGetUrlForAppId() {369 void testGetUrlForAppId() {
329 QCOMPARE(launcherModel->getUrlForAppId(QString()), QString());370 QCOMPARE(launcherModel->getUrlForAppId(QString()), QString());
330 QCOMPARE(launcherModel->getUrlForAppId(""), QString());371 QCOMPARE(launcherModel->getUrlForAppId(""), QString());
331372
=== modified file 'tests/qmltests/Launcher/tst_Launcher.qml'
--- tests/qmltests/Launcher/tst_Launcher.qml 2015-07-29 12:33:59 +0000
+++ tests/qmltests/Launcher/tst_Launcher.qml 2015-07-29 12:33:59 +0000
@@ -197,7 +197,7 @@
197 startX+units.gu(8), startY);197 startX+units.gu(8), startY);
198198
199 var panel = findChild(launcher, "launcherPanel");199 var panel = findChild(launcher, "launcherPanel");
200 verify(panel != undefined);200 verify(!!panel);
201201
202 // wait until it gets fully extended202 // wait until it gets fully extended
203 tryCompare(panel, "x", 0);203 tryCompare(panel, "x", 0);
@@ -208,7 +208,7 @@
208 mouseMove(root, 1, root.height / 2);208 mouseMove(root, 1, root.height / 2);
209209
210 var panel = findChild(launcher, "launcherPanel");210 var panel = findChild(launcher, "launcherPanel");
211 verify(panel != undefined);211 verify(!!panel);
212212
213 // wait until it gets fully extended213 // wait until it gets fully extended
214 tryCompare(panel, "x", 0);214 tryCompare(panel, "x", 0);
@@ -248,7 +248,7 @@
248 waitUntilLauncherDisappears();248 waitUntilLauncherDisappears();
249249
250 var panel = findChild(launcher, "launcherPanel")250 var panel = findChild(launcher, "launcherPanel")
251 verify(panel != undefined)251 verify(!!panel)
252252
253 // it starts out hidden just left of the left launcher edge253 // it starts out hidden just left of the left launcher edge
254 compare(panel.x, -panel.width)254 compare(panel.x, -panel.width)
@@ -286,7 +286,7 @@
286286
287 var appIcon = findChild(launcher, "launcherDelegate0");287 var appIcon = findChild(launcher, "launcherDelegate0");
288288
289 verify(appIcon != undefined);289 verify(!!appIcon);
290290
291 if (data.mouse) {291 if (data.mouse) {
292 mouseClick(appIcon);292 mouseClick(appIcon);
@@ -309,7 +309,7 @@
309 dragLauncherIntoView()309 dragLauncherIntoView()
310310
311 var dashIcon = findChild(launcher, "dashItem")311 var dashIcon = findChild(launcher, "dashItem")
312 verify(dashIcon != undefined)312 verify(!!dashIcon)
313313
314 mouseClick(dashIcon)314 mouseClick(dashIcon)
315315
@@ -599,7 +599,7 @@
599599
600 // Doing longpress600 // Doing longpress
601 mousePress(draggedItem);601 mousePress(draggedItem);
602 tryCompare(quickListShape, "opacity", 0.96);602 tryCompare(quickListShape, "opacity", 0.8);
603 mouseRelease(draggedItem);603 mouseRelease(draggedItem);
604604
605 verify(quickList.y >= units.gu(1));605 verify(quickList.y >= units.gu(1));
@@ -684,9 +684,31 @@
684 tryCompare(quickList, "state", "");684 tryCompare(quickList, "state", "");
685 }685 }
686686
687 function test_quickListMenuOnRMB() {
688 dragLauncherIntoView();
689 var clickedItem = findChild(launcher, "launcherDelegate5")
690 var quickList = findChild(launcher, "quickList")
691 var quickListShape = findChild(launcher, "quickListShape")
692 var dndArea = findChild(launcher, "dndArea");
693
694 // Initial state
695 tryCompare(quickListShape, "visible", false)
696
697 // Doing RMB click
698 mouseClick(clickedItem, clickedItem.width / 2, clickedItem.height / 2, Qt.RightButton)
699 tryCompare(quickListShape, "visible", true)
700 verify(quickList, "state", "open")
701 verify(dndArea, "dragging", false)
702
703 // Click somewhere in the empty space to dismiss the quicklist
704 mouseClick(launcher, launcher.width - units.gu(1), units.gu(1));
705 tryCompare(quickListShape, "visible", false);
706 verify(quickList, "state", "")
707 }
708
687 function test_revealByHover() {709 function test_revealByHover() {
688 var panel = findChild(launcher, "launcherPanel");710 var panel = findChild(launcher, "launcherPanel");
689 verify(panel != undefined);711 verify(!!panel);
690712
691 revealByHover();713 revealByHover();
692 tryCompare(launcher, "state", "visibleTemporary");714 tryCompare(launcher, "state", "visibleTemporary");

Subscribers

People subscribed via source and target branches