diff --git a/runners/appstream/appstreamrunner.cpp b/runners/appstream/appstreamrunner.cpp index 3782f00bf..dd14902c4 100644 --- a/runners/appstream/appstreamrunner.cpp +++ b/runners/appstream/appstreamrunner.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -39,7 +40,8 @@ InstallerRunner::InstallerRunner(QObject *parent, const KPluginMetaData &metaDat : Plasma::AbstractRunner(parent, metaData, args) { setObjectName(QStringLiteral("Installation Suggestions")); - setPriority(AbstractRunner::HighestPriority); + // We want to give the other runners time to check if there are matching applications already installed + setPriority(AbstractRunner::LowestPriority); addSyntax(Plasma::RunnerSyntax(":q:", i18n("Looks for non-installed components according to :q:"))); setMinLetterCount(3); @@ -80,6 +82,25 @@ static QIcon componentIcon(const AppStream::Component &comp) void InstallerRunner::match(Plasma::RunnerContext &context) { + // Give the other runners a bit of time to produce results + QEventLoop loop; + QTimer::singleShot(200, &loop, [&loop]() { + loop.quit(); + }); + loop.exec(); + if (!context.isValid()) { + return; + } + + // Check if other plugins have already found an executable, if that is the case we do + // not want to ask the user to install anything else + const QList matches = context.matches(); + for (const auto &match : matches) { + if (match.id().startsWith(QLatin1String("exec://"))) { + return; + } + } + const auto components = findComponentsByString(context.query()).mid(0, 3); for (const AppStream::Component &component : components) { diff --git a/runners/baloo/baloosearchrunner.cpp b/runners/baloo/baloosearchrunner.cpp index 476855dd3..4e2544c0e 100644 --- a/runners/baloo/baloosearchrunner.cpp +++ b/runners/baloo/baloosearchrunner.cpp @@ -172,7 +172,7 @@ RemoteMatches SearchRunner::matchInternal(const QString &searchTerm, const QStri foundUrls.insert(url); - match.id = it.filePath(); + match.id = url.toString(); match.text = url.fileName(); match.iconName = mimeDb.mimeTypeForFile(localUrl).iconName(); match.relevance = relevance; @@ -197,7 +197,7 @@ RemoteMatches SearchRunner::matchInternal(const QString &searchTerm, const QStri void SearchRunner::Run(const QString &id, const QString &actionId) { - const QUrl url = QUrl::fromLocalFile(id); + const QUrl url(id); if (actionId == s_openParentDirId) { KIO::highlightInFileManager({url}); return; diff --git a/runners/baloo/plasma-runner-baloosearch.desktop b/runners/baloo/plasma-runner-baloosearch.desktop index 296f8ad59..075d374b0 100644 --- a/runners/baloo/plasma-runner-baloosearch.desktop +++ b/runners/baloo/plasma-runner-baloosearch.desktop @@ -110,3 +110,5 @@ X-Plasma-DBusRunner-Service=org.kde.runners.baloo X-Plasma-DBusRunner-Path=/runner X-Plasma-Request-Actions-Once=true X-Plasma-Runner-Min-Letter-Count=3 +X-Plasma-Runner-Unique-Results=true +X-Plasma-Runner-Weak-Results=true diff --git a/runners/recentdocuments/plasma-runner-recentdocuments.desktop b/runners/recentdocuments/plasma-runner-recentdocuments.desktop index e005d208b..a7ca94f8e 100644 --- a/runners/recentdocuments/plasma-runner-recentdocuments.desktop +++ b/runners/recentdocuments/plasma-runner-recentdocuments.desktop @@ -47,3 +47,4 @@ X-KDE-PluginInfo-Version=1.0 X-KDE-PluginInfo-License=LGPL X-Plasma-AdvertiseSingleRunnerQueryMode=true X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-Runner-Unique-Results=true diff --git a/runners/recentdocuments/recentdocuments.cpp b/runners/recentdocuments/recentdocuments.cpp index 4373bfd6b..1097ebd69 100644 --- a/runners/recentdocuments/recentdocuments.cpp +++ b/runners/recentdocuments/recentdocuments.cpp @@ -97,6 +97,7 @@ void RecentDocuments::match(Plasma::RunnerContext &context) match.setRelevance(relevance); match.setData(QVariant(url)); match.setUrls({url}); + match.setId(url.toString()); if (url.isLocalFile()) { match.setActions(actions().values()); } diff --git a/runners/services/plasma-runner-services.desktop b/runners/services/plasma-runner-services.desktop index f060c06d4..f17e53643 100644 --- a/runners/services/plasma-runner-services.desktop +++ b/runners/services/plasma-runner-services.desktop @@ -175,3 +175,4 @@ X-KDE-PluginInfo-Version=1.0 X-KDE-PluginInfo-License=LGPL X-KDE-PluginInfo-EnabledByDefault=true X-Plasma-AdvertiseSingleRunnerQueryMode=true +X-Plasma-Runner-Unique-Results=true diff --git a/runners/services/servicerunner.cpp b/runners/services/servicerunner.cpp index 4395a112d..142dd3dcd 100644 --- a/runners/services/servicerunner.cpp +++ b/runners/services/servicerunner.cpp @@ -40,6 +40,7 @@ #include #include +#include #include "debug.h" @@ -177,6 +178,13 @@ private: QUrl url(service->storageId()); url.setScheme(QStringLiteral("applications")); match.setData(url); + QString exec = service->exec(); + // We have a snap, remove the ENV variable + if (exec.contains(QLatin1String("BAMF_DESKTOP_FILE_HINT"))) { + const static QRegularExpression snapCleanupRegex(QStringLiteral("env BAMF_DESKTOP_FILE_HINT=.+ ")); + exec.remove(snapCleanupRegex); + } + match.setId(QStringLiteral("exec://") + KIO::DesktopExecParser::executableName(exec)); if (!service->genericName().isEmpty() && service->genericName() != name) { match.setSubtext(service->genericName()); diff --git a/runners/shell/plasma-runner-shell.desktop b/runners/shell/plasma-runner-shell.desktop index 28d634ba9..8e580b142 100644 --- a/runners/shell/plasma-runner-shell.desktop +++ b/runners/shell/plasma-runner-shell.desktop @@ -164,3 +164,5 @@ X-KDE-PluginInfo-Version=1.0 X-KDE-PluginInfo-License=LGPL X-Plasma-AdvertiseSingleRunnerQueryMode=true X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-Runner-Unique-Results=true +X-Plasma-Runner-Weak-Results=true diff --git a/runners/shell/shellrunner.cpp b/runners/shell/shellrunner.cpp index ad90bd35c..b3b498dcd 100644 --- a/runners/shell/shellrunner.cpp +++ b/runners/shell/shellrunner.cpp @@ -36,7 +36,8 @@ ShellRunner::ShellRunner(QObject *parent, const KPluginMetaData &metaData, const : Plasma::AbstractRunner(parent, metaData, args) { setObjectName(QStringLiteral("Command")); - setPriority(AbstractRunner::HighestPriority); + // The results from the services runner are preferred, consequently we set a low priority + setPriority(AbstractRunner::LowestPriority); // If the runner is not authorized we can suspend it bool enabled = KAuthorized::authorize(QStringLiteral("run_command")) && KAuthorized::authorize(QStringLiteral("shell_access")); suspendMatching(!enabled); @@ -57,7 +58,7 @@ void ShellRunner::match(Plasma::RunnerContext &context) if (parseShellCommand(context.query(), envs, command)) { const QString term = context.query(); Plasma::QueryMatch match(this); - match.setId(term); + match.setId(QStringLiteral("exec://") + context.query()); match.setType(Plasma::QueryMatch::ExactMatch); match.setIcon(m_matchIcon); match.setText(i18n("Run %1", term));