From 9e6b299dede3d664d0f4e2255e8fb14743f8c0e8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ball=C3=B3=20Gy=C3=B6rgy?= Date: Fri, 4 Apr 2025 08:08:31 +0200 Subject: [PATCH] [PATCH] KProcessRunner: Fix launching actions without executable If D-Bus activation is possible, it's not needed to have an executable, since everything is done via D-Bus. Therefore look for the matching action name instead of the exec value when launching an action. The specification allows to omit the "Exec" key if "DBusActivatable" is true. Most applications specify the Exec parameter for compatibility reasons, but if the action's "Exec" line got removed from a D-Bus activatable desktop file, then KIO just activates the application rather than calling the requested action. This change fixes that issue. Gbp-Pq: Name upstream_31806c51_KProcessRunner-Fix-launching-actions-without-executable.patch --- src/gui/applicationlauncherjob.cpp | 7 +++++-- src/gui/kprocessrunner.cpp | 8 ++++++-- src/gui/kprocessrunner_p.h | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/gui/applicationlauncherjob.cpp b/src/gui/applicationlauncherjob.cpp index 463cec1..f3cafaf 100644 --- a/src/gui/applicationlauncherjob.cpp +++ b/src/gui/applicationlauncherjob.cpp @@ -49,6 +49,7 @@ public: KService::Ptr m_service; QString m_serviceEntryPath; QList m_urls; + QString m_actionName; KIO::ApplicationLauncherJob::RunFlags m_runFlags; QString m_suggestedFileName; QString m_mimeTypeName; @@ -75,6 +76,7 @@ KIO::ApplicationLauncherJob::ApplicationLauncherJob(const KServiceAction &servic Q_ASSERT(d->m_service); d->m_service.detach(); d->m_service->setExec(serviceAction.exec()); + d->m_actionName = serviceAction.name(); } KIO::ApplicationLauncherJob::ApplicationLauncherJob(const KDesktopFileAction &desktopFileAction, QObject *parent) : ApplicationLauncherJob(KService::Ptr(new KService(desktopFileAction.desktopFilePath())), parent) @@ -82,6 +84,7 @@ KIO::ApplicationLauncherJob::ApplicationLauncherJob(const KDesktopFileAction &de Q_ASSERT(d->m_service); d->m_service.detach(); d->m_service->setExec(desktopFileAction.exec()); + d->m_actionName = desktopFileAction.name(); } KIO::ApplicationLauncherJob::ApplicationLauncherJob(QObject *parent) @@ -196,7 +199,7 @@ void KIO::ApplicationLauncherJob::proceedAfterSecurityChecks() d->m_processRunners.reserve(d->m_numProcessesPending); for (int i = 1; i < d->m_urls.count(); ++i) { auto *processRunner = - KProcessRunner::fromApplication(d->m_service, d->m_serviceEntryPath, {d->m_urls.at(i)}, d->m_runFlags, d->m_suggestedFileName, QByteArray{}); + KProcessRunner::fromApplication(d->m_service, d->m_serviceEntryPath, {d->m_urls.at(i)}, d->m_actionName, d->m_runFlags, d->m_suggestedFileName, QByteArray{}); d->m_processRunners.push_back(processRunner); connect(processRunner, &KProcessRunner::processStarted, this, [this](qint64 pid) { d->slotStarted(pid); @@ -208,7 +211,7 @@ void KIO::ApplicationLauncherJob::proceedAfterSecurityChecks() } auto *processRunner = - KProcessRunner::fromApplication(d->m_service, d->m_serviceEntryPath, d->m_urls, d->m_runFlags, d->m_suggestedFileName, d->m_startupId); + KProcessRunner::fromApplication(d->m_service, d->m_serviceEntryPath, d->m_urls, d->m_actionName, d->m_runFlags, d->m_suggestedFileName, d->m_startupId); d->m_processRunners.push_back(processRunner); connect(processRunner, &KProcessRunner::error, this, [this](const QString &errorText) { setError(KJob::UserDefinedError); diff --git a/src/gui/kprocessrunner.cpp b/src/gui/kprocessrunner.cpp index 64fa3af..00f7811 100644 --- a/src/gui/kprocessrunner.cpp +++ b/src/gui/kprocessrunner.cpp @@ -88,6 +88,7 @@ static void modifyEnv(KProcess &process, QProcessEnvironment mod) KProcessRunner *KProcessRunner::fromApplication(const KService::Ptr &service, const QString &serviceEntryPath, const QList &urls, + const QString &actionName, KIO::ApplicationLauncherJob::RunFlags flags, const QString &suggestedFileName, const QByteArray &asn) @@ -103,9 +104,12 @@ KProcessRunner *KProcessRunner::fromApplication(const KService::Ptr &service, const bool notYetSupportedOpenActivationNeeded = !urls.isEmpty(); if (!notYetSupportedOpenActivationNeeded && DBusActivationRunner::activationPossible(service, flags, suggestedFileName)) { const auto actions = service->actions(); - auto action = std::find_if(actions.cbegin(), actions.cend(), [service](const KServiceAction &action) { - return action.exec() == service->exec(); + auto action = std::find_if(actions.cbegin(), actions.cend(), [actionName](const KServiceAction &action) { + return action.name() == actionName; }); + if (!actionName.isEmpty() && action == actions.cend()) { + qCWarning(KIO_GUI) << "Requested action" << actionName << "cannot be found for" << service->name(); + } instance = new DBusActivationRunner(action != actions.cend() ? action->name() : QString()); } else { instance = makeInstance(); diff --git a/src/gui/kprocessrunner_p.h b/src/gui/kprocessrunner_p.h index 63e517d..7f084a4 100644 --- a/src/gui/kprocessrunner_p.h +++ b/src/gui/kprocessrunner_p.h @@ -59,6 +59,7 @@ public: static KProcessRunner *fromApplication(const KService::Ptr &service, const QString &serviceEntryPath, const QList &urls, + const QString &actionName = {}, KIO::ApplicationLauncherJob::RunFlags flags = {}, const QString &suggestedFileName = {}, const QByteArray &asn = {}); -- 2.30.2