on xenial help sign in
Use UAL instead of manually parsing a desktop file for launcher
a69ada0Michael Terry
CMakeLists.txt+1−1
@@ -63,7 +63,7 @@ pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
63pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
63pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
64pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
64pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
65pkg_check_modules(GD3 REQUIRED gnome-desktop-3.0)
65pkg_check_modules(GD3 REQUIRED gnome-desktop-3.0)
66−
66+pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2)
67pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
67pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
68
68
69### Check UbuntuGestures private headers. No pkg-config (.pc) file is provided for them
69### 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)
6include_directories(
6include_directories(
7 ${CMAKE_CURRENT_SOURCE_DIR}
7 ${CMAKE_CURRENT_SOURCE_DIR}
8 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
8 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
9− ${GSETTINGS_QT_INCLUDE_DIRS}
10− ${GLIB_INCLUDE_DIRS}
11 ${libunity8-private_SOURCE_DIR}
9 ${libunity8-private_SOURCE_DIR}
12)
10)
13
11
12+include_directories(
13+ SYSTEM
14+ ${GSETTINGS_QT_INCLUDE_DIRS}
15+ ${GLIB_INCLUDE_DIRS}
16+ ${UAL_INCLUDE_DIRS}
17+ )
18+
14set(QMLLAUNCHERPLUGIN_SRC
19set(QMLLAUNCHERPLUGIN_SRC
15 plugin.cpp
20 plugin.cpp
16 launchermodel.cpp
21 launchermodel.cpp
@@ -19,7 +24,6 @@ set(QMLLAUNCHERPLUGIN_SRC
19 quicklistentry.cpp
24 quicklistentry.cpp
20 dbusinterface.cpp
25 dbusinterface.cpp
21 gsettings.cpp
26 gsettings.cpp
22− desktopfilehandler.cpp
23 asadapter.cpp
27 asadapter.cpp
24 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
28 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
25 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
29 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
@@ -38,6 +42,7 @@ target_link_libraries(UnityLauncher-qml
38 unity8-private
42 unity8-private
39 ${GSETTINGS_QT_LDFLAGS}
43 ${GSETTINGS_QT_LDFLAGS}
40 ${GLIB_LIBRARIES}
44 ${GLIB_LIBRARIES}
45+ ${UAL_LIBRARIES}
41 )
46 )
42
47
43qt5_use_modules(UnityLauncher-qml DBus Qml Gui)
48qt5_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 @@
20#include "launchermodel.h"
20#include "launchermodel.h"
21#include "launcheritem.h"
21#include "launcheritem.h"
22#include "gsettings.h"
22#include "gsettings.h"
23−#include "desktopfilehandler.h"
24#include "dbusinterface.h"
23#include "dbusinterface.h"
25#include "asadapter.h"
24#include "asadapter.h"
26
25
26+#include <ubuntu-app-launch/application.h>
27#include <unity/shell/application/ApplicationInfoInterface.h>
27#include <unity/shell/application/ApplicationInfoInterface.h>
28#include <unity/shell/application/MirSurfaceListInterface.h>
28#include <unity/shell/application/MirSurfaceListInterface.h>
29
29
@@ -37,7 +37,8 @@ LauncherModel::LauncherModel(QObject *parent):
37 m_settings(new GSettings(this)),
37 m_settings(new GSettings(this)),
38 m_dbusIface(new DBusInterface(this)),
38 m_dbusIface(new DBusInterface(this)),
39 m_asAdapter(new ASAdapter()),
39 m_asAdapter(new ASAdapter()),
40− m_appManager(nullptr)
40+ m_appManager(nullptr),
41+ m_ualRegistry(std::make_shared<ubuntu::app_launch::Registry>())
41{
42{
42 connect(m_dbusIface, &DBusInterface::countChanged, this, &LauncherModel::countChanged);
43 connect(m_dbusIface, &DBusInterface::countChanged, this, &LauncherModel::countChanged);
43 connect(m_dbusIface, &DBusInterface::countVisibleChanged, this, &LauncherModel::countVisibleChanged);
44 connect(m_dbusIface, &DBusInterface::countVisibleChanged, this, &LauncherModel::countVisibleChanged);
@@ -157,16 +158,16 @@ void LauncherModel::pin(const QString &appId, int index)
157 index = m_list.count();
158 index = m_list.count();
158 }
159 }
159
160
160− DesktopFileHandler desktopFile(appId);
161+ auto appInfo = getApplicationInfo(appId);
161− if (!desktopFile.isValid()) {
162+ if (!appInfo) {
162− qWarning() << "Can't pin this application, there is no .desktop file available.";
163+ qWarning() << "Can't pin application, appId not found:" << appId;
163 return;
164 return;
164 }
165 }
165
166
166 beginInsertRows(QModelIndex(), index, index);
167 beginInsertRows(QModelIndex(), index, index);
167 LauncherItem *item = new LauncherItem(appId,
168 LauncherItem *item = new LauncherItem(appId,
168− desktopFile.displayName(),
169+ QString::fromStdString(appInfo->info()->name()),
169− desktopFile.icon(),
170+ QString::fromStdString(appInfo->info()->iconPath()),
170 this);
171 this);
171 item->setPinned(true);
172 item->setPinned(true);
172 m_list.insert(index, item);
173 m_list.insert(index, item);
@@ -333,6 +334,24 @@ int LauncherModel::findApplication(const QString &appId)
333 return -1;
334 return -1;
334}
335}
335
336
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+
336void LauncherModel::progressChanged(const QString &appId, int progress)
355void LauncherModel::progressChanged(const QString &appId, int progress)
337{
356{
338 const int idx = findApplication(appId);
357 const int idx = findApplication(appId);
@@ -380,11 +399,11 @@ void LauncherModel::countVisibleChanged(const QString &appId, bool countVisible)
380 }
399 }
381 } else {
400 } else {
382 // Need to create a new LauncherItem and show the highlight
401 // Need to create a new LauncherItem and show the highlight
383− DesktopFileHandler desktopFile(appId);
402+ auto appInfo = getApplicationInfo(appId);
384− if (countVisible && desktopFile.isValid()) {
403+ if (countVisible && appInfo) {
385 LauncherItem *item = new LauncherItem(appId,
404 LauncherItem *item = new LauncherItem(appId,
386− desktopFile.displayName(),
405+ QString::fromStdString(appInfo->info()->name()),
387− desktopFile.icon(),
406+ QString::fromStdString(appInfo->info()->iconPath()),
388 this);
407 this);
389 item->setCountVisible(true);
408 item->setCountVisible(true);
390 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
409 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
@@ -400,28 +419,28 @@ void LauncherModel::refresh()
400 // First walk through all the existing items and see if we need to remove something
419 // First walk through all the existing items and see if we need to remove something
401 QList<LauncherItem*> toBeRemoved;
420 QList<LauncherItem*> toBeRemoved;
402 Q_FOREACH (LauncherItem* item, m_list) {
421 Q_FOREACH (LauncherItem* item, m_list) {
403− DesktopFileHandler desktopFile(item->appId());
422+ auto appInfo = getApplicationInfo(item->appId());
404− if (!desktopFile.isValid()) {
423+ if (!appInfo) {
405− // Desktop file not available for this app => drop it!
424+ // Application no longer available => drop it!
406 toBeRemoved << item;
425 toBeRemoved << item;
407 } else if (!m_settings->storedApplications().contains(item->appId())) {
426 } else if (!m_settings->storedApplications().contains(item->appId())) {
408 // Item not in settings any more => drop it!
427 // Item not in settings any more => drop it!
409 toBeRemoved << item;
428 toBeRemoved << item;
410 } else {
429 } else {
411 int idx = m_list.indexOf(item);
430 int idx = m_list.indexOf(item);
412− item->setName(desktopFile.displayName());
431+ item->setName(QString::fromStdString(appInfo->info()->name()));
413 item->setPinned(item->pinned()); // update pinned text if needed
432 item->setPinned(item->pinned()); // update pinned text if needed
414 item->setRunning(item->running());
433 item->setRunning(item->running());
415 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleRunning});
434 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleRunning});
416
435
417 const QString oldIcon = item->icon();
436 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
419 item->setIcon(QString());
438 item->setIcon(QString());
420 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
439 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
421 }
440 }
422
441
423 // now set the icon for real
442 // now set the icon for real
424− item->setIcon(desktopFile.icon());
443+ item->setIcon(QString::fromStdString(appInfo->info()->iconPath()));
425 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
444 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
426 }
445 }
427 }
446 }
@@ -452,15 +471,14 @@ void LauncherModel::refresh()
452 if (itemIndex == -1) {
471 if (itemIndex == -1) {
453 // Need to add it. Just add it into the addedIndex to keep same ordering as the list
472 // Need to add it. Just add it into the addedIndex to keep same ordering as the list
454 // in the settings.
473 // in the settings.
455− DesktopFileHandler desktopFile(entry);
474+ auto appInfo = getApplicationInfo(entry);
456− if (!desktopFile.isValid()) {
475+ if (!appInfo) {
457− qWarning() << "Couldn't find a .desktop file for" << entry << ". Skipping...";
458 continue;
476 continue;
459 }
477 }
460
478
461 LauncherItem *item = new LauncherItem(entry,
479 LauncherItem *item = new LauncherItem(entry,
462− desktopFile.displayName(),
480+ QString::fromStdString(appInfo->info()->name()),
463− desktopFile.icon(),
481+ QString::fromStdString(appInfo->info()->iconPath()),
464 this);
482 this);
465 item->setPinned(true);
483 item->setPinned(true);
466 beginInsertRows(QModelIndex(), addedIndex, addedIndex);
484 beginInsertRows(QModelIndex(), addedIndex, addedIndex);
plugins/Unity/Launcher/launchermodel.h+9
@@ -20,6 +20,7 @@
20#ifndef LAUNCHERMODEL_H
20#ifndef LAUNCHERMODEL_H
21#define LAUNCHERMODEL_H
21#define LAUNCHERMODEL_H
22
22
23+#include <ubuntu-app-launch/registry.h>
23#include <unity/shell/launcher/LauncherModelInterface.h>
24#include <unity/shell/launcher/LauncherModelInterface.h>
24#include <unity/shell/application/ApplicationManagerInterface.h>
25#include <unity/shell/application/ApplicationManagerInterface.h>
25
26
@@ -30,6 +31,12 @@ class GSettings;
30class DBusInterface;
31class DBusInterface;
31class ASAdapter;
32class ASAdapter;
32
33
34+namespace ubuntu {
35+ namespace app_launch {
36+ class Application;
37+ }
38+}
39+
33using namespace unity::shell::launcher;
40using namespace unity::shell::launcher;
34using namespace unity::shell::application;
41using namespace unity::shell::application;
35
42
@@ -69,6 +76,7 @@ private:
69 void storeAppList();
76 void storeAppList();
70
77
71 void unpin(const QString &appId);
78 void unpin(const QString &appId);
79+ std::shared_ptr<ubuntu::app_launch::Application> getApplicationInfo(const QString &appId);
72
80
73private Q_SLOTS:
81private Q_SLOTS:
74 void countChanged(const QString &appId, int count);
82 void countChanged(const QString &appId, int count);
@@ -88,6 +96,7 @@ private:
88 ASAdapter *m_asAdapter;
96 ASAdapter *m_asAdapter;
89
97
90 ApplicationManagerInterface *m_appManager;
98 ApplicationManagerInterface *m_appManager;
99+ std::shared_ptr<ubuntu::app_launch::Registry> m_ualRegistry;
91
100
92 friend class LauncherModelTest;
101 friend class LauncherModelTest;
93};
102};
tests/plugins/Unity/Launcher/CMakeLists.txt+12−19
@@ -6,9 +6,14 @@ include_directories(
6 ${CMAKE_CURRENT_BINARY_DIR}
6 ${CMAKE_CURRENT_BINARY_DIR}
7 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
7 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
8 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher
8 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher
9+ ${libunity8-private_SOURCE_DIR}
10+ )
11+
12+include_directories(
13+ SYSTEM
9 ${GSETTINGS_QT_INCLUDE_DIRS}
14 ${GSETTINGS_QT_INCLUDE_DIRS}
10 ${GLIB_INCLUDE_DIRS}
15 ${GLIB_INCLUDE_DIRS}
11− ${libunity8-private_SOURCE_DIR}
16+ ${UAL_INCLUDE_DIRS}
12 )
17 )
13
18
14add_definitions(-DSM_BUSNAME=sessionBus)
19add_definitions(-DSM_BUSNAME=sessionBus)
@@ -25,7 +30,6 @@ add_executable(launchermodeltestExec
25 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/launcheritem.cpp
30 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/launcheritem.cpp
26 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistmodel.cpp
31 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistmodel.cpp
27 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/dbusinterface.cpp
32 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/dbusinterface.cpp
28− ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/desktopfilehandler.cpp
29 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistentry.cpp
33 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistentry.cpp
30 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
34 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
31 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
35 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
@@ -37,11 +41,13 @@ target_link_libraries(launchermodeltestExec
37 unity8-private
41 unity8-private
38 ${GSETTINGS_QT_LDFLAGS}
42 ${GSETTINGS_QT_LDFLAGS}
39 ${GLIB_LIBRARIES}
43 ${GLIB_LIBRARIES}
44+ ${UAL_LIBRARIES}
40 )
45 )
41add_dependencies(launchermodeltestExec mock-server)
46add_dependencies(launchermodeltestExec mock-server)
42qt5_use_modules(launchermodeltestExec Test Core DBus Xml Gui)
47qt5_use_modules(launchermodeltestExec Test Core DBus Xml Gui)
43
48
44add_unity8_unittest(LauncherModel dbus-test-runner
49add_unity8_unittest(LauncherModel dbus-test-runner
50+ ENVIRONMENT "XDG_DATA_HOME=${CMAKE_CURRENT_BINARY_DIR}"
45 ARG_PREFIX "--parameter"
51 ARG_PREFIX "--parameter"
46 ARGS
52 ARGS
47 --task $<TARGET_FILE:mock-server>
53 --task $<TARGET_FILE:mock-server>
@@ -50,20 +56,7 @@ add_unity8_unittest(LauncherModel dbus-test-runner
50 --wait-for org.freedesktop.Accounts
56 --wait-for org.freedesktop.Accounts
51)
57)
52
58
53−# copy .desktop files into build directory for shadow builds
59+# copy sample application files into build directory for shadow builds
54−file(GLOB DESKTOP_FILES *.desktop)
60+file(COPY applications
55−
56−foreach(DESKTOP_FILE ${DESKTOP_FILES})
57− file(COPY "${DESKTOP_FILE}"
58− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
61+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
59− )
62+ )
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()
tests/plugins/Unity/Launcher/abs-icon.desktop → tests/plugins/Unity/Launcher/applications/abs-icon.desktoprenamed+1
@@ -1,3 +1,4 @@
1[Desktop Entry]
1[Desktop Entry]
2+Type=Application
2Name=Absolute Icon
3Name=Absolute Icon
3Icon=/path/to/icon.png
4Icon=/path/to/icon.png
tests/plugins/Unity/Launcher/click-icon.desktop → tests/plugins/Unity/Launcher/applications/click-icon.desktoprenamed+1
@@ -1,4 +1,5 @@
1[Desktop Entry]
1[Desktop Entry]
2+Type=Application
2Name=Click Package Icon
3Name=Click Package Icon
3Icon=click-icon.svg
4Icon=click-icon.svg
4Path=/path/to/some/click/app
5Path=/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 @@
1[Desktop Entry]
1[Desktop Entry]
2+Type=Application
2Icon=no-name
3Icon=no-name
tests/plugins/Unity/Launcher/rel-icon.desktop → tests/plugins/Unity/Launcher/applications/rel-icon.desktoprenamed+1
@@ -1,3 +1,4 @@
1[Desktop Entry]
1[Desktop Entry]
2+Type=Application
2Name=Relative Icon
3Name=Relative Icon
3Icon=rel-icon.svg
4Icon=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:
177 appManager->addApplication(new MockApp("abs-icon"));
177 appManager->addApplication(new MockApp("abs-icon"));
178 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
178 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
179
179
180− appManager->addApplication(new MockApp("no-icon"));
180+ appManager->addApplication(new MockApp("rel-icon"));
181 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
181 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
182
182
183 launcherModel->m_settings->setStoredApplications(QStringList());
183 launcherModel->m_settings->setStoredApplications(QStringList());
@@ -199,6 +199,10 @@ private Q_SLOTS:
199 QString::fromUtf8(g_get_user_name()));
199 QString::fromUtf8(g_get_user_name()));
200 QVERIFY(removeReply.isValid());
200 QVERIFY(removeReply.isValid());
201 QCOMPARE(removeReply.value(), true);
201 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");
202 }
206 }
203
207
204 void testMove() {
208 void testMove() {
@@ -331,7 +335,7 @@ private Q_SLOTS:
331
335
332 void testApplicationRunning() {
336 void testApplicationRunning() {
333 launcherModel->pin("abs-icon");
337 launcherModel->pin("abs-icon");
334− launcherModel->pin("no-icon");
338+ launcherModel->pin("rel-icon");
335
339
336 QCOMPARE(launcherModel->get(0)->running(), true);
340 QCOMPARE(launcherModel->get(0)->running(), true);
337 QCOMPARE(launcherModel->get(1)->running(), true);
341 QCOMPARE(launcherModel->get(1)->running(), true);
@@ -340,7 +344,7 @@ private Q_SLOTS:
340 QCOMPARE(launcherModel->get(0)->running(), false);
344 QCOMPARE(launcherModel->get(0)->running(), false);
341 QCOMPARE(launcherModel->get(1)->running(), true);
345 QCOMPARE(launcherModel->get(1)->running(), true);
342
346
343− appManager->stopApplication("no-icon");
347+ appManager->stopApplication("rel-icon");
344 QCOMPARE(launcherModel->get(0)->running(), false);
348 QCOMPARE(launcherModel->get(0)->running(), false);
345 QCOMPARE(launcherModel->get(1)->running(), false);
349 QCOMPARE(launcherModel->get(1)->running(), false);
346 }
350 }
@@ -355,7 +359,7 @@ private Q_SLOTS:
355 QCOMPARE(launcherModel->get(0)->focused(), true);
359 QCOMPARE(launcherModel->get(0)->focused(), true);
356 QCOMPARE(launcherModel->get(1)->focused(), false);
360 QCOMPARE(launcherModel->get(1)->focused(), false);
357
361
358− appManager->focusApplication("no-icon");
362+ appManager->focusApplication("rel-icon");
359 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
363 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
360 QCOMPARE(launcherModel->get(0)->focused(), false);
364 QCOMPARE(launcherModel->get(0)->focused(), false);
361 QCOMPARE(launcherModel->get(1)->focused(), true);
365 QCOMPARE(launcherModel->get(1)->focused(), true);
@@ -377,8 +381,8 @@ private Q_SLOTS:
377 QCOMPARE(launcherModel->rowCount(), 2);
381 QCOMPARE(launcherModel->rowCount(), 2);
378
382
379 // stop the second one keeping it pinned so that it doesn't go away
383 // stop the second one keeping it pinned so that it doesn't go away
380− launcherModel->pin("no-icon");
384+ launcherModel->pin("rel-icon");
381− appManager->stopApplication("no-icon");
385+ appManager->stopApplication("rel-icon");
382
386
383 // find the first Quit item, should be there
387 // find the first Quit item, should be there
384 QuickListModel *model = qobject_cast<QuickListModel*>(launcherModel->get(0)->quickList());
388 QuickListModel *model = qobject_cast<QuickListModel*>(launcherModel->get(0)->quickList());
@@ -407,7 +411,7 @@ private Q_SLOTS:
407 // first app should be gone...
411 // first app should be gone...
408 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
412 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
409 // ... the second app (now at index 0) should still be there, pinned and stopped
413 // ... 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"));
411 QCOMPARE(launcherModel->get(0)->pinned(), true);
415 QCOMPARE(launcherModel->get(0)->pinned(), true);
412 QCOMPARE(launcherModel->get(0)->running(), false);
416 QCOMPARE(launcherModel->get(0)->running(), false);
413 }
417 }
@@ -602,17 +606,16 @@ private Q_SLOTS:
602
606
603 // pin both apps
607 // pin both apps
604 launcherModel->pin("abs-icon");
608 launcherModel->pin("abs-icon");
605− launcherModel->pin("no-icon");
609+ launcherModel->pin("rel-icon");
606 // close both apps
610 // close both apps
607 appManager->removeApplication(0);
611 appManager->removeApplication(0);
608 appManager->removeApplication(0);
612 appManager->removeApplication(0);
609
613
610 // "delete" the .desktop files
614 // "delete" the .desktop files
611− QString oldCurrent = QDir::currentPath();
612 if (deleted) {
615 if (deleted) {
613 // In testing mode, the launcher searches the current dir for the sample .desktop file
616 // 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
617+ // We can make that fail by moving the applications dir
615− QDir::setCurrent("..");
618+ QFile::rename("applications", "applications.old");
616 }
619 }
617
620
618 // Call refresh
621 // Call refresh
@@ -623,9 +626,6 @@ private Q_SLOTS:
623 QCOMPARE(reply.isValid(), true);
626 QCOMPARE(reply.isValid(), true);
624
627
625 QCOMPARE(launcherModel->rowCount(), deleted ? 0 : 2);
628 QCOMPARE(launcherModel->rowCount(), deleted ? 0 : 2);
626−
627− // Restoring current dir
628− QDir::setCurrent(oldCurrent);
629 }
629 }
630
630
631 void testSettings() {
631 void testSettings() {
@@ -637,7 +637,7 @@ private Q_SLOTS:
637
637
638 // pin both apps
638 // pin both apps
639 launcherModel->pin("abs-icon");
639 launcherModel->pin("abs-icon");
640− launcherModel->pin("no-icon");
640+ launcherModel->pin("rel-icon");
641 QCOMPARE(spy.count(), 0);
641 QCOMPARE(spy.count(), 0);
642
642
643 // Now settings should have 2 apps
643 // Now settings should have 2 apps
@@ -659,9 +659,9 @@ private Q_SLOTS:
659 QCOMPARE(launcherModel->rowCount(), 1);
659 QCOMPARE(launcherModel->rowCount(), 1);
660
660
661 // Add them back but in reverse order
661 // Add them back but in reverse order
662− settings->simulateDConfChanged(QStringList() << "no-icon" << "abs-icon");
662+ settings->simulateDConfChanged(QStringList() << "rel-icon" << "abs-icon");
663 QCOMPARE(launcherModel->rowCount(), 2);
663 QCOMPARE(launcherModel->rowCount(), 2);
664− QCOMPARE(launcherModel->get(0)->appId(), QString("no-icon"));
664+ QCOMPARE(launcherModel->get(0)->appId(), QString("rel-icon"));
665 QCOMPARE(launcherModel->get(1)->appId(), QString("abs-icon"));
665 QCOMPARE(launcherModel->get(1)->appId(), QString("abs-icon"));
666 QCOMPARE(spy.count(), 2);
666 QCOMPARE(spy.count(), 2);
667 }
667 }
@@ -671,7 +671,7 @@ private Q_SLOTS:
671 QCOMPARE(launcherModel->rowCount(), getASConfig().count());
671 QCOMPARE(launcherModel->rowCount(), getASConfig().count());
672
672
673 int oldCount = launcherModel->rowCount();
673 int oldCount = launcherModel->rowCount();
674− appManager->addApplication(new MockApp("rel-icon"));
674+ appManager->addApplication(new MockApp("click-icon"));
675 QCOMPARE(launcherModel->rowCount(), oldCount + 1);
675 QCOMPARE(launcherModel->rowCount(), oldCount + 1);
676 QCOMPARE(launcherModel->rowCount(), getASConfig().count());
676 QCOMPARE(launcherModel->rowCount(), getASConfig().count());
677 }
677 }
tests/plugins/Unity/Launcher/no-icon.desktopdeleted−2
@@ -1,2 +0,0 @@
1−[Desktop Entry]
2−Name=No Icon