Merge lp:~unity-team/unity8/ual-launcher into lp:unity8
- ual-launcher
- Merge into trunk
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 |
Related bugs: |
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
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2614
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
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...
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2615
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2615
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Albert Astals Cid (aacid) wrote : | # |
Note: was top approved already
Text conflict in debian/control
1 conflicts encountered.
- 2616. By Michael Terry
-
Merge trunk
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2616
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Albert Astals Cid (aacid) wrote : | # |
re-top-approving after merge since it was already top approved
Preview Diff
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 |
FAILED: Continuous integration, rev:2613 /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2241/ /unity8- jenkins. ubuntu. com/job/ build/2952/ console /unity8- jenkins. ubuntu. com/job/ build-0- fetch/2980 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 2838/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 2838/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= yakkety/ 2838 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= yakkety/ 2838/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 2838/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 2838/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= yakkety/ 2838 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= yakkety/ 2838/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 2838/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 2838/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= yakkety/ 2838 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= yakkety/ 2838/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2241/ rebuild
https:/