on xenial help sign in
Integrate Launcher with AppManager.

Approved by PS Jenkins bot, Gerry Boland.

commitb64ae7df92ea57503cbb54839d33124a7879a1e0 authorMichael Zanetti <michael.zanetti@canonical.com> dateThu 5 Sep 2013, 08:57 (13 years ago) parente52014cbf1243b
8 files changed+109−19
Shell.qml+5 plugins/Unity/Launcher/backend/launcherbackend.cpp+36−4 plugins/Unity/Launcher/launchermodel.cpp+37 plugins/Unity/Launcher/launchermodel.h+1 tests/mocks/Unity/Launcher/MockLauncherModel.cpp+5 tests/mocks/Unity/Launcher/MockLauncherModel.h+1 tests/plugins/Unity/Launcher/CMakeLists.txt+10 tests/plugins/Unity/Launcher/launcherbackendtest.cpp+14−15
Shell.qml+5
@@ -95,6 +95,11 @@ FocusScope {
9595 greeter.hide();
9696 shell.activateApplication(desktopFile);
9797 }
98+
99+ onMainStageFocusedApplicationChanged: {
100+ var app = applicationManager.mainStageFocusedApplication
101+ LauncherModel.applicationFocused(app.desktopFile);
102+ }
98103 }
99104
100105 function activateApplication(desktopFile, argument) {
plugins/Unity/Launcher/backend/launcherbackend.cpp+36−4
@@ -25,6 +25,7 @@
2525#include <QDBusArgument>
2626#include <QFileInfo>
2727#include <QGSettings>
28+#include <QDebug>
2829
2930class LauncherBackendItem
3031{
@@ -73,6 +74,19 @@ void LauncherBackend::setStoredApplications(const QStringList &appIds)
7374 }
7475 }
7576 m_storedApps = appIds;
77+ Q_FOREACH(const QString &appId, appIds) {
78+ if (!m_itemCache.contains(appId)) {
79+ QString df = findDesktopFile(appId);
80+ if (!df.isEmpty()) {
81+ LauncherBackendItem *item = parseDesktopFile(df);
82+ m_itemCache.insert(appId, item);
83+ } else {
84+ // Cannot find any data for that app... ignoring it.
85+ qWarning() << "cannot find desktop file for" << appId << ". discarding app.";
86+ m_storedApps.removeAll(appId);
87+ }
88+ }
89+ }
7690 syncToAccounts();
7791}
7892
@@ -199,7 +213,7 @@ void LauncherBackend::syncFromAccounts()
199213
200214 m_storedApps.clear();
201215
202− if (m_accounts && m_user.isEmpty()) {
216+ if (m_accounts && !m_user.isEmpty()) {
203217 QVariant variant = m_accounts->getUserProperty(m_user, "launcher-items");
204218 apps = qdbus_cast<QList<QVariantMap>>(variant.value<QDBusArgument>());
205219 defaults = isDefaultsItem(apps);
@@ -248,14 +262,32 @@ QString LauncherBackend::findDesktopFile(const QString &appId) const
248262 int dashPos = -1;
249263 QString helper = appId;
250264
265+ QStringList searchDirs;
266+ searchDirs << "/usr/share/applications";
267+
268+// FIXME: Right now the appId can be (or rather is) a full path
269+// to a .desktop file. This will change in the future.
270+// Once the ApplicationManager has been switched over to use appIds,
271+// remove this chop() and enable the ifdef to only search the current
272+// working dir for testing. Also, this is the place to add the search
273+// paths for click apps in the next step.
274+ if (helper.endsWith(".desktop")) {
275+ helper.chop(8);
276+ }
277+//#ifdef LAUNCHER_TESTING
278+ searchDirs << "";
279+//#endif
280+
251281 do {
252282 if (dashPos != -1) {
253283 helper = helper.replace(dashPos, 1, '/');
254284 }
255285
256− QFileInfo fileInfo(QDir("/usr/share/applications"), helper);
257− if (fileInfo.exists()) {
258− return fileInfo.absoluteFilePath();
286+ Q_FOREACH(const QString &searchDir, searchDirs) {
287+ QFileInfo fileInfo(QDir(searchDir), helper + ".desktop");
288+ if (fileInfo.exists()) {
289+ return fileInfo.absoluteFilePath();
290+ }
259291 }
260292
261293 dashPos = helper.indexOf("-");
plugins/Unity/Launcher/launchermodel.cpp+37
@@ -191,6 +191,43 @@ void LauncherModel::setUser(const QString &username)
191191 m_backend->setUser(username);
192192}
193193
194+void LauncherModel::applicationFocused(const QString &appId)
195+{
196+ int index = findApplication(appId);
197+
198+ if (index >= 0) {
199+ // TODO: Mark application as focued
200+ } else {
201+ // Add app to recent apps
202+ QString desktopFile = m_backend->desktopFile(appId);
203+ QString appName = m_backend->displayName(appId);
204+ QString icon = m_backend->icon(appId);
205+
206+ LauncherItem *item = new LauncherItem(appId, desktopFile, appName, icon);
207+ item->setRecent(true);
208+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
209+ m_list.append(item);
210+ endInsertRows();
211+
212+ // Clean up old recent apps
213+ QList<int> recentAppIndices;
214+ for (int i = 0; i < m_list.count(); ++i) {
215+ if (m_list.at(i)->recent()) {
216+ recentAppIndices << i;
217+ }
218+ }
219+ int run = 0;
220+ while (recentAppIndices.count() > 5) {
221+ beginRemoveRows(QModelIndex(), recentAppIndices.first() - run, recentAppIndices.first() - run);
222+ m_list.takeAt(recentAppIndices.first() - run)->deleteLater();
223+ endRemoveRows();
224+ recentAppIndices.takeFirst();
225+ ++run;
226+ }
227+ storeAppList();
228+ }
229+}
230+
194231void LauncherModel::storeAppList()
195232{
196233 QStringList appIds;
plugins/Unity/Launcher/launchermodel.h+1
@@ -49,6 +49,7 @@ public:
4949 Q_INVOKABLE void requestRemove(const QString &appId);
5050 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
5151 Q_INVOKABLE void setUser(const QString &username);
52+ Q_INVOKABLE void applicationFocused(const QString &appId);
5253
5354private:
5455 void storeAppList();
tests/mocks/Unity/Launcher/MockLauncherModel.cpp+5
@@ -180,3 +180,8 @@ void MockLauncherModel::setUser(const QString &username)
180180 Q_UNUSED(username)
181181 // TODO: implement this...
182182}
183+
184+void MockLauncherModel::applicationFocused(const QString &appId)
185+{
186+ Q_UNUSED(appId)
187+}
tests/mocks/Unity/Launcher/MockLauncherModel.h+1
@@ -44,6 +44,7 @@ public:
4444 Q_INVOKABLE void requestRemove(const QString &appId);
4545 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
4646 Q_INVOKABLE void setUser(const QString &username);
47+ Q_INVOKABLE void applicationFocused(const QString &appId);
4748
4849Q_SIGNALS:
4950 void quickListTriggered(const QString &appId, int index);
tests/plugins/Unity/Launcher/CMakeLists.txt+10
@@ -10,6 +10,7 @@ include_directories(
1010
1111add_definitions(-DSM_BUSNAME=sessionBus)
1212add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
13+add_definitions(-DLAUNCHER_TESTING)
1314
1415set(testCommand ${CMAKE_CURRENT_BINARY_DIR}/launcherbackendtestExec
1516 -o ${CMAKE_BINARY_DIR}/launcherbackendtest.xml,xunitxml
@@ -24,3 +25,12 @@ add_executable(launcherbackendtestExec
2425 )
2526target_link_libraries(launcherbackendtestExec ${GSETTINGS_QT_LDFLAGS})
2627qt5_use_modules(launcherbackendtestExec Test Core DBus)
28+
29+# copy .desktop files into build directory for shadow builds
30+file(GLOB DESKTOP_FILES *.desktop)
31+
32+foreach(DESKTOP_FILE ${DESKTOP_FILES})
33+ file(COPY "${DESKTOP_FILE}"
34+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
35+ )
36+endforeach()
tests/plugins/Unity/Launcher/launcherbackendtest.cpp+14−15
@@ -20,7 +20,6 @@
2020#include "launcherbackend.h"
2121
2222#include <QtTest>
23−#include <QDebug>
2423
2524class LauncherBackendTest : public QObject
2625{
@@ -31,29 +30,29 @@ private Q_SLOTS:
3130 {
3231 LauncherBackend backend(false);
3332
34− backend.setStoredApplications(QStringList() << "relative.path" << "/full/path");
35− QCOMPARE(backend.storedApplications(), QStringList() << "relative.path" << "/full/path");
33+ backend.setStoredApplications(QStringList() << "rel-icon.desktop" << "abs-icon" << "invalid");
34+ QCOMPARE(backend.storedApplications(), QStringList() << "rel-icon.desktop" << "abs-icon");
3635 }
3736
3837 void testPinning()
3938 {
4039 LauncherBackend backend(false);
4140
42− backend.setStoredApplications(QStringList() << "one" << "two");
43− QCOMPARE(backend.isPinned("one"), false);
44− QCOMPARE(backend.isPinned("two"), false);
41+ backend.setStoredApplications(QStringList() << "rel-icon" << "abs-icon");
42+ QCOMPARE(backend.isPinned("rel-icon"), false);
43+ QCOMPARE(backend.isPinned("abs-icon"), false);
4544
46− backend.setPinned("two", true);
47− QCOMPARE(backend.isPinned("two"), true);
45+ backend.setPinned("rel-icon", true);
46+ QCOMPARE(backend.isPinned("rel-icon"), true);
4847
49− backend.setStoredApplications(QStringList() << "one" << "two" << "three");
50− QCOMPARE(backend.isPinned("two"), true);
51− QCOMPARE(backend.isPinned("three"), false);
48+ backend.setStoredApplications(QStringList() << "rel-icon" << "abs-icon" << "no-name");
49+ QCOMPARE(backend.isPinned("rel-icon"), true);
50+ QCOMPARE(backend.isPinned("no-name"), false);
5251
53− backend.setPinned("three", true);
54− backend.setStoredApplications(QStringList() << "one" << "two");
55− QCOMPARE(backend.isPinned("two"), true);
56− QCOMPARE(backend.isPinned("three"), false); // doesn't exist anymore!
52+ backend.setPinned("no-name", true);
53+ backend.setStoredApplications(QStringList() << "rel-icon" << "abs-icon");
54+ QCOMPARE(backend.isPinned("rel-icon"), true);
55+ QCOMPARE(backend.isPinned("no-name"), false); // doesn't exist anymore!
5756 }
5857};
5958