Commit b72930eb authored by Jin Liu's avatar Jin Liu Committed by Ahmad Samir
Browse files

Launch app in terminal when Terminal=true

When the desktop file has Terminal=true (e.g. htop), it should be
launched in a terminal.

Instead of calling "kstart5 -- <exec path>", this calls
"kstart5 --application <desktop file name>" when and only when:
1. kstart5 is available
2. the desktop file is in XDG_DATA_HOME/applications/,
not XDG_DATA_HOME/kglobalaccel/
3. we are launching the desktop file's main group, not other actions

BUG: 455117
parent 28b5e417
Pipeline #198836 passed with stage
in 2 minutes and 27 seconds
......@@ -11,6 +11,7 @@
#include "logging_p.h"
#include <QDBusConnectionInterface>
#include <QFileInfo>
#include <QProcess>
#include <KShell>
......@@ -28,6 +29,16 @@ KServiceActionComponent::KServiceActionComponent(const QString &serviceStorageId
// Fallback to applications data dir
// for custom shortcut for instance
fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("applications/") + serviceStorageId);
m_isInApplicationsDir = true;
} else {
QFileInfo info(fileName);
if (info.isSymLink()) {
auto fileName2 = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("applications/") + serviceStorageId);
if (info.symLinkTarget() == fileName2) {
fileName = fileName2;
m_isInApplicationsDir = true;
}
}
}
if (fileName.isEmpty()) {
qCWarning(KGLOBALACCELD) << "No desktop file found for service " << serviceStorageId;
......@@ -39,7 +50,7 @@ KServiceActionComponent::~KServiceActionComponent()
{
}
void runProcess(const KConfigGroup &group, bool klauncherAvailable, const QString &token)
void KServiceActionComponent::runProcess(const KConfigGroup &group, const QString &token)
{
QStringList args = KShell::splitArgs(group.readEntry(QStringLiteral("Exec"), QString()));
if (args.isEmpty()) {
......@@ -68,10 +79,20 @@ void runProcess(const KConfigGroup &group, bool klauncherAvailable, const QStrin
const auto kstart = QStandardPaths::findExecutable(QStringLiteral("kstart5"));
if (!kstart.isEmpty()) {
args.prepend(command);
args.prepend(QStringLiteral("--"));
if (group.name() == QLatin1String("Desktop Entry") && m_isInApplicationsDir) {
args.prepend(QFileInfo(m_desktopFile->fileName()).completeBaseName());
args.prepend(QStringLiteral("--application"));
} else {
args.prepend(command);
args.prepend(QStringLiteral("--"));
}
startDetachedWithToken(kstart, args);
} else if (klauncherAvailable) {
return;
}
QDBusConnectionInterface *dbusDaemon = QDBusConnection::sessionBus().interface();
const bool klauncherAvailable = dbusDaemon->isServiceRegistered(QStringLiteral("org.kde.klauncher5"));
if (klauncherAvailable) {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.klauncher5"),
QStringLiteral("/KLauncher"),
QStringLiteral("org.kde.KLauncher"),
......@@ -79,14 +100,15 @@ void runProcess(const KConfigGroup &group, bool klauncherAvailable, const QStrin
msg << command << args;
QDBusConnection::sessionBus().asyncCall(msg);
} else {
const QString cmdExec = QStandardPaths::findExecutable(command);
if (cmdExec.isEmpty()) {
qCWarning(KGLOBALACCELD) << "Could not find executable in PATH" << command;
return;
}
startDetachedWithToken(cmdExec, args);
return;
}
const QString cmdExec = QStandardPaths::findExecutable(command);
if (cmdExec.isEmpty()) {
qCWarning(KGLOBALACCELD) << "Could not find executable in PATH" << command;
return;
}
startDetachedWithToken(cmdExec, args);
}
void KServiceActionComponent::emitGlobalShortcutPressed(const GlobalShortcut &shortcut)
......@@ -117,18 +139,15 @@ void KServiceActionComponent::emitGlobalShortcutPressed(const GlobalShortcut &sh
return;
}
QDBusConnectionInterface *dbusDaemon = QDBusConnection::sessionBus().interface();
const bool klauncherAvailable = dbusDaemon->isServiceRegistered(QStringLiteral("org.kde.klauncher5"));
// we can't use KRun there as it depends from KIO and would create a circular dep
if (shortcut.uniqueName() == QLatin1String("_launch")) {
runProcess(m_desktopFile->desktopGroup(), klauncherAvailable, token);
runProcess(m_desktopFile->desktopGroup(), token);
return;
}
const auto lstActions = m_desktopFile->readActions();
for (const QString &action : lstActions) {
if (action == shortcut.uniqueName()) {
runProcess(m_desktopFile->actionGroup(action), klauncherAvailable, token);
runProcess(m_desktopFile->actionGroup(action), token);
return;
}
}
......
......@@ -34,8 +34,11 @@ public:
bool cleanUp() override;
private:
void runProcess(const KConfigGroup &group, const QString &token);
QString m_serviceStorageId;
QScopedPointer<KDesktopFile> m_desktopFile;
bool m_isInApplicationsDir = false;
};
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment