Merge lp:~unity-team/unity8/ual-launcher into lp:unity8

Proposed by Michael Terry
Status: Merged
Approved by: Albert Astals Cid
Approved revision: 2616
Merged at revision: 2660
Proposed branch: lp:~unity-team/unity8/ual-launcher
Merge into: lp:unity8
Diff against target: 804 lines (+115/-294)
15 files modified
CMakeLists.txt (+1/-1)
debian/control (+1/-0)
plugins/Unity/Launcher/CMakeLists.txt (+8/-3)
plugins/Unity/Launcher/desktopfilehandler.cpp (+0/-155)
plugins/Unity/Launcher/desktopfilehandler.h (+0/-56)
plugins/Unity/Launcher/launchermodel.cpp (+53/-26)
plugins/Unity/Launcher/launchermodel.h (+17/-8)
tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt (+0/-1)
tests/plugins/Unity/Launcher/CMakeLists.txt (+12/-20)
tests/plugins/Unity/Launcher/applications/abs-icon.desktop (+1/-0)
tests/plugins/Unity/Launcher/applications/click-icon.desktop (+1/-0)
tests/plugins/Unity/Launcher/applications/no-name.desktop (+1/-0)
tests/plugins/Unity/Launcher/applications/rel-icon.desktop (+1/-0)
tests/plugins/Unity/Launcher/launchermodeltest.cpp (+19/-22)
tests/plugins/Unity/Launcher/no-icon.desktop (+0/-2)
To merge this branch: bzr merge lp:~unity-team/unity8/ual-launcher
Reviewer Review Type Date Requested Status
Albert Astals Cid (community) Abstain
Unity8 CI Bot continuous-integration Needs Fixing
Michael Zanetti (community) Approve
Review via email: mp+306539@code.launchpad.net

Commit message

Grab launcher icon information from ubuntu-app-launch, not directly from desktop files.

Description of the change

This is mostly expected. A few odd changes I've made to the testing code:

- I switched from no-icon to rel-icon as the 2nd standard app in the tests. This is because UAL refuses to handle apps without an icon. A harsh but not unreasonable policy. I did not add a test for the no-icon case, since it felt more like a test UAL should have (and probably does have) than us.

- Added Type=Application to the test desktop files. UAL won't read them without it.

- For the tests to find the sample desktop files, I've moved them to an applications subdir and set XDG_DATA_HOME, which is where UAL will look for them.

== Checklist ==

 * 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, I ran u8 with this change and saw the same launcher icons I saw without this branch.

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
 I'm on the team.

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

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2613
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2241/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/2952/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2980
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2838/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2838/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2838
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2838/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2838/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2838/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2838
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2838/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2838/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2838/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2838
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2838/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2241/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2614
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2244/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/2955/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2983
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2841/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2841/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2841
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2841/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2841/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2841/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2841
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2841/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2841/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2841/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2841
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2841/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2244/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote :

thanks for the small refactorings I asked for in IRC.

tested it on turbo (after merging with silo 78). Works fine.

Not entirely sure what's going on with CI...

review: Approve
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2615
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2245/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/2956/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2984
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2842/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2842/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2842
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2842/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2842/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2842/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2842
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2842/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2842/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2842/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2842
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2842/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2245/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Note: was top approved already

Text conflict in debian/control
1 conflicts encountered.

review: Needs Fixing
lp:~unity-team/unity8/ual-launcher updated
2616. By Michael Terry

Merge trunk

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2616
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2268/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/2989
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/1650
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/1650
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=qmluitests.sh/1650
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3017
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2874/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2874/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2874/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2874/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2874/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2874/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2874/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2874/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2874
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2874/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2268/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

re-top-approving after merge since it was already top approved

review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-09-07 08:36:59 +0000
3+++ CMakeLists.txt 2016-09-28 15:23:28 +0000
4@@ -63,7 +63,7 @@
5 pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
6 pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
7 pkg_check_modules(GD3 REQUIRED gnome-desktop-3.0)
8-
9+pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2)
10 pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
11
12 ### Check UbuntuGestures private headers. No pkg-config (.pc) file is provided for them
13
14=== modified file 'debian/control'
15--- debian/control 2016-09-07 08:36:59 +0000
16+++ debian/control 2016-09-28 15:23:28 +0000
17@@ -32,6 +32,7 @@
18 libqt5svg5-dev,
19 libqt5xmlpatterns5-dev,
20 libsystemsettings-dev,
21+ libubuntu-app-launch2-dev,
22 libubuntu-download-manager-common-dev,
23 libubuntugestures5-dev (>= 1.3.2030),
24 libubuntugestures5-private-dev (>= 1.3.2030),
25
26=== modified file 'plugins/Unity/Launcher/CMakeLists.txt'
27--- plugins/Unity/Launcher/CMakeLists.txt 2016-05-13 11:14:15 +0000
28+++ plugins/Unity/Launcher/CMakeLists.txt 2016-09-28 15:23:28 +0000
29@@ -6,10 +6,15 @@
30 include_directories(
31 ${CMAKE_CURRENT_SOURCE_DIR}
32 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
33+ ${libunity8-private_SOURCE_DIR}
34+)
35+
36+include_directories(
37+ SYSTEM
38 ${GSETTINGS_QT_INCLUDE_DIRS}
39 ${GLIB_INCLUDE_DIRS}
40- ${libunity8-private_SOURCE_DIR}
41-)
42+ ${UAL_INCLUDE_DIRS}
43+ )
44
45 set(QMLLAUNCHERPLUGIN_SRC
46 plugin.cpp
47@@ -19,7 +24,6 @@
48 quicklistentry.cpp
49 dbusinterface.cpp
50 gsettings.cpp
51- desktopfilehandler.cpp
52 asadapter.cpp
53 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
54 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
55@@ -38,6 +42,7 @@
56 unity8-private
57 ${GSETTINGS_QT_LDFLAGS}
58 ${GLIB_LIBRARIES}
59+ ${UAL_LIBRARIES}
60 )
61
62 qt5_use_modules(UnityLauncher-qml DBus Qml Gui)
63
64=== removed file 'plugins/Unity/Launcher/desktopfilehandler.cpp'
65--- plugins/Unity/Launcher/desktopfilehandler.cpp 2016-02-19 08:44:42 +0000
66+++ plugins/Unity/Launcher/desktopfilehandler.cpp 1970-01-01 00:00:00 +0000
67@@ -1,155 +0,0 @@
68-/*
69- * Copyright 2014 Canonical Ltd.
70- *
71- * This program is free software; you can redistribute it and/or modify
72- * it under the terms of the GNU Lesser General Public License as published by
73- * the Free Software Foundation; version 3.
74- *
75- * This program is distributed in the hope that it will be useful,
76- * but WITHOUT ANY WARRANTY; without even the implied warranty of
77- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
78- * GNU Lesser General Public License for more details.
79- *
80- * You should have received a copy of the GNU Lesser General Public License
81- * along with this program. If not, see <http://www.gnu.org/licenses/>.
82- *
83- * Authors:
84- * Michael Zanetti <michael.zanetti@canonical.com>
85- */
86-
87-#include "desktopfilehandler.h"
88-
89-#include <QStringList>
90-#include <QStandardPaths>
91-#include <QDir>
92-#include <QSettings>
93-#include <QLocale>
94-
95-#include <libintl.h>
96-
97-DesktopFileHandler::DesktopFileHandler(const QString &appId, QObject *parent):
98- QObject(parent),
99- m_appId(appId)
100-{
101- load();
102-}
103-
104-QString DesktopFileHandler::appId() const
105-{
106- return m_appId;
107-}
108-
109-void DesktopFileHandler::setAppId(const QString &appId)
110-{
111- if (m_appId != appId) {
112- m_appId = appId;
113- load();
114- }
115-}
116-
117-QString DesktopFileHandler::filename() const
118-{
119- return m_filename;
120-}
121-
122-bool DesktopFileHandler::isValid() const
123-{
124- return !m_filename.isEmpty();
125-}
126-
127-void DesktopFileHandler::load()
128-{
129- m_filename.clear();
130-
131- if (m_appId.isEmpty()) {
132- return;
133- }
134-
135- int dashPos = -1;
136- QString helper = m_appId;
137-
138- QStringList searchDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
139-#ifdef LAUNCHER_TESTING
140- searchDirs << QStringLiteral(".");
141-#endif
142-
143- QString path;
144- do {
145- if (dashPos != -1) {
146- helper.replace(dashPos, 1, '/');
147- }
148-
149- if (helper.contains('/')) {
150- path += helper.split('/').at(0) + '/';
151- helper.remove(QRegExp("^" + path));
152- }
153-
154- Q_FOREACH(const QString &searchDirName, searchDirs) {
155- QDir searchDir(searchDirName + "/" + path);
156- const QString desktop = QStringLiteral("*.desktop");
157- Q_FOREACH(const QString &desktopFile, searchDir.entryList(QStringList() << desktop)) {
158- if (desktopFile.startsWith(helper)) {
159- QFileInfo fileInfo(searchDir, desktopFile);
160- m_filename = fileInfo.absoluteFilePath();
161- return;
162- }
163- }
164- }
165-
166- dashPos = helper.indexOf('-');
167- } while (dashPos != -1);
168-}
169-
170-QString DesktopFileHandler::displayName() const
171-{
172- if (!isValid()) {
173- return QString();
174- }
175-
176- QSettings settings(m_filename, QSettings::IniFormat);
177- settings.setIniCodec("UTF-8");
178- settings.beginGroup(QStringLiteral("Desktop Entry"));
179-
180- // First try to find Name[xx_YY] and Name[xx] in .desktop file
181- const QString locale = QLocale().name();
182- const QStringList splitLocale = locale.split(QLatin1Char('_'));
183- const QString shortLocale = splitLocale.first();
184-
185- if (locale != shortLocale && settings.contains(QStringLiteral("Name[%1]").arg(locale))) {
186- return settings.value(QStringLiteral("Name[%1]").arg(locale)).toString();
187- }
188-
189- if (settings.contains(QStringLiteral("Name[%1]").arg(shortLocale))) {
190- return settings.value(QStringLiteral("Name[%1]").arg(shortLocale)).toString();
191- }
192-
193- // No translation found in desktop file. Get the untranslated one and have a go with gettext.
194- QString displayName = settings.value(QStringLiteral("Name")).toString();
195-
196- if (settings.contains(QStringLiteral("X-Ubuntu-Gettext-Domain"))) {
197- const QString domain = settings.value(QStringLiteral("X-Ubuntu-Gettext-Domain")).toString();
198- return dgettext(domain.toUtf8().constData(), displayName.toUtf8().constData());
199- }
200-
201- return displayName;
202-}
203-
204-QString DesktopFileHandler::icon() const
205-{
206- if (!isValid()) {
207- return QString();
208- }
209-
210- QSettings settings(m_filename, QSettings::IniFormat);
211- settings.setIniCodec("UTF-8");
212- settings.beginGroup(QStringLiteral("Desktop Entry"));
213- QString iconString = settings.value(QStringLiteral("Icon")).toString();
214- QString pathString = settings.value(QStringLiteral("Path")).toString();
215-
216- if (QFileInfo::exists(iconString)) {
217- return QFileInfo(iconString).absoluteFilePath();
218- } else if (QFileInfo::exists(pathString + '/' + iconString)) {
219- return pathString + '/' + iconString;
220- }
221- return "image://theme/" + iconString;
222-}
223
224=== removed file 'plugins/Unity/Launcher/desktopfilehandler.h'
225--- plugins/Unity/Launcher/desktopfilehandler.h 2014-09-02 17:45:50 +0000
226+++ plugins/Unity/Launcher/desktopfilehandler.h 1970-01-01 00:00:00 +0000
227@@ -1,56 +0,0 @@
228-/*
229- * Copyright 2014 Canonical Ltd.
230- *
231- * This program is free software; you can redistribute it and/or modify
232- * it under the terms of the GNU Lesser General Public License as published by
233- * the Free Software Foundation; version 3.
234- *
235- * This program is distributed in the hope that it will be useful,
236- * but WITHOUT ANY WARRANTY; without even the implied warranty of
237- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
238- * GNU Lesser General Public License for more details.
239- *
240- * You should have received a copy of the GNU Lesser General Public License
241- * along with this program. If not, see <http://www.gnu.org/licenses/>.
242- *
243- * Authors:
244- * Michael Zanetti <michael.zanetti@canonical.com>
245- */
246-
247-#ifndef DESKTOPFILEHANDLER_H
248-#define DESKTOPFILEHANDLER_H
249-
250-#include <QObject>
251-
252-/**
253- * When an object of this class is created or whenever setAppId(appId) is called,
254- * this will search for a .desktop file matching the give appId. If a file is
255- * found, isValid() will return true and the other methods return the contents
256- * of the .desktop file.
257- *
258- * Note that this class will consider the user's locale and do a best effort
259- * to return localized values.
260- */
261-
262-class DesktopFileHandler: public QObject
263-{
264- Q_OBJECT
265-public:
266- DesktopFileHandler(const QString &appId = QString(), QObject *parent = nullptr);
267-
268- QString appId() const;
269- void setAppId(const QString &appId);
270-
271- bool isValid() const;
272- QString filename() const;
273- QString displayName() const;
274- QString icon() const;
275-
276-private:
277- void load();
278-
279- QString m_appId;
280- QString m_filename;
281-};
282-
283-#endif
284
285=== modified file 'plugins/Unity/Launcher/launchermodel.cpp'
286--- plugins/Unity/Launcher/launchermodel.cpp 2016-07-07 16:18:59 +0000
287+++ plugins/Unity/Launcher/launchermodel.cpp 2016-09-28 15:23:28 +0000
288@@ -1,5 +1,5 @@
289 /*
290- * Copyright 2013-2014 Canonical Ltd.
291+ * Copyright 2013-2016 Canonical Ltd.
292 *
293 * This program is free software; you can redistribute it and/or modify
294 * it under the terms of the GNU Lesser General Public License as published by
295@@ -12,24 +12,25 @@
296 *
297 * You should have received a copy of the GNU Lesser General Public License
298 * along with this program. If not, see <http://www.gnu.org/licenses/>.
299- *
300- * Authors:
301- * Michael Zanetti <michael.zanetti@canonical.com>
302 */
303
304 #include "launchermodel.h"
305 #include "launcheritem.h"
306 #include "gsettings.h"
307-#include "desktopfilehandler.h"
308 #include "dbusinterface.h"
309 #include "asadapter.h"
310
311+#include <ubuntu-app-launch/appid.h>
312+#include <ubuntu-app-launch/application.h>
313+#include <ubuntu-app-launch/registry.h>
314 #include <unity/shell/application/ApplicationInfoInterface.h>
315 #include <unity/shell/application/MirSurfaceListInterface.h>
316
317 #include <QDesktopServices>
318 #include <QDebug>
319
320+namespace ual = ubuntu::app_launch;
321+
322 using namespace unity::shell::application;
323
324 LauncherModel::LauncherModel(QObject *parent):
325@@ -37,7 +38,8 @@
326 m_settings(new GSettings(this)),
327 m_dbusIface(new DBusInterface(this)),
328 m_asAdapter(new ASAdapter()),
329- m_appManager(nullptr)
330+ m_appManager(nullptr),
331+ m_ualRegistry(std::make_shared<ual::Registry>())
332 {
333 connect(m_dbusIface, &DBusInterface::countChanged, this, &LauncherModel::countChanged);
334 connect(m_dbusIface, &DBusInterface::countVisibleChanged, this, &LauncherModel::countVisibleChanged);
335@@ -157,16 +159,16 @@
336 index = m_list.count();
337 }
338
339- DesktopFileHandler desktopFile(appId);
340- if (!desktopFile.isValid()) {
341- qWarning() << "Can't pin this application, there is no .desktop file available.";
342+ auto appInfo = getApplicationInfo(appId);
343+ if (!appInfo.valid) {
344+ qWarning() << "Can't pin application, appId not found:" << appId;
345 return;
346 }
347
348 beginInsertRows(QModelIndex(), index, index);
349 LauncherItem *item = new LauncherItem(appId,
350- desktopFile.displayName(),
351- desktopFile.icon(),
352+ appInfo.name,
353+ appInfo.icon,
354 this);
355 item->setPinned(true);
356 m_list.insert(index, item);
357@@ -333,6 +335,32 @@
358 return -1;
359 }
360
361+LauncherModel::AppInfo LauncherModel::getApplicationInfo(const QString &appId)
362+{
363+ AppInfo info;
364+
365+ ual::AppID ualAppId = ual::AppID::find(m_ualRegistry, appId.toStdString());
366+ if (ualAppId.empty()) {
367+ return info;
368+ }
369+
370+ std::shared_ptr<ual::Application> ualApp;
371+ try
372+ {
373+ ualApp = ual::Application::create(ualAppId, m_ualRegistry);
374+ }
375+ catch (std::runtime_error &e)
376+ {
377+ qWarning() << "Couldn't find application info for" << appId << "-" << e.what();
378+ return info;
379+ }
380+
381+ info.valid = true;
382+ info.name = QString::fromStdString(ualApp->info()->name());
383+ info.icon = QString::fromStdString(ualApp->info()->iconPath());
384+ return info;
385+}
386+
387 void LauncherModel::progressChanged(const QString &appId, int progress)
388 {
389 const int idx = findApplication(appId);
390@@ -380,11 +408,11 @@
391 }
392 } else {
393 // Need to create a new LauncherItem and show the highlight
394- DesktopFileHandler desktopFile(appId);
395- if (countVisible && desktopFile.isValid()) {
396+ auto appInfo = getApplicationInfo(appId);
397+ if (countVisible && appInfo.valid) {
398 LauncherItem *item = new LauncherItem(appId,
399- desktopFile.displayName(),
400- desktopFile.icon(),
401+ appInfo.name,
402+ appInfo.icon,
403 this);
404 item->setCountVisible(true);
405 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
406@@ -400,28 +428,28 @@
407 // First walk through all the existing items and see if we need to remove something
408 QList<LauncherItem*> toBeRemoved;
409 Q_FOREACH (LauncherItem* item, m_list) {
410- DesktopFileHandler desktopFile(item->appId());
411- if (!desktopFile.isValid()) {
412- // Desktop file not available for this app => drop it!
413+ auto appInfo = getApplicationInfo(item->appId());
414+ if (!appInfo.valid) {
415+ // Application no longer available => drop it!
416 toBeRemoved << item;
417 } else if (!m_settings->storedApplications().contains(item->appId())) {
418 // Item not in settings any more => drop it!
419 toBeRemoved << item;
420 } else {
421 int idx = m_list.indexOf(item);
422- item->setName(desktopFile.displayName());
423+ item->setName(appInfo.name);
424 item->setPinned(item->pinned()); // update pinned text if needed
425 item->setRunning(item->running());
426 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleRunning});
427
428 const QString oldIcon = item->icon();
429- if (oldIcon == desktopFile.icon()) { // same icon file, perhaps different contents, simulate changing the icon name to force reload
430+ if (oldIcon == appInfo.icon) { // same icon file, perhaps different contents, simulate changing the icon name to force reload
431 item->setIcon(QString());
432 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
433 }
434
435 // now set the icon for real
436- item->setIcon(desktopFile.icon());
437+ item->setIcon(appInfo.icon);
438 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
439 }
440 }
441@@ -452,15 +480,14 @@
442 if (itemIndex == -1) {
443 // Need to add it. Just add it into the addedIndex to keep same ordering as the list
444 // in the settings.
445- DesktopFileHandler desktopFile(entry);
446- if (!desktopFile.isValid()) {
447- qWarning() << "Couldn't find a .desktop file for" << entry << ". Skipping...";
448+ auto appInfo = getApplicationInfo(entry);
449+ if (!appInfo.valid) {
450 continue;
451 }
452
453 LauncherItem *item = new LauncherItem(entry,
454- desktopFile.displayName(),
455- desktopFile.icon(),
456+ appInfo.name,
457+ appInfo.icon,
458 this);
459 item->setPinned(true);
460 beginInsertRows(QModelIndex(), addedIndex, addedIndex);
461
462=== modified file 'plugins/Unity/Launcher/launchermodel.h'
463--- plugins/Unity/Launcher/launchermodel.h 2016-05-13 11:14:15 +0000
464+++ plugins/Unity/Launcher/launchermodel.h 2016-09-28 15:23:28 +0000
465@@ -1,5 +1,5 @@
466 /*
467- * Copyright 2013-2014 Canonical Ltd.
468+ * Copyright 2013-2016 Canonical Ltd.
469 *
470 * This program is free software; you can redistribute it and/or modify
471 * it under the terms of the GNU Lesser General Public License as published by
472@@ -12,14 +12,11 @@
473 *
474 * You should have received a copy of the GNU Lesser General Public License
475 * along with this program. If not, see <http://www.gnu.org/licenses/>.
476- *
477- * Authors:
478- * Michael Zanetti <michael.zanetti@canonical.com>
479 */
480
481-#ifndef LAUNCHERMODEL_H
482-#define LAUNCHERMODEL_H
483+#pragma once
484
485+#include <memory>
486 #include <unity/shell/launcher/LauncherModelInterface.h>
487 #include <unity/shell/application/ApplicationManagerInterface.h>
488
489@@ -30,6 +27,12 @@
490 class DBusInterface;
491 class ASAdapter;
492
493+namespace ubuntu {
494+ namespace app_launch {
495+ class Registry;
496+ }
497+}
498+
499 using namespace unity::shell::launcher;
500 using namespace unity::shell::application;
501
502@@ -70,6 +73,13 @@
503
504 void unpin(const QString &appId);
505
506+ struct AppInfo {
507+ bool valid = false;
508+ QString name;
509+ QString icon;
510+ };
511+ AppInfo getApplicationInfo(const QString &appId);
512+
513 private Q_SLOTS:
514 void countChanged(const QString &appId, int count);
515 void countVisibleChanged(const QString &appId, bool count);
516@@ -88,8 +98,7 @@
517 ASAdapter *m_asAdapter;
518
519 ApplicationManagerInterface *m_appManager;
520+ std::shared_ptr<ubuntu::app_launch::Registry> m_ualRegistry;
521
522 friend class LauncherModelTest;
523 };
524-
525-#endif // LAUNCHERMODEL_H
526
527=== modified file 'tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt'
528--- tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-10-26 14:05:14 +0000
529+++ tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2016-09-28 15:23:28 +0000
530@@ -10,7 +10,6 @@
531
532 add_definitions(-DSM_BUSNAME=sessionBus)
533 add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
534-add_definitions(-DLAUNCHER_TESTING)
535
536 ### LauncherModelASTest
537 add_executable(launchermodelastestExec
538
539=== modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt'
540--- tests/plugins/Unity/Launcher/CMakeLists.txt 2016-05-10 15:51:00 +0000
541+++ tests/plugins/Unity/Launcher/CMakeLists.txt 2016-09-28 15:23:28 +0000
542@@ -6,14 +6,18 @@
543 ${CMAKE_CURRENT_BINARY_DIR}
544 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
545 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher
546+ ${libunity8-private_SOURCE_DIR}
547+ )
548+
549+include_directories(
550+ SYSTEM
551 ${GSETTINGS_QT_INCLUDE_DIRS}
552 ${GLIB_INCLUDE_DIRS}
553- ${libunity8-private_SOURCE_DIR}
554+ ${UAL_INCLUDE_DIRS}
555 )
556
557 add_definitions(-DSM_BUSNAME=sessionBus)
558 add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
559-add_definitions(-DLAUNCHER_TESTING)
560
561 ### LauncherModelTest
562 add_executable(launchermodeltestExec
563@@ -25,7 +29,6 @@
564 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/launcheritem.cpp
565 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistmodel.cpp
566 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/dbusinterface.cpp
567- ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/desktopfilehandler.cpp
568 ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistentry.cpp
569 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
570 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
571@@ -37,11 +40,13 @@
572 unity8-private
573 ${GSETTINGS_QT_LDFLAGS}
574 ${GLIB_LIBRARIES}
575+ ${UAL_LIBRARIES}
576 )
577 add_dependencies(launchermodeltestExec mock-server)
578 qt5_use_modules(launchermodeltestExec Test Core DBus Xml Gui)
579
580 add_unity8_unittest(LauncherModel dbus-test-runner
581+ ENVIRONMENT "XDG_DATA_HOME=${CMAKE_CURRENT_BINARY_DIR}"
582 ARG_PREFIX "--parameter"
583 ARGS
584 --task $<TARGET_FILE:mock-server>
585@@ -50,20 +55,7 @@
586 --wait-for org.freedesktop.Accounts
587 )
588
589-# copy .desktop files into build directory for shadow builds
590-file(GLOB DESKTOP_FILES *.desktop)
591-
592-foreach(DESKTOP_FILE ${DESKTOP_FILES})
593- file(COPY "${DESKTOP_FILE}"
594- DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
595- )
596-endforeach()
597-
598-# copy .svg files into build directory for shadow builds
599-file(GLOB DESKTOP_FILES *.svg)
600-
601-foreach(DESKTOP_FILE ${DESKTOP_FILES})
602- file(COPY "${DESKTOP_FILE}"
603- DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
604- )
605-endforeach()
606+# copy sample application files into build directory for shadow builds
607+file(COPY applications
608+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
609+ )
610
611=== added directory 'tests/plugins/Unity/Launcher/applications'
612=== renamed file 'tests/plugins/Unity/Launcher/abs-icon.desktop' => 'tests/plugins/Unity/Launcher/applications/abs-icon.desktop'
613--- tests/plugins/Unity/Launcher/abs-icon.desktop 2013-08-20 17:57:08 +0000
614+++ tests/plugins/Unity/Launcher/applications/abs-icon.desktop 2016-09-28 15:23:28 +0000
615@@ -1,3 +1,4 @@
616 [Desktop Entry]
617+Type=Application
618 Name=Absolute Icon
619 Icon=/path/to/icon.png
620
621=== renamed file 'tests/plugins/Unity/Launcher/click-icon.desktop' => 'tests/plugins/Unity/Launcher/applications/click-icon.desktop'
622--- tests/plugins/Unity/Launcher/click-icon.desktop 2013-09-09 16:30:56 +0000
623+++ tests/plugins/Unity/Launcher/applications/click-icon.desktop 2016-09-28 15:23:28 +0000
624@@ -1,4 +1,5 @@
625 [Desktop Entry]
626+Type=Application
627 Name=Click Package Icon
628 Icon=click-icon.svg
629 Path=/path/to/some/click/app
630
631=== renamed file 'tests/plugins/Unity/Launcher/click-icon.svg' => 'tests/plugins/Unity/Launcher/applications/click-icon.svg'
632=== renamed file 'tests/plugins/Unity/Launcher/no-name.desktop' => 'tests/plugins/Unity/Launcher/applications/no-name.desktop'
633--- tests/plugins/Unity/Launcher/no-name.desktop 2013-08-20 17:57:08 +0000
634+++ tests/plugins/Unity/Launcher/applications/no-name.desktop 2016-09-28 15:23:28 +0000
635@@ -1,2 +1,3 @@
636 [Desktop Entry]
637+Type=Application
638 Icon=no-name
639
640=== renamed file 'tests/plugins/Unity/Launcher/rel-icon.desktop' => 'tests/plugins/Unity/Launcher/applications/rel-icon.desktop'
641--- tests/plugins/Unity/Launcher/rel-icon.desktop 2013-09-09 16:30:56 +0000
642+++ tests/plugins/Unity/Launcher/applications/rel-icon.desktop 2016-09-28 15:23:28 +0000
643@@ -1,3 +1,4 @@
644 [Desktop Entry]
645+Type=Application
646 Name=Relative Icon
647 Icon=rel-icon.svg
648
649=== renamed file 'tests/plugins/Unity/Launcher/rel-icon.svg' => 'tests/plugins/Unity/Launcher/applications/rel-icon.svg'
650=== modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp'
651--- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2016-07-25 14:57:11 +0000
652+++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2016-09-28 15:23:28 +0000
653@@ -1,5 +1,5 @@
654 /*
655- * Copyright 2013-2015 Canonical Ltd.
656+ * Copyright 2013-2016 Canonical Ltd.
657 *
658 * This program is free software; you can redistribute it and/or modify
659 * it under the terms of the GNU Lesser General Public License as published by
660@@ -12,9 +12,6 @@
661 *
662 * You should have received a copy of the GNU Lesser General Public License
663 * along with this program. If not, see <http://www.gnu.org/licenses/>.
664- *
665- * Authors:
666- * Michael Zanetti <michael.zanetti@canonical.com>
667 */
668
669 // unity-api
670@@ -177,7 +174,7 @@
671 appManager->addApplication(new MockApp("abs-icon"));
672 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
673
674- appManager->addApplication(new MockApp("no-icon"));
675+ appManager->addApplication(new MockApp("rel-icon"));
676 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
677
678 launcherModel->m_settings->setStoredApplications(QStringList());
679@@ -199,6 +196,10 @@
680 QString::fromUtf8(g_get_user_name()));
681 QVERIFY(removeReply.isValid());
682 QCOMPARE(removeReply.value(), true);
683+
684+ // Some tests move the directory, so lets move it back if so.
685+ // But this will usually fail.
686+ QFile::rename("applications.old", "applications");
687 }
688
689 void testMove() {
690@@ -331,7 +332,7 @@
691
692 void testApplicationRunning() {
693 launcherModel->pin("abs-icon");
694- launcherModel->pin("no-icon");
695+ launcherModel->pin("rel-icon");
696
697 QCOMPARE(launcherModel->get(0)->running(), true);
698 QCOMPARE(launcherModel->get(1)->running(), true);
699@@ -340,7 +341,7 @@
700 QCOMPARE(launcherModel->get(0)->running(), false);
701 QCOMPARE(launcherModel->get(1)->running(), true);
702
703- appManager->stopApplication("no-icon");
704+ appManager->stopApplication("rel-icon");
705 QCOMPARE(launcherModel->get(0)->running(), false);
706 QCOMPARE(launcherModel->get(1)->running(), false);
707 }
708@@ -355,7 +356,7 @@
709 QCOMPARE(launcherModel->get(0)->focused(), true);
710 QCOMPARE(launcherModel->get(1)->focused(), false);
711
712- appManager->focusApplication("no-icon");
713+ appManager->focusApplication("rel-icon");
714 QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
715 QCOMPARE(launcherModel->get(0)->focused(), false);
716 QCOMPARE(launcherModel->get(1)->focused(), true);
717@@ -377,8 +378,8 @@
718 QCOMPARE(launcherModel->rowCount(), 2);
719
720 // stop the second one keeping it pinned so that it doesn't go away
721- launcherModel->pin("no-icon");
722- appManager->stopApplication("no-icon");
723+ launcherModel->pin("rel-icon");
724+ appManager->stopApplication("rel-icon");
725
726 // find the first Quit item, should be there
727 QuickListModel *model = qobject_cast<QuickListModel*>(launcherModel->get(0)->quickList());
728@@ -407,7 +408,7 @@
729 // first app should be gone...
730 QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
731 // ... the second app (now at index 0) should still be there, pinned and stopped
732- QCOMPARE(launcherModel->get(0)->appId(), QStringLiteral("no-icon"));
733+ QCOMPARE(launcherModel->get(0)->appId(), QStringLiteral("rel-icon"));
734 QCOMPARE(launcherModel->get(0)->pinned(), true);
735 QCOMPARE(launcherModel->get(0)->running(), false);
736 }
737@@ -602,17 +603,16 @@
738
739 // pin both apps
740 launcherModel->pin("abs-icon");
741- launcherModel->pin("no-icon");
742+ launcherModel->pin("rel-icon");
743 // close both apps
744 appManager->removeApplication(0);
745 appManager->removeApplication(0);
746
747 // "delete" the .desktop files
748- QString oldCurrent = QDir::currentPath();
749 if (deleted) {
750 // In testing mode, the launcher searches the current dir for the sample .desktop file
751- // We can make that fail by changing the current dir
752- QDir::setCurrent("..");
753+ // We can make that fail by moving the applications dir
754+ QFile::rename("applications", "applications.old");
755 }
756
757 // Call refresh
758@@ -623,9 +623,6 @@
759 QCOMPARE(reply.isValid(), true);
760
761 QCOMPARE(launcherModel->rowCount(), deleted ? 0 : 2);
762-
763- // Restoring current dir
764- QDir::setCurrent(oldCurrent);
765 }
766
767 void testSettings() {
768@@ -637,7 +634,7 @@
769
770 // pin both apps
771 launcherModel->pin("abs-icon");
772- launcherModel->pin("no-icon");
773+ launcherModel->pin("rel-icon");
774 QCOMPARE(spy.count(), 0);
775
776 // Now settings should have 2 apps
777@@ -659,9 +656,9 @@
778 QCOMPARE(launcherModel->rowCount(), 1);
779
780 // Add them back but in reverse order
781- settings->simulateDConfChanged(QStringList() << "no-icon" << "abs-icon");
782+ settings->simulateDConfChanged(QStringList() << "rel-icon" << "abs-icon");
783 QCOMPARE(launcherModel->rowCount(), 2);
784- QCOMPARE(launcherModel->get(0)->appId(), QString("no-icon"));
785+ QCOMPARE(launcherModel->get(0)->appId(), QString("rel-icon"));
786 QCOMPARE(launcherModel->get(1)->appId(), QString("abs-icon"));
787 QCOMPARE(spy.count(), 2);
788 }
789@@ -671,7 +668,7 @@
790 QCOMPARE(launcherModel->rowCount(), getASConfig().count());
791
792 int oldCount = launcherModel->rowCount();
793- appManager->addApplication(new MockApp("rel-icon"));
794+ appManager->addApplication(new MockApp("click-icon"));
795 QCOMPARE(launcherModel->rowCount(), oldCount + 1);
796 QCOMPARE(launcherModel->rowCount(), getASConfig().count());
797 }
798
799=== removed file 'tests/plugins/Unity/Launcher/no-icon.desktop'
800--- tests/plugins/Unity/Launcher/no-icon.desktop 2013-08-20 17:57:08 +0000
801+++ tests/plugins/Unity/Launcher/no-icon.desktop 1970-01-01 00:00:00 +0000
802@@ -1,2 +0,0 @@
803-[Desktop Entry]
804-Name=No Icon

Subscribers

People subscribed via source and target branches