on xenial help sign in
Use UAL instead of manually parsing a desktop file for launcher
commita69ada019f82428df7fa8396f7b76aa6d156873e authorMichael Terry <michael.terry@canonical.com> dateThu 22 Sep 2016, 16:22 (10 years ago) parentb5a5879
15 files changed+92−276
CMakeLists.txt+1−1 plugins/Unity/Launcher/CMakeLists.txt+8−3 plugins/Unity/Launcher/desktopfilehandler.cpp−155 plugins/Unity/Launcher/desktopfilehandler.h−56 plugins/Unity/Launcher/launchermodel.cpp+40−22 plugins/Unity/Launcher/launchermodel.h+9 tests/plugins/Unity/Launcher/CMakeLists.txt+12−19 tests/plugins/Unity/Launcher/abs-icon.desktop → tests/plugins/Unity/Launcher/applications/abs-icon.desktop+1 tests/plugins/Unity/Launcher/click-icon.desktop → tests/plugins/Unity/Launcher/applications/click-icon.desktop+1 tests/plugins/Unity/Launcher/click-icon.svg → tests/plugins/Unity/Launcher/applications/click-icon.svg tests/plugins/Unity/Launcher/no-name.desktop → tests/plugins/Unity/Launcher/applications/no-name.desktop+1 tests/plugins/Unity/Launcher/rel-icon.desktop → tests/plugins/Unity/Launcher/applications/rel-icon.desktop+1 tests/plugins/Unity/Launcher/rel-icon.svg → tests/plugins/Unity/Launcher/applications/rel-icon.svg tests/plugins/Unity/Launcher/launchermodeltest.cpp+18−18 tests/plugins/Unity/Launcher/no-icon.desktop−2
CMakeLists.txt+1−1
@@ -63,7 +63,7 @@ pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
6363pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
6464pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
6565pkg_check_modules(GD3 REQUIRED gnome-desktop-3.0)
66−
66+pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2)
6767pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
6868
6969### Check UbuntuGestures private headers. No pkg-config (.pc) file is provided for them
plugins/Unity/Launcher/CMakeLists.txt+8−3
@@ -6,11 +6,16 @@ add_definitions(-DSM_BUSNAME=systemBus)
66include_directories(
77 ${CMAKE_CURRENT_SOURCE_DIR}
88 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
9− ${GSETTINGS_QT_INCLUDE_DIRS}
10− ${GLIB_INCLUDE_DIRS}
119 ${libunity8-private_SOURCE_DIR}
1210)
1311
12+include_directories(
13+ SYSTEM
14+ ${GSETTINGS_QT_INCLUDE_DIRS}
15+ ${GLIB_INCLUDE_DIRS}
16+ ${UAL_INCLUDE_DIRS}
17+ )
18+
1419set(QMLLAUNCHERPLUGIN_SRC
1520 plugin.cpp
1621 launchermodel.cpp
@@ -19,7 +24,6 @@ set(QMLLAUNCHERPLUGIN_SRC
1924 quicklistentry.cpp
2025 dbusinterface.cpp
2126 gsettings.cpp
22− desktopfilehandler.cpp
2327 asadapter.cpp
2428 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
2529 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
@@ -38,6 +42,7 @@ target_link_libraries(UnityLauncher-qml
3842 unity8-private
3943 ${GSETTINGS_QT_LDFLAGS}
4044 ${GLIB_LIBRARIES}
45+ ${UAL_LIBRARIES}
4146 )
4247
4348qt5_use_modules(UnityLauncher-qml DBus Qml Gui)
plugins/Unity/Launcher/desktopfilehandler.cppdeleted−155
@@ -1,155 +0,0 @@
1−/*
2− * Copyright 2014 Canonical Ltd.
3− *
4− * 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 by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU Lesser General Public License for more details.
12− *
13− * You should have received a copy of the GNU Lesser General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors:
17− * Michael Zanetti <michael.zanetti@canonical.com>
18− */
19−
20−#include "desktopfilehandler.h"
21−
22−#include <QStringList>
23−#include <QStandardPaths>
24−#include <QDir>
25−#include <QSettings>
26−#include <QLocale>
27−
28−#include <libintl.h>
29−
30−DesktopFileHandler::DesktopFileHandler(const QString &appId, QObject *parent):
31− QObject(parent),
32− m_appId(appId)
33−{
34− load();
35−}
36−
37−QString DesktopFileHandler::appId() const
38−{
39− return m_appId;
40−}
41−
42−void DesktopFileHandler::setAppId(const QString &appId)
43−{
44− if (m_appId != appId) {
45− m_appId = appId;
46− load();
47− }
48−}
49−
50−QString DesktopFileHandler::filename() const
51−{
52− return m_filename;
53−}
54−
55−bool DesktopFileHandler::isValid() const
56−{
57− return !m_filename.isEmpty();
58−}
59−
60−void DesktopFileHandler::load()
61−{
62− m_filename.clear();
63−
64− if (m_appId.isEmpty()) {
65− return;
66− }
67−
68− int dashPos = -1;
69− QString helper = m_appId;
70−
71− QStringList searchDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
72−#ifdef LAUNCHER_TESTING
73− searchDirs << QStringLiteral(".");
74−#endif
75−
76− QString path;
77− do {
78− if (dashPos != -1) {
79− helper.replace(dashPos, 1, '/');
80− }
81−
82− if (helper.contains('/')) {
83− path += helper.split('/').at(0) + '/';
84− helper.remove(QRegExp("^" + path));
85− }
86−
87− Q_FOREACH(const QString &searchDirName, searchDirs) {
88− QDir searchDir(searchDirName + "/" + path);
89− const QString desktop = QStringLiteral("*.desktop");
90− Q_FOREACH(const QString &desktopFile, searchDir.entryList(QStringList() << desktop)) {
91− if (desktopFile.startsWith(helper)) {
92− QFileInfo fileInfo(searchDir, desktopFile);
93− m_filename = fileInfo.absoluteFilePath();
94− return;
95− }
96− }
97− }
98−
99− dashPos = helper.indexOf('-');
100− } while (dashPos != -1);
101−}
102−
103−QString DesktopFileHandler::displayName() const
104−{
105− if (!isValid()) {
106− return QString();
107− }
108−
109− QSettings settings(m_filename, QSettings::IniFormat);
110− settings.setIniCodec("UTF-8");
111− settings.beginGroup(QStringLiteral("Desktop Entry"));
112−
113− // First try to find Name[xx_YY] and Name[xx] in .desktop file
114− const QString locale = QLocale().name();
115− const QStringList splitLocale = locale.split(QLatin1Char('_'));
116− const QString shortLocale = splitLocale.first();
117−
118− if (locale != shortLocale && settings.contains(QStringLiteral("Name[%1]").arg(locale))) {
119− return settings.value(QStringLiteral("Name[%1]").arg(locale)).toString();
120− }
121−
122− if (settings.contains(QStringLiteral("Name[%1]").arg(shortLocale))) {
123− return settings.value(QStringLiteral("Name[%1]").arg(shortLocale)).toString();
124− }
125−
126− // No translation found in desktop file. Get the untranslated one and have a go with gettext.
127− QString displayName = settings.value(QStringLiteral("Name")).toString();
128−
129− if (settings.contains(QStringLiteral("X-Ubuntu-Gettext-Domain"))) {
130− const QString domain = settings.value(QStringLiteral("X-Ubuntu-Gettext-Domain")).toString();
131− return dgettext(domain.toUtf8().constData(), displayName.toUtf8().constData());
132− }
133−
134− return displayName;
135−}
136−
137−QString DesktopFileHandler::icon() const
138−{
139− if (!isValid()) {
140− return QString();
141− }
142−
143− QSettings settings(m_filename, QSettings::IniFormat);
144− settings.setIniCodec("UTF-8");
145− settings.beginGroup(QStringLiteral("Desktop Entry"));
146− QString iconString = settings.value(QStringLiteral("Icon")).toString();
147− QString pathString = settings.value(QStringLiteral("Path")).toString();
148−
149− if (QFileInfo::exists(iconString)) {
150− return QFileInfo(iconString).absoluteFilePath();
151− } else if (QFileInfo::exists(pathString + '/' + iconString)) {
152− return pathString + '/' + iconString;
153− }
154− return "image://theme/" + iconString;
155−}
plugins/Unity/Launcher/desktopfilehandler.hdeleted−56
@@ -1,56 +0,0 @@
1−/*
2− * Copyright 2014 Canonical Ltd.
3− *
4− * 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 by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU Lesser General Public License for more details.
12− *
13− * You should have received a copy of the GNU Lesser General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors:
17− * Michael Zanetti <michael.zanetti@canonical.com>
18− */
19−
20−#ifndef DESKTOPFILEHANDLER_H
21−#define DESKTOPFILEHANDLER_H
22−
23−#include <QObject>
24−
25−/**
26− * When an object of this class is created or whenever setAppId(appId) is called,
27− * this will search for a .desktop file matching the give appId. If a file is
28− * found, isValid() will return true and the other methods return the contents
29− * of the .desktop file.
30− *
31− * Note that this class will consider the user's locale and do a best effort
32− * to return localized values.
33− */
34−
35−class DesktopFileHandler: public QObject
36−{
37− Q_OBJECT
38−public:
39− DesktopFileHandler(const QString &appId = QString(), QObject *parent = nullptr);
40−
41− QString appId() const;
42− void setAppId(const QString &appId);
43−
44− bool isValid() const;
45− QString filename() const;
46− QString displayName() const;
47− QString icon() const;
48−
49−private:
50− void load();
51−
52− QString m_appId;
53− QString m_filename;
54−};
55−
56−#endif
plugins/Unity/Launcher/launchermodel.cpp+40−22
@@ -20,10 +20,10 @@
2020#include "launchermodel.h"
2121#include "launcheritem.h"
2222#include "gsettings.h"
23−#include "desktopfilehandler.h"
2423#include "dbusinterface.h"
2524#include "asadapter.h"
2625
26+#include <ubuntu-app-launch/application.h>
2727#include <unity/shell/application/ApplicationInfoInterface.h>
2828#include <unity/shell/application/MirSurfaceListInterface.h>
2929
@@ -37,7 +37,8 @@ LauncherModel::LauncherModel(QObject *parent):
3737 m_settings(new GSettings(this)),
3838 m_dbusIface(new DBusInterface(this)),
3939 m_asAdapter(new ASAdapter()),
40− m_appManager(nullptr)
40+ m_appManager(nullptr),
41+ m_ualRegistry(std::make_shared<ubuntu::app_launch::Registry>())
4142{
4243 connect(m_dbusIface, &DBusInterface::countChanged, this, &LauncherModel::countChanged);
4344 connect(m_dbusIface, &DBusInterface::countVisibleChanged, this, &LauncherModel::countVisibleChanged);
@@ -157,16 +158,16 @@ void LauncherModel::pin(const QString &appId, int index)
157158 index = m_list.count();
158159 }
159160
160− DesktopFileHandler desktopFile(appId);
161− if (!desktopFile.isValid()) {
162− qWarning() << "Can't pin this application, there is no .desktop file available.";
161+ auto appInfo = getApplicationInfo(appId);
162+ if (!appInfo) {
163+ qWarning() << "Can't pin application, appId not found:" << appId;
163164 return;
164165 }
165166
166167 beginInsertRows(QModelIndex(), index, index);
167168 LauncherItem *item = new LauncherItem(appId,
168− desktopFile.displayName(),
169− desktopFile.icon(),
169+ QString::fromStdString(appInfo->info()->name()),
170+ QString::fromStdString(appInfo->info()->iconPath()),
170171 this);
171172 item->setPinned(true);
172173 m_list.insert(index, item);
@@ -333,6 +334,24 @@ int LauncherModel::findApplication(const QString &appId)
333334 return -1;
334335}
335336
337+std::shared_ptr<ubuntu::app_launch::Application> LauncherModel::getApplicationInfo(const QString &appId)
338+{
339+ auto ualAppId = ubuntu::app_launch::AppID::find(appId.toStdString());
340+ if (ualAppId.empty()) {
341+ return nullptr;
342+ }
343+
344+ try
345+ {
346+ return ubuntu::app_launch::Application::create(ualAppId, m_ualRegistry);
347+ }
348+ catch (std::runtime_error &e)
349+ {
350+ qWarning() << "Couldn't find application info for" << appId << "-" << e.what();
351+ return nullptr;
352+ }
353+}
354+
336355void LauncherModel::progressChanged(const QString &appId, int progress)
337356{
338357 const int idx = findApplication(appId);
@@ -380,11 +399,11 @@ void LauncherModel::countVisibleChanged(const QString &appId, bool countVisible)
380399 }
381400 } else {
382401 // Need to create a new LauncherItem and show the highlight
383− DesktopFileHandler desktopFile(appId);
384− if (countVisible && desktopFile.isValid()) {
402+ auto appInfo = getApplicationInfo(appId);
403+ if (countVisible && appInfo) {
385404 LauncherItem *item = new LauncherItem(appId,
386− desktopFile.displayName(),
387− desktopFile.icon(),
405+ QString::fromStdString(appInfo->info()->name()),
406+ QString::fromStdString(appInfo->info()->iconPath()),
388407 this);
389408 item->setCountVisible(true);
390409 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
@@ -400,28 +419,28 @@ void LauncherModel::refresh()
400419 // First walk through all the existing items and see if we need to remove something
401420 QList<LauncherItem*> toBeRemoved;
402421 Q_FOREACH (LauncherItem* item, m_list) {
403− DesktopFileHandler desktopFile(item->appId());
404− if (!desktopFile.isValid()) {
405− // Desktop file not available for this app => drop it!
422+ auto appInfo = getApplicationInfo(item->appId());
423+ if (!appInfo) {
424+ // Application no longer available => drop it!
406425 toBeRemoved << item;
407426 } else if (!m_settings->storedApplications().contains(item->appId())) {
408427 // Item not in settings any more => drop it!
409428 toBeRemoved << item;
410429 } else {
411430 int idx = m_list.indexOf(item);
412− item->setName(desktopFile.displayName());
431+ item->setName(QString::fromStdString(appInfo->info()->name()));
413432 item->setPinned(item->pinned()); // update pinned text if needed
414433 item->setRunning(item->running());
415434 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleRunning});
416435
417436 const QString oldIcon = item->icon();
418− if (oldIcon == desktopFile.icon()) { // same icon file, perhaps different contents, simulate changing the icon name to force reload
437+ if (oldIcon == QString::fromStdString(appInfo->info()->iconPath())) { // same icon file, perhaps different contents, simulate changing the icon name to force reload
419438 item->setIcon(QString());
420439 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
421440 }
422441
423442 // now set the icon for real
424− item->setIcon(desktopFile.icon());
443+ item->setIcon(QString::fromStdString(appInfo->info()->iconPath()));
425444 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
426445 }
427446 }
@@ -452,15 +471,14 @@ void LauncherModel::refresh()
452471 if (itemIndex == -1) {
453472 // Need to add it. Just add it into the addedIndex to keep same ordering as the list
454473 // in the settings.
455− DesktopFileHandler desktopFile(entry);
456− if (!desktopFile.isValid()) {
457− qWarning() << "Couldn't find a .desktop file for" << entry << ". Skipping...";
474+ auto appInfo = getApplicationInfo(entry);
475+ if (!appInfo) {
458476 continue;
459477 }
460478
461479 LauncherItem *item = new LauncherItem(entry,
462− desktopFile.displayName(),
463− desktopFile.icon(),
480+ QString::fromStdString(appInfo->info()->name()),
481+ QString::fromStdString(appInfo->info()->iconPath()),
464482 this);
465483 item->setPinned(true);
466484 beginInsertRows(QModelIndex(), addedIndex, addedIndex);
plugins/Unity/Launcher/launchermodel.h+9
@@ -20,6 +20,7 @@
2020#ifndef LAUNCHERMODEL_H
2121#define LAUNCHERMODEL_H
2222
23+#include <ubuntu-app-launch/registry.h>
2324#include <unity/shell/launcher/LauncherModelInterface.h>
2425#include <unity/shell/application/ApplicationManagerInterface.h>
2526
@@ -30,6 +31,12 @@ class GSettings;
3031class DBusInterface;
3132class ASAdapter;
3233
34+namespace ubuntu {
35+ namespace app_launch {
36+ class Application;
37+ }
38+}
39+
3340using namespace unity::shell::launcher;
3441using namespace unity::shell::application;
3542
@@ -69,6 +76,7 @@ private:
6976 void storeAppList();
7077
7178 void unpin(const QString &appId);
79+ std::shared_ptr<ubuntu::app_launch::Application> getApplicationInfo(const QString &appId);
7280
7381private Q_SLOTS:
7482 void countChanged(const QString &appId, int count);
@@ -88,6 +96,7 @@ private:
8896 ASAdapter *m_asAdapter;
8997
9098 ApplicationManagerInterface *m_appManager;
99+ std::shared_ptr<ubuntu::app_launch::Registry> m_ualRegistry;
91100
92101 friend class LauncherModelTest;
93102};
tests/plugins/Unity/Launcher/CMakeLists.txt+12−19
@@ -6,9 +6,14 @@ include_directories(
66 ${CMAKE_CURRENT_BINARY_DIR}
77 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
88 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher
9+ ${libunity8-private_SOURCE_DIR}
10+ )
11+
12+include_directories(
13+ SYSTEM
914 ${GSETTINGS_QT_INCLUDE_DIRS}
1015 ${GLIB_INCLUDE_DIRS}
11− ${libunity8-private_SOURCE_DIR}
16+ ${UAL_INCLUDE_DIRS}
1217 )
1318
1419add_definitions(-DSM_BUSNAME=sessionBus)
@@ -25,7 +30,6 @@ add_executable(launchermodeltestExec
2530 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/launcheritem.cpp
2631 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistmodel.cpp
2732 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/dbusinterface.cpp
28− ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/desktopfilehandler.cpp
2933 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistentry.cpp
3034 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
3135 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
@@ -37,11 +41,13 @@ target_link_libraries(launchermodeltestExec
3741 unity8-private
3842 ${GSETTINGS_QT_LDFLAGS}
3943 ${GLIB_LIBRARIES}
44+ ${UAL_LIBRARIES}
4045 )
4146add_dependencies(launchermodeltestExec mock-server)
4247qt5_use_modules(launchermodeltestExec Test Core DBus Xml Gui)
4348
4449add_unity8_unittest(LauncherModel dbus-test-runner
50+ ENVIRONMENT "XDG_DATA_HOME=${CMAKE_CURRENT_BINARY_DIR}"
4551 ARG_PREFIX "--parameter"
4652 ARGS
4753 --task $<TARGET_FILE:mock-server>
@@ -50,20 +56,7 @@ add_unity8_unittest(LauncherModel dbus-test-runner
5056 --wait-for org.freedesktop.Accounts
5157)
5258
53−# copy .desktop files into build directory for shadow builds
54−file(GLOB DESKTOP_FILES *.desktop)
55−
56−foreach(DESKTOP_FILE ${DESKTOP_FILES})
57− file(COPY "${DESKTOP_FILE}"
58− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
59− )
60−endforeach()
61−
62−# copy .svg files into build directory for shadow builds
63−file(GLOB DESKTOP_FILES *.svg)
64−
65−foreach(DESKTOP_FILE ${DESKTOP_FILES})
66− file(COPY "${DESKTOP_FILE}"
67− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
68− )
69−endforeach()
59+# copy sample application files into build directory for shadow builds
60+file(COPY applications
61+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
62+ )
tests/plugins/Unity/Launcher/abs-icon.desktop → tests/plugins/Unity/Launcher/applications/abs-icon.desktoprenamed+1
@@ -1,3 +1,4 @@
11[Desktop Entry]
2+Type=Application
23Name=Absolute Icon
34Icon=/path/to/icon.png
tests/plugins/Unity/Launcher/click-icon.desktop → tests/plugins/Unity/Launcher/applications/click-icon.desktoprenamed+1
@@ -1,4 +1,5 @@
11[Desktop Entry]
2+Type=Application
23Name=Click Package Icon
34Icon=click-icon.svg
45Path=/path/to/some/click/app
tests/plugins/Unity/Launcher/click-icon.svg → tests/plugins/Unity/Launcher/applications/click-icon.svgrenamed

The content is the same.

tests/plugins/Unity/Launcher/no-name.desktop → tests/plugins/Unity/Launcher/applications/no-name.desktoprenamed+1
@@ -1,2 +1,3 @@
11[Desktop Entry]
2+Type=Application
23Icon=no-name
tests/plugins/Unity/Launcher/rel-icon.desktop → tests/plugins/Unity/Launcher/applications/rel-icon.desktoprenamed+1
@@ -1,3 +1,4 @@
11[Desktop Entry]
2+Type=Application
23Name=Relative Icon
34Icon=rel-icon.svg
tests/plugins/Unity/Launcher/rel-icon.svg → tests/plugins/Unity/Launcher/applications/rel-icon.svgrenamed

The content is the same.

tests/plugins/Unity/Launcher/launchermodeltest.cpp+18−18
@@ -177,7 +177,7 @@ private Q_SLOTS:
177177 appManager->addApplication(new MockApp("abs-icon"));
178178 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
179179
180− appManager->addApplication(new MockApp("no-icon"));
180+ appManager->addApplication(new MockApp("rel-icon"));
181181 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
182182
183183 launcherModel->m_settings->setStoredApplications(QStringList());
@@ -199,6 +199,10 @@ private Q_SLOTS:
199199 QString::fromUtf8(g_get_user_name()));
200200 QVERIFY(removeReply.isValid());
201201 QCOMPARE(removeReply.value(), true);
202+
203+ // Some tests move the directory, so lets move it back if so.
204+ // But this will usually fail.
205+ QFile::rename("applications.old", "applications");
202206 }
203207
204208 void testMove() {
@@ -331,7 +335,7 @@ private Q_SLOTS:
331335
332336 void testApplicationRunning() {
333337 launcherModel->pin("abs-icon");
334− launcherModel->pin("no-icon");
338+ launcherModel->pin("rel-icon");
335339
336340 QCOMPARE(launcherModel->get(0)->running(), true);
337341 QCOMPARE(launcherModel->get(1)->running(), true);
@@ -340,7 +344,7 @@ private Q_SLOTS:
340344 QCOMPARE(launcherModel->get(0)->running(), false);
341345 QCOMPARE(launcherModel->get(1)->running(), true);
342346
343− appManager->stopApplication("no-icon");
347+ appManager->stopApplication("rel-icon");
344348 QCOMPARE(launcherModel->get(0)->running(), false);
345349 QCOMPARE(launcherModel->get(1)->running(), false);
346350 }
@@ -355,7 +359,7 @@ private Q_SLOTS:
355359 QCOMPARE(launcherModel->get(0)->focused(), true);
356360 QCOMPARE(launcherModel->get(1)->focused(), false);
357361
358− appManager->focusApplication("no-icon");
362+ appManager->focusApplication("rel-icon");
359363 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
360364 QCOMPARE(launcherModel->get(0)->focused(), false);
361365 QCOMPARE(launcherModel->get(1)->focused(), true);
@@ -377,8 +381,8 @@ private Q_SLOTS:
377381 QCOMPARE(launcherModel->rowCount(), 2);
378382
379383 // stop the second one keeping it pinned so that it doesn't go away
380− launcherModel->pin("no-icon");
381− appManager->stopApplication("no-icon");
384+ launcherModel->pin("rel-icon");
385+ appManager->stopApplication("rel-icon");
382386
383387 // find the first Quit item, should be there
384388 QuickListModel *model = qobject_cast<QuickListModel*>(launcherModel->get(0)->quickList());
@@ -407,7 +411,7 @@ private Q_SLOTS:
407411 // first app should be gone...
408412 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
409413 // ... the second app (now at index 0) should still be there, pinned and stopped
410− QCOMPARE(launcherModel->get(0)->appId(), QStringLiteral("no-icon"));
414+ QCOMPARE(launcherModel->get(0)->appId(), QStringLiteral("rel-icon"));
411415 QCOMPARE(launcherModel->get(0)->pinned(), true);
412416 QCOMPARE(launcherModel->get(0)->running(), false);
413417 }
@@ -602,17 +606,16 @@ private Q_SLOTS:
602606
603607 // pin both apps
604608 launcherModel->pin("abs-icon");
605− launcherModel->pin("no-icon");
609+ launcherModel->pin("rel-icon");
606610 // close both apps
607611 appManager->removeApplication(0);
608612 appManager->removeApplication(0);
609613
610614 // "delete" the .desktop files
611− QString oldCurrent = QDir::currentPath();
612615 if (deleted) {
613616 // In testing mode, the launcher searches the current dir for the sample .desktop file
614− // We can make that fail by changing the current dir
615− QDir::setCurrent("..");
617+ // We can make that fail by moving the applications dir
618+ QFile::rename("applications", "applications.old");
616619 }
617620
618621 // Call refresh
@@ -623,9 +626,6 @@ private Q_SLOTS:
623626 QCOMPARE(reply.isValid(), true);
624627
625628 QCOMPARE(launcherModel->rowCount(), deleted ? 0 : 2);
626−
627− // Restoring current dir
628− QDir::setCurrent(oldCurrent);
629629 }
630630
631631 void testSettings() {
@@ -637,7 +637,7 @@ private Q_SLOTS:
637637
638638 // pin both apps
639639 launcherModel->pin("abs-icon");
640− launcherModel->pin("no-icon");
640+ launcherModel->pin("rel-icon");
641641 QCOMPARE(spy.count(), 0);
642642
643643 // Now settings should have 2 apps
@@ -659,9 +659,9 @@ private Q_SLOTS:
659659 QCOMPARE(launcherModel->rowCount(), 1);
660660
661661 // Add them back but in reverse order
662− settings->simulateDConfChanged(QStringList() << "no-icon" << "abs-icon");
662+ settings->simulateDConfChanged(QStringList() << "rel-icon" << "abs-icon");
663663 QCOMPARE(launcherModel->rowCount(), 2);
664− QCOMPARE(launcherModel->get(0)->appId(), QString("no-icon"));
664+ QCOMPARE(launcherModel->get(0)->appId(), QString("rel-icon"));
665665 QCOMPARE(launcherModel->get(1)->appId(), QString("abs-icon"));
666666 QCOMPARE(spy.count(), 2);
667667 }
@@ -671,7 +671,7 @@ private Q_SLOTS:
671671 QCOMPARE(launcherModel->rowCount(), getASConfig().count());
672672
673673 int oldCount = launcherModel->rowCount();
674− appManager->addApplication(new MockApp("rel-icon"));
674+ appManager->addApplication(new MockApp("click-icon"));
675675 QCOMPARE(launcherModel->rowCount(), oldCount + 1);
676676 QCOMPARE(launcherModel->rowCount(), getASConfig().count());
677677 }
tests/plugins/Unity/Launcher/no-icon.desktopdeleted−2
@@ -1,2 +0,0 @@
1−[Desktop Entry]
2−Name=No Icon