[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [plasma-workspace] libtaskmanager: Avoid absolute paths to .desktop files in launcher URLs.
From: Eike Hein <null () kde ! org>
Date: 2017-08-29 22:46:28
Message-ID: E1dmpHA-0002bZ-Kn () code ! kde ! org
[Download RAW message or body]
Git commit a47d1f19e1e0bda300ff799dfc6f377802a2a678 by Eike Hein.
Committed on 29/08/2017 at 22:46.
Pushed by hein into branch 'master'.
Avoid absolute paths to .desktop files in launcher URLs.
Summary:
In any place we look up a KService, check if it has a menuId,
and then generate KAStats-style applications: URL with it. Also
learn how to handle applications: URLs.
This was requested by Kai in D7203. His patch makes Kate
dynamically add its sessions as jump list actions to a copy of its
.desktop file in $HOME. As the library would generate the absolute
path to a .desktop file e.g. in /usr as launcher URL before, the
TM applet would ignore the overriding copy in $HOME and the actions
wouldn't be found.
This patch won't rewrite existing config, but LauncherTasksModel
will resolve the absolute path to the applications: URL as it goes
through TaskTools, and then return that. The window and startup
tasks models produce those URLs, too, so things match up. Newly-
added launchers will then store the applications: URL in config
directly.
Moving away from storing absolute paths when we can is also nice
in case there is a $HOME .desktop file at the time a launcher is
added which later gets deleted. Using the new storage format, we
will now fall back to a system file instead.
Note the conservative approach taken: We only generate an
applications: URL when the service returns something for menuId().
We don't use KService::storageId() here, which can fall back to
KService::entryPath() - in this case we're better off just using
the absolute path we already have. We still use storageId() when
generating the applications: URL for KAStats db insertions, as
that is more liberal (and matches Kicker).
It makes sense to look at the Kicker backend code to see if should
store applications: URLs (which it already produces to insert into
KAStats) as well.
This will need a subsequent patch to the Task Manager applet to
handle applications: URLs there in code that consumes launcher URLs
to parse things out of .desktop files.
Contains other minor cleanup and fixes, such as porting the
LauncherTasksModel to use TaskTools::runApp (which now understands
preferred: URLs as well), a fix for a small logic error there (the
&& before the !isApplication should have been ||, now moot), and
not needlessly opening and parsing a .desktop file in
TaskTools::appDataFromUrl.
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D7561
M +1 -35 libtaskmanager/launchertasksmodel.cpp
M +8 -0 libtaskmanager/startuptasksmodel.cpp
M +70 -17 libtaskmanager/tasktools.cpp
M +8 -0 libtaskmanager/xwindowtasksmodel.cpp
https://commits.kde.org/plasma-workspace/a47d1f19e1e0bda300ff799dfc6f377802a2a678
diff --git a/libtaskmanager/launchertasksmodel.cpp \
b/libtaskmanager/launchertasksmodel.cpp index ea2a0451..bc4ae726 100644
--- a/libtaskmanager/launchertasksmodel.cpp
+++ b/libtaskmanager/launchertasksmodel.cpp
@@ -544,41 +544,7 @@ void LauncherTasksModel::requestNewInstance(const QModelIndex \
&index) return;
}
- const QUrl &url = d->launchersOrder.at(index.row());
-
- quint32 timeStamp = 0;
-
-#if HAVE_X11
- if (KWindowSystem::isPlatformX11()) {
- timeStamp = QX11Info::appUserTime();
- }
-#endif
-
- if (url.scheme() == QLatin1String("preferred")) {
- const KService::Ptr service = \
KService::serviceByStorageId(defaultApplication(url));
-
- if (!service && !service->isApplication()) {
- return;
- }
-
- KRun::runApplication(*service, QList<QUrl>(), nullptr, 0, {},
- KStartupInfo::createNewStartupIdForTimestamp(timeStamp));
-
- KActivities::ResourceInstance::notifyAccessed(QUrl(QStringLiteral("applications:") \
+ service->storageId()),
- QStringLiteral("org.kde.libtaskmanager"));
- } else {
- const KService::Ptr service = \
KService::serviceByDesktopPath(url.toLocalFile());
-
- if (service && service->isApplication()) {
- KRun::runApplication(*service, QList<QUrl>(), nullptr, 0, {},
- KStartupInfo::createNewStartupIdForTimestamp(timeStamp));
-
- KActivities::ResourceInstance::notifyAccessed(QUrl(QStringLiteral("applications:") \
+ service->storageId()),
- QStringLiteral("org.kde.libtaskmanager"));
- } else {
- new KRun(url, 0, false, \
KStartupInfo::createNewStartupIdForTimestamp(timeStamp));
- }
- }
+ runApp(d->appData(d->launchersOrder.at(index.row())));
}
void LauncherTasksModel::requestOpenUrls(const QModelIndex &index, const QList<QUrl> \
&urls)
diff --git a/libtaskmanager/startuptasksmodel.cpp \
b/libtaskmanager/startuptasksmodel.cpp index 2847ffe9..13977b35 100644
--- a/libtaskmanager/startuptasksmodel.cpp
+++ b/libtaskmanager/startuptasksmodel.cpp
@@ -193,6 +193,14 @@ QUrl StartupTasksModel::Private::launcherUrl(const \
KStartupInfoData &data) }
if (!services.empty()) {
+ const QString &menuId = services.at(0)->menuId();
+
+ // applications: URLs are used to refer to applications by their \
KService::menuId + // (i.e. .desktop file name) rather than the absolute path \
to a .desktop file. + if (!menuId.isEmpty()) {
+ return QUrl(QStringLiteral("applications:") + menuId);
+ }
+
QString path = services.at(0)->entryPath();
if (path.isEmpty()) {
diff --git a/libtaskmanager/tasktools.cpp b/libtaskmanager/tasktools.cpp
index 08499148..342d3c46 100644
--- a/libtaskmanager/tasktools.cpp
+++ b/libtaskmanager/tasktools.cpp
@@ -69,11 +69,36 @@ AppData appDataFromUrl(const QUrl &url, const QIcon \
&fallbackIcon) }
}
+ // applications: URLs are used to refer to applications by their \
KService::menuId + // (i.e. .desktop file name) rather than the absolute path to a \
.desktop file. + if (url.scheme() == QStringLiteral("applications")) {
+ const KService::Ptr service = KService::serviceByMenuId(url.path());
+
+ if (service && url.path() == service->menuId()) {
+ data.name = service->name();
+ data.genericName = service->genericName();
+ data.id = service->storageId();
+
+ if (data.icon.isNull()) {
+ data.icon = QIcon::fromTheme(service->icon());
+ }
+ }
+ }
+
if (url.isLocalFile() && KDesktopFile::isDesktopFile(url.toLocalFile())) {
KDesktopFile f(url.toLocalFile());
const KService::Ptr service = KService::serviceByStorageId(f.fileName());
+ // Resolve to non-absolute menuId-based URL if possible.
+ if (service) {
+ const QString &menuId = service->menuId();
+
+ if (!menuId.isEmpty()) {
+ data.url = QUrl(QStringLiteral("applications:") + menuId);
+ }
+ }
+
if (service && QUrl::fromLocalFile(service->entryPath()) == url) {
data.name = service->name();
data.genericName = service->genericName();
@@ -101,23 +126,23 @@ AppData appDataFromUrl(const QUrl &url, const QIcon \
&fallbackIcon)
const KService::Ptr service = KService::serviceByStorageId(data.id);
if (service) {
- QString desktopFile = service->entryPath();
-
- // Update with resolved URL.
- data.url = QUrl::fromLocalFile(desktopFile);
-
- KDesktopFile f(desktopFile);
- KConfigGroup cg(&f, "Desktop Entry");
+ const QString &menuId = service->menuId();
+ const QString &desktopFile = service->entryPath();
- data.icon = QIcon::fromTheme(f.readIcon());
- const QString exec = cg.readEntry("Exec", QString());
- data.name = cg.readEntry("Name", QString());
+ data.name = service->name();
+ data.genericName = service->genericName();
+ data.id = service->storageId();
- if (data.name.isEmpty() && !exec.isEmpty()) {
- data.name = exec.split(' ').at(0);
+ if (data.icon.isNull()) {
+ data.icon = QIcon::fromTheme(service->icon());
}
- data.genericName = f.readGenericName();
+ // Update with resolved URL.
+ if (!menuId.isEmpty()) {
+ data.url = QUrl(QStringLiteral("applications:") + menuId);
+ } else {
+ data.url = QUrl::fromLocalFile(desktopFile);
+ }
}
}
@@ -142,7 +167,16 @@ AppData appDataFromAppId(const QString &appId)
data.id = service->storageId();
data.name = service->name();
data.genericName = service->genericName();
- data.url = QUrl::fromLocalFile(service->entryPath());
+
+ const QString &menuId = service->menuId();
+
+ // applications: URLs are used to refer to applications by their \
KService::menuId + // (i.e. .desktop file name) rather than the absolute path \
to a .desktop file. + if (!menuId.isEmpty()) {
+ data.url = QUrl(QStringLiteral("applications:") + menuId);
+ } else {
+ data.url = QUrl::fromLocalFile(service->entryPath());
+ }
return data;
}
@@ -375,9 +409,18 @@ QUrl windowUrlFromMetadata(const QString &appId, quint32 pid,
}
if (!services.empty()) {
- QString path = services[0]->entryPath();
+ const QString &menuId = services.at(0)->menuId();
+
+ // applications: URLs are used to refer to applications by their \
KService::menuId + // (i.e. .desktop file name) rather than the absolute path \
to a .desktop file. + if (!menuId.isEmpty()) {
+ return QUrl(QStringLiteral("applications:") + menuId);
+ }
+
+ QString path = services.at(0)->entryPath();
+
if (path.isEmpty()) {
- path = services[0]->exec();
+ path = services.at(0)->exec();
}
if (!path.isEmpty()) {
@@ -640,7 +683,17 @@ void runApp(const AppData &appData, const QList<QUrl> &urls)
}
#endif
- const KService::Ptr service = \
KService::serviceByDesktopPath(appData.url.toLocalFile()); + KService::Ptr \
service; +
+ // applications: URLs are used to refer to applications by their \
KService::menuId + // (i.e. .desktop file name) rather than the absolute path \
to a .desktop file. + if (appData.url.scheme() == \
QStringLiteral("applications")) { + service = \
KService::serviceByMenuId(appData.url.path()); + } else if \
(appData.url.scheme() == QLatin1String("preferred")) { + const \
KService::Ptr service = \
KService::serviceByStorageId(defaultApplication(appData.url)); + } else {
+ service = KService::serviceByDesktopPath(appData.url.toLocalFile());
+ }
if (service && service->isApplication()) {
KRun::runApplication(*service, urls, nullptr, 0, {},
diff --git a/libtaskmanager/xwindowtasksmodel.cpp \
b/libtaskmanager/xwindowtasksmodel.cpp index 1cef6c97..349faae9 100644
--- a/libtaskmanager/xwindowtasksmodel.cpp
+++ b/libtaskmanager/xwindowtasksmodel.cpp
@@ -484,6 +484,14 @@ QUrl XWindowTasksModel::Private::windowUrl(WId window)
KService::Ptr service = KService::serviceByStorageId(desktopFile);
if (service) {
+ const QString &menuId = service->menuId();
+
+ // applications: URLs are used to refer to applications by their \
KService::menuId + // (i.e. .desktop file name) rather than the absolute \
path to a .desktop file. + if (!menuId.isEmpty()) {
+ return QUrl(QStringLiteral("applications:") + menuId);
+ }
+
return QUrl::fromLocalFile(service->entryPath());
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic