on xenial help sign in
merge appdate branch as prereq
ac987a2Michael Zanetti
data/unity8-filewatcher.confnew file+8
@@ -0,0 +1,8 @@
1+description "File system watcher for unity8"
2+author "Michael Zanetti <michael.zanetti@canonical.com>"
3+
4+# Workaround for bug 1360208. ~ and * in one expression doesn't work currently
5+start on (file FILE=/home/phablet/.local/share/applications/*.desktop) or (file FILE=/usr/share/applications/*.desktop)
6+
7+exec dbus-send --type=method_call --dest=com.canonical.Unity.Launcher /com/canonical/Unity/Launcher com.canonical.Unity.Launcher.Refresh
8+
plugins/Unity/Launcher/backend/launcherbackend.cpp+41−4
@@ -314,6 +314,19 @@ void LauncherBackend::syncToAccounts()
314 }
314 }
315}
315}
316
316
317+void LauncherBackend::refresh()
318+{
319+ QList<QString> removedApps;
320+ Q_FOREACH (const QString &appId, m_storedApps) {
321+ if (findDesktopFile(appId).isEmpty()) {
322+ removedApps << appId;
323+ }
324+ }
325+ Q_FOREACH (const QString &appId, removedApps) {
326+ Q_EMIT appUninstalled(appId);
327+ }
328+}
329+
317QString LauncherBackend::findDesktopFile(const QString &appId) const
330QString LauncherBackend::findDesktopFile(const QString &appId) const
318{
331{
319 int dashPos = -1;
332 int dashPos = -1;
@@ -400,15 +413,23 @@ void LauncherBackend::loadFromVariant(const QVariantMap &details)
400 }
413 }
401 QString appId = details.value("id").toString();
414 QString appId = details.value("id").toString();
402
415
416+ QString desktopFile = findDesktopFile(appId);
417+ if (desktopFile.isEmpty()) {
418+ return;
419+ }
420+
403 LauncherBackendItem *item = m_itemCache.value(appId, nullptr);
421 LauncherBackendItem *item = m_itemCache.value(appId, nullptr);
404 if (item) {
422 if (item) {
405 delete item;
423 delete item;
406 }
424 }
407
425
426+ if (qgetenv("USER") == "lightdm") {
408− item = new LauncherBackendItem();
427+ item = new LauncherBackendItem();
409−
410− item->displayName = details.value("name").toString();
428+ item->displayName = details.value("name").toString();
411− item->icon = details.value("icon").toString();
429+ item->icon = details.value("icon").toString();
430+ } else {
431+ item = parseDesktopFile(desktopFile);
432+ }
412 item->count = details.value("count").toInt();
433 item->count = details.value("count").toInt();
413 item->countVisible = details.value("countVisible").toBool();
434 item->countVisible = details.value("countVisible").toBool();
414
435
@@ -442,6 +463,16 @@ bool LauncherBackend::handleMessage(const QDBusMessage& message, const QDBusConn
442 if (message.type() != QDBusMessage::MessageType::MethodCallMessage) {
463 if (message.type() != QDBusMessage::MessageType::MethodCallMessage) {
443 return false;
464 return false;
444 }
465 }
466+ // First handle methods of the Launcher interface
467+ if (message.interface() == "com.canonical.Unity.Launcher") {
468+ if (message.member() == "Refresh") {
469+ QDBusMessage reply = message.createReply();
470+ refresh();
471+ return connection.send(reply);
472+ }
473+ }
474+
475+ // Now handle dynamic properties (for launcher emblems)
445 if (message.interface() != "org.freedesktop.DBus.Properties") {
476 if (message.interface() != "org.freedesktop.DBus.Properties") {
446 return false;
477 return false;
447 }
478 }
@@ -491,6 +522,12 @@ QString LauncherBackend::introspect(const QString &path) const
491 if (path == "/com/canonical/Unity/Launcher/" || path == "/com/canonical/Unity/Launcher") {
522 if (path == "/com/canonical/Unity/Launcher/" || path == "/com/canonical/Unity/Launcher") {
492 QString nodes;
523 QString nodes;
493
524
525+ // Add Refresh to introspect
526+ nodes = "<interface name=\"com.canonical.Unity.Launcher\">"
527+ "<method name=\"Refresh\"/>"
528+ "</interface>";
529+
530+ // Add dynamic properties for launcher emblems
494 Q_FOREACH(const QString &appId, m_itemCache.keys()) {
531 Q_FOREACH(const QString &appId, m_itemCache.keys()) {
495 nodes.append("<node name=\"");
532 nodes.append("<node name=\"");
496 nodes.append(encodeAppId(appId));
533 nodes.append(encodeAppId(appId));
plugins/Unity/Launcher/backend/launcherbackend.h+2
@@ -166,6 +166,7 @@ Q_SIGNALS:
166 void progressChanged(const QString &appId, int progress) const;
166 void progressChanged(const QString &appId, int progress) const;
167 void countChanged(const QString &appId, int count) const;
167 void countChanged(const QString &appId, int count) const;
168 void countVisibleChanged(const QString &appId, bool visible) const;
168 void countVisibleChanged(const QString &appId, bool visible) const;
169+ void appUninstalled(const QString &appId);
169
170
170private:
171private:
171 QString findDesktopFile(const QString &appId) const;
172 QString findDesktopFile(const QString &appId) const;
@@ -177,6 +178,7 @@ private:
177 bool isDefaultsItem(const QList<QVariantMap> &apps) const;
178 bool isDefaultsItem(const QList<QVariantMap> &apps) const;
178 void syncFromAccounts();
179 void syncFromAccounts();
179 void syncToAccounts();
180 void syncToAccounts();
181+ void refresh();
180
182
181 QList<QString> m_storedApps;
183 QList<QString> m_storedApps;
182 mutable QHash<QString, LauncherBackendItem*> m_itemCache;
184 mutable QHash<QString, LauncherBackendItem*> m_itemCache;
plugins/Unity/Launcher/launchermodel.cpp+1
@@ -34,6 +34,7 @@ LauncherModel::LauncherModel(QObject *parent):
34{
34{
35 connect(m_backend, SIGNAL(countChanged(QString,int)), SLOT(countChanged(QString,int)));
35 connect(m_backend, SIGNAL(countChanged(QString,int)), SLOT(countChanged(QString,int)));
36 connect(m_backend, SIGNAL(progressChanged(QString,int)), SLOT(progressChanged(QString,int)));
36 connect(m_backend, SIGNAL(progressChanged(QString,int)), SLOT(progressChanged(QString,int)));
37+ connect(m_backend, SIGNAL(appUninstalled(QString)), SLOT(requestRemove(QString)));
37
38
38 Q_FOREACH (const QString &entry, m_backend->storedApplications()) {
39 Q_FOREACH (const QString &entry, m_backend->storedApplications()) {
39 LauncherItem *item = new LauncherItem(entry,
40 LauncherItem *item = new LauncherItem(entry,
plugins/Unity/Launcher/launchermodel.h+3−1
@@ -48,7 +48,6 @@ public:
48 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const;
48 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const;
49 Q_INVOKABLE void move(int oldIndex, int newIndex);
49 Q_INVOKABLE void move(int oldIndex, int newIndex);
50 Q_INVOKABLE void pin(const QString &appId, int index = -1);
50 Q_INVOKABLE void pin(const QString &appId, int index = -1);
51− Q_INVOKABLE void requestRemove(const QString &appId);
52 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
51 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
53 Q_INVOKABLE void setUser(const QString &username);
52 Q_INVOKABLE void setUser(const QString &username);
54 Q_INVOKABLE QString getUrlForAppId(const QString &appId) const;
53 Q_INVOKABLE QString getUrlForAppId(const QString &appId) const;
@@ -56,6 +55,9 @@ public:
56 unity::shell::application::ApplicationManagerInterface* applicationManager() const;
55 unity::shell::application::ApplicationManagerInterface* applicationManager() const;
57 void setApplicationManager(unity::shell::application::ApplicationManagerInterface *appManager);
56 void setApplicationManager(unity::shell::application::ApplicationManagerInterface *appManager);
58
57
58+public Q_SLOTS:
59+ void requestRemove(const QString &appId);
60+
59private:
61private:
60 void storeAppList();
62 void storeAppList();
61 int findApplication(const QString &appId);
63 int findApplication(const QString &appId);