Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package krunner for openSUSE:Factory checked 
in at 2021-05-10 15:35:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/krunner (Old)
 and      /work/SRC/openSUSE:Factory/.krunner.new.2988 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "krunner"

Mon May 10 15:35:47 2021 rev:89 rq:891778 version:5.82.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/krunner/krunner.changes  2021-04-12 
12:36:48.849330875 +0200
+++ /work/SRC/openSUSE:Factory/.krunner.new.2988/krunner.changes        
2021-05-10 15:37:30.534010207 +0200
@@ -1,0 +2,13 @@
+Sat May  1 16:41:12 UTC 2021 - Christophe Giboudeaux <christo...@krop.fr>
+
+- Update to 5.82.0
+  * New feature release
+  * For more details please see:
+  * https://kde.org/announcements/frameworks/5/5.82.0
+- Too many changes since 5.81.0, only listing bugfixes:
+  * Allow runners to prevent duplicate results (kde#406292)
+  * runnermanager: Allow loading runners in single runner mode if
+    they are disabled (kde#435050)
+  * dbus runner: Fix interface definition (kde#433549)
+
+-------------------------------------------------------------------

Old:
----
  krunner-5.81.0.tar.xz
  krunner-5.81.0.tar.xz.sig

New:
----
  krunner-5.82.0.tar.xz
  krunner-5.82.0.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ krunner.spec ++++++
--- /var/tmp/diff_new_pack.taY7gJ/_old  2021-05-10 15:37:31.134007883 +0200
+++ /var/tmp/diff_new_pack.taY7gJ/_new  2021-05-10 15:37:31.134007883 +0200
@@ -17,7 +17,7 @@
 
 
 %define lname   libKF5Runner5
-%define _tar_path 5.81
+%define _tar_path 5.82
 # Full KF5 version (e.g. 5.33.0)
 %{!?_kf5_version: %global _kf5_version %{version}}
 # Last major and minor KF5 version (e.g. 5.33)
@@ -25,7 +25,7 @@
 # Only needed for the package signature condition
 %bcond_without lang
 Name:           krunner
-Version:        5.81.0
+Version:        5.82.0
 Release:        0
 Summary:        KDE Framework for providing different actions given a string 
query
 License:        LGPL-2.1-or-later
@@ -50,9 +50,9 @@
 BuildRequires:  cmake(KF5Solid) >= %{_kf5_bugfix_version}
 BuildRequires:  cmake(KF5ThreadWeaver) >= %{_kf5_bugfix_version}
 BuildRequires:  cmake(KF5WindowSystem) >= %{_kf5_bugfix_version}
-BuildRequires:  cmake(Qt5Gui) >= 5.14.0
-BuildRequires:  cmake(Qt5Quick) >= 5.14.0
-BuildRequires:  cmake(Qt5Test) >= 5.14.0
+BuildRequires:  cmake(Qt5Gui) >= 5.15.0
+BuildRequires:  cmake(Qt5Quick) >= 5.15.0
+BuildRequires:  cmake(Qt5Test) >= 5.15.0
 
 %description
 KDE Framework for providing different actions given a string query.
@@ -70,22 +70,22 @@
 Requires:       %{lname} = %{version}
 Requires:       extra-cmake-modules
 Requires:       cmake(KF5Plasma) >= %{_kf5_bugfix_version}
-Requires:       cmake(Qt5Core) >= 5.14.0
+Requires:       cmake(Qt5Core) >= 5.15.0
 Conflicts:      kapptemplate <= 16.03.80
 
 %description devel
 Files needed for developing custom runners or frontends.
 
 %prep
-%setup -q
+%autosetup -p1
 
 %build
-  %cmake_kf5 -d build
-  %cmake_build
+%cmake_kf5 -d build
+%cmake_build
 
 %install
-  %kf5_makeinstall -C build
-  %fdupes %{buildroot}
+%kf5_makeinstall -C build
+%fdupes %{buildroot}
 
 %post -n %{lname} -p /sbin/ldconfig
 %postun -n %{lname} -p /sbin/ldconfig


++++++ krunner-5.81.0.tar.xz -> krunner-5.82.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/.gitignore 
new/krunner-5.82.0/.gitignore
--- old/krunner-5.81.0/.gitignore       2021-04-03 11:37:00.000000000 +0200
+++ new/krunner-5.82.0/.gitignore       2021-05-01 11:45:28.000000000 +0200
@@ -25,3 +25,4 @@
 .idea
 .vscode
 /compile_commands.json
+.clangd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/CMakeLists.txt 
new/krunner-5.82.0/CMakeLists.txt
--- old/krunner-5.81.0/CMakeLists.txt   2021-04-03 11:37:00.000000000 +0200
+++ new/krunner-5.82.0/CMakeLists.txt   2021-05-01 11:45:28.000000000 +0200
@@ -1,12 +1,12 @@
 cmake_minimum_required(VERSION 3.5)
 
-set(KF_VERSION "5.81.0") # handled by release scripts
-set(KF_DEP_VERSION "5.81.0") # handled by release scripts
+set(KF_VERSION "5.82.0") # handled by release scripts
+set(KF_DEP_VERSION "5.82.0") # handled by release scripts
 project(KRunner VERSION ${KF_VERSION})
 
 # ECM setup
 include(FeatureSummary)
-find_package(ECM 5.81.0  NO_MODULE)
+find_package(ECM 5.82.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL "https://commits.kde.org/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 
@@ -38,7 +38,7 @@
 )
 
 # Dependencies
-set(REQUIRED_QT_VERSION 5.14.0)
+set(REQUIRED_QT_VERSION 5.15.0)
 
 find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED Gui Widgets Quick)
 
@@ -70,8 +70,8 @@
         PACKAGE_SETUP_AUTOMOC_VARIABLES
 )
 
-add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050e00)
-add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x055000)
+add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050e00) # must port away from 
qmlRegisterInterface before upgrading this to 050f00
+add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x055100)
 add_definitions(-DPLASMA_DISABLE_DEPRECATED_BEFORE_AND_AT=0x050500) # needed 
because we use Plasma::Package in the API
 add_definitions(-DQT_NO_FOREACH -DQT_NO_KEYWORDS)
 
@@ -79,7 +79,6 @@
 add_subdirectory(src)
 if (BUILD_TESTING)
     add_subdirectory(autotests)
-    add_subdirectory(tests)
 endif()
 add_subdirectory(templates)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/autotests/CMakeLists.txt 
new/krunner-5.82.0/autotests/CMakeLists.txt
--- old/krunner-5.81.0/autotests/CMakeLists.txt 2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/autotests/CMakeLists.txt 2021-05-01 11:45:28.000000000 
+0200
@@ -28,6 +28,11 @@
     LINK_LIBRARIES Qt5::Test KF5::KIOCore KF5Runner Qt5::Widgets
 )
 
+ecm_add_tests(
+    runnermanagersinglerunnermodetest.cpp
+    LINK_LIBRARIES Qt5::Test KF5::KIOCore KF5Runner Qt5::Widgets Qt5::DBus
+)
+
 set(demoapp_SRCS testremoterunner.cpp)
 qt5_add_dbus_adaptor(demoapp_SRCS "../src/data/org.kde.krunner1.xml" 
testremoterunner.h TestRemoteRunner)
 add_executable(testremoterunner ${demoapp_SRCS})
@@ -38,3 +43,4 @@
 
 include(../KF5KRunnerMacros.cmake)
 configure_krunner_test(dbusrunnertest testremoterunner DESKTOP_FILE 
"${CMAKE_CURRENT_SOURCE_DIR}/dbusrunnertest.desktop")
+configure_krunner_test(runnermanagersinglerunnermodetest testremoterunner 
DESKTOP_FILE "${CMAKE_CURRENT_SOURCE_DIR}/dbusrunnertest.desktop")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/autotests/dbusrunnertest.desktop 
new/krunner-5.82.0/autotests/dbusrunnertest.desktop
--- old/krunner-5.81.0/autotests/dbusrunnertest.desktop 2021-04-03 
11:37:00.000000000 +0200
+++ new/krunner-5.82.0/autotests/dbusrunnertest.desktop 2021-05-01 
11:45:28.000000000 +0200
@@ -10,6 +10,7 @@
 X-KDE-PluginInfo-Version=1.0
 X-KDE-PluginInfo-License=LGPL
 X-KDE-PluginInfo-EnabledByDefault=true
+X-Plasma-AdvertiseSingleRunnerQueryMode=true
 X-Plasma-API=DBus
 X-Plasma-DBusRunner-Service=net.krunnertests.dave
 X-Plasma-DBusRunner-Path=/dave
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/autotests/dbusrunnertestmulti.desktop 
new/krunner-5.82.0/autotests/dbusrunnertestmulti.desktop
--- old/krunner-5.81.0/autotests/dbusrunnertestmulti.desktop    2021-04-03 
11:37:00.000000000 +0200
+++ new/krunner-5.82.0/autotests/dbusrunnertestmulti.desktop    2021-05-01 
11:45:28.000000000 +0200
@@ -1,12 +1,12 @@
 [Desktop Entry]
-Name=DBus runner test
-Comment=DBus runner test
+Name=DBus runner testmulti
+Comment=DBus runner testmulti
 X-KDE-ServiceTypes=Plasma/Runner
 Type=Service
 Icon=internet-web-browser
 X-KDE-PluginInfo-Author=Some Developer
 X-KDE-PluginInfo-Email=k...@example.com
-X-KDE-PluginInfo-Name=dbusrunnertest
+X-KDE-PluginInfo-Name=dbusrunnertestmulti
 X-KDE-PluginInfo-Version=1.0
 X-KDE-PluginInfo-License=LGPL
 X-KDE-PluginInfo-EnabledByDefault=true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/autotests/fakerunner.h 
new/krunner-5.82.0/autotests/fakerunner.h
--- old/krunner-5.81.0/autotests/fakerunner.h   2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/autotests/fakerunner.h   2021-05-01 11:45:28.000000000 
+0200
@@ -10,8 +10,8 @@
 class FakeRunner : public AbstractRunner
 {
 public:
-    FakeRunner()
-        : AbstractRunner(nullptr, 
KPluginMetaData(QStringLiteral("metadata.desktop")), QVariantList())
+    FakeRunner(const KPluginMetaData &metadata = 
KPluginMetaData(QStringLiteral("metadata.desktop")))
+        : AbstractRunner(nullptr, metadata, QVariantList())
     {
     }
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/autotests/metadatafile1.desktop 
new/krunner-5.82.0/autotests/metadatafile1.desktop
--- old/krunner-5.81.0/autotests/metadatafile1.desktop  1970-01-01 
01:00:00.000000000 +0100
+++ new/krunner-5.82.0/autotests/metadatafile1.desktop  2021-05-01 
11:45:28.000000000 +0200
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Name=DBus runner test
+X-KDE-ServiceTypes=Plasma/Runner
+Type=Service
+X-KDE-PluginInfo-EnabledByDefault=true
+X-Plasma-Runner-Unique-Results=true
+X-Plasma-Runner-Weak-Results=true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/autotests/metadatafile2.desktop 
new/krunner-5.82.0/autotests/metadatafile2.desktop
--- old/krunner-5.81.0/autotests/metadatafile2.desktop  1970-01-01 
01:00:00.000000000 +0100
+++ new/krunner-5.82.0/autotests/metadatafile2.desktop  2021-05-01 
11:45:28.000000000 +0200
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Name=DBus runner test
+X-KDE-ServiceTypes=Plasma/Runner
+Type=Service
+X-Plasma-Runner-Unique-Results=true
+X-Plasma-Runner-Weak-Results=false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/krunner-5.81.0/autotests/runnermanagersinglerunnermodetest.cpp 
new/krunner-5.82.0/autotests/runnermanagersinglerunnermodetest.cpp
--- old/krunner-5.81.0/autotests/runnermanagersinglerunnermodetest.cpp  
1970-01-01 01:00:00.000000000 +0100
+++ new/krunner-5.82.0/autotests/runnermanagersinglerunnermodetest.cpp  
2021-05-01 11:45:28.000000000 +0200
@@ -0,0 +1,133 @@
+/*
+    SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.loh...@gmx.de>
+    SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR 
LicenseRef-KDE-Accepted-GPL
+*/
+
+#include "fakerunner.h"
+#include "runnermanager.h"
+
+#include <KSharedConfig>
+#include <QAction>
+#include <QCoreApplication>
+#include <QObject>
+#include <QProcess>
+#include <QStandardPaths>
+#include <QTest>
+
+#include "abstractrunnertest.h"
+
+using namespace Plasma;
+
+class RunnerManagerSingleRunnerModeTest : public AbstractRunnerTest
+{
+    Q_OBJECT
+private Q_SLOTS:
+    void loadTwoRunners()
+    {
+        startDBusRunnerProcess({QStringLiteral("net.krunnertests.dave")});
+        startDBusRunnerProcess({QStringLiteral("net.krunnertests.multi.a1")}, 
QStringLiteral("net.krunnertests.multi.a1"));
+        qputenv("XDG_DATA_DIRS", 
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation).toLocal8Bit());
+        QCoreApplication::setLibraryPaths(QStringList());
+        initProperties();
+        auto md = 
KPluginMetaData::fromDesktopFile(QFINDTESTDATA("dbusrunnertestmulti.desktop"), 
{QStringLiteral("plasma-runner.desktop")});
+        QVERIFY(md.isValid());
+        manager->loadRunner(md);
+    }
+
+    void cleanup()
+    {
+        killRunningDBusProcesses();
+        const QString configFile = 
QStandardPaths::locate(QStandardPaths::ConfigLocation, 
"runnermanagersinglerunnermodetestrcm");
+        if (!configFile.isEmpty()) {
+            QFile::remove(configFile);
+        }
+    }
+
+    void testAllRunnerResults();
+    void testSingleRunnerResults();
+    void testNonExistentRunnerId();
+    void testLoadingDisabledRunner();
+#if KRUNNER_BUILD_DEPRECATED_SINCE(5, 81)
+    void testAdvertisedSingleRunners();
+#endif
+};
+
+void RunnerManagerSingleRunnerModeTest::testAllRunnerResults()
+{
+    loadTwoRunners();
+    launchQuery("foo");
+    const auto matches = manager->matches();
+    QCOMPARE(matches.count(), 2);
+    const QStringList ids = {matches.at(0).runner()->id(), 
matches.at(1).runner()->id()};
+    // Both runners should have produced one result
+    QVERIFY(ids.contains("dbusrunnertest"));
+    QVERIFY(ids.contains("dbusrunnertestmulti"));
+}
+
+void RunnerManagerSingleRunnerModeTest::testSingleRunnerResults()
+{
+    loadTwoRunners();
+    launchQuery("foo", "dbusrunnertest");
+    QCOMPARE(manager->matches().count(), 1);
+    QCOMPARE(manager->matches().constFirst().runner()->id(), "dbusrunnertest");
+    launchQuery("foo", "dbusrunnertestmulti");
+    QCOMPARE(manager->matches().count(), 1);
+    QCOMPARE(manager->matches().constFirst().runner()->id(), 
"dbusrunnertestmulti");
+}
+
+void RunnerManagerSingleRunnerModeTest::testNonExistentRunnerId()
+{
+    loadTwoRunners();
+    manager->launchQuery("foo", "bla"); // This internally calls reset, we 
just wait a bit and make sure there are no matches
+    QTest::qSleep(250);
+    QVERIFY(manager->matches().isEmpty());
+}
+
+void RunnerManagerSingleRunnerModeTest::testLoadingDisabledRunner()
+{
+    loadTwoRunners();
+    // Make sure the runner is disabled in the config
+    auto config = KSharedConfig::openConfig();
+    config->group("Plugins").writeEntry("dbusrunnertestEnabled", false);
+    // reset our manager to start clean
+    manager.reset(new RunnerManager());
+    // Copy the service files to the appropriate location and only load 
runners from there
+    QString location = 
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + 
"/krunner/dbusplugins/";
+    QDir().mkpath(location);
+    QFile::copy(QFINDTESTDATA("dbusrunnertest.desktop"), location + 
"dbusrunnertest.desktop");
+    QFile::copy(QFINDTESTDATA("dbusrunnertestmulti.desktop"), location + 
"dbusrunnertestmulti.desktop");
+
+    // Only enabled runner should be loaded and have results
+    launchQuery("foo");
+    QCOMPARE(manager->runners().count(), 1);
+    QCOMPARE(manager->runners().constFirst()->id(), "dbusrunnertestmulti");
+    QCOMPARE(manager->matches().count(), 1);
+    QCOMPARE(manager->matches().constFirst().runner()->id(), 
"dbusrunnertestmulti");
+
+    // Only enabled runner should be loaded and have results
+    launchQuery("foo", "dbusrunnertest");
+    QCOMPARE(manager->runners().count(), 2);
+    const QStringList ids{manager->runners().at(0)->id(), 
manager->runners().at(1)->id()};
+    QVERIFY(ids.contains("dbusrunnertestmulti"));
+    QVERIFY(ids.contains("dbusrunnertest"));
+    QCOMPARE(manager->matches().count(), 1);
+    QCOMPARE(manager->matches().constFirst().runner()->id(), "dbusrunnertest");
+
+    // Only enabled runner should used for querying
+    launchQuery("foo");
+    QCOMPARE(manager->runners().count(), 2);
+    QCOMPARE(manager->matches().count(), 1);
+    QCOMPARE(manager->matches().constFirst().runner()->id(), 
"dbusrunnertestmulti");
+}
+
+#if KRUNNER_BUILD_DEPRECATED_SINCE(5, 82)
+void RunnerManagerSingleRunnerModeTest::testAdvertisedSingleRunners()
+{
+    loadTwoRunners();
+    QCOMPARE(manager->singleModeAdvertisedRunnerIds(), 
QStringList{"dbusrunnertest"});
+}
+#endif
+
+QTEST_MAIN(RunnerManagerSingleRunnerModeTest)
+
+#include "runnermanagersinglerunnermodetest.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/autotests/runnermatchmethodstest.cpp 
new/krunner-5.82.0/autotests/runnermatchmethodstest.cpp
--- old/krunner-5.81.0/autotests/runnermatchmethodstest.cpp     2021-04-03 
11:37:00.000000000 +0200
+++ new/krunner-5.82.0/autotests/runnermatchmethodstest.cpp     2021-05-01 
11:45:28.000000000 +0200
@@ -10,6 +10,7 @@
 
 #include <QAction>
 #include <QObject>
+#include <QStandardPaths>
 #include <QTest>
 
 using namespace Plasma;
@@ -31,7 +32,7 @@
     RunnerContextMatchMethodsTest();
     ~RunnerContextMatchMethodsTest();
 
-    RunnerContext *ctx = nullptr;
+    std::unique_ptr<RunnerContext> ctx;
     FakeRunner *runner1;
     FakeRunner *runner2;
 private Q_SLOTS:
@@ -43,6 +44,7 @@
     void testRemoveMatchMulti();
     void testRemoveMatchByRunner();
 #endif
+    void testDuplicateIds();
 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 79)
     void testGetMatchById();
     void testNonExistentMatchIds();
@@ -54,6 +56,16 @@
     , runner1(new FakeRunner())
     , runner2(new FakeRunner())
 {
+    QStandardPaths::setTestModeEnabled(true);
+    const QByteArray defaultDataDirs = 
qEnvironmentVariableIsSet("XDG_DATA_DIRS") ? qgetenv("XDG_DATA_DIRS") : 
QByteArray("/usr/local:/usr");
+    const QByteArray modifiedDataDirs = 
QFile::encodeName(QCoreApplication::applicationDirPath()) + 
QByteArrayLiteral("/data:") + defaultDataDirs;
+    qputenv("XDG_DATA_DIRS", modifiedDataDirs);
+    KPluginMetaData data1 = 
KPluginMetaData::fromDesktopFile(QFINDTESTDATA("metadatafile1.desktop"));
+    KPluginMetaData data2 = 
KPluginMetaData::fromDesktopFile(QFINDTESTDATA("metadatafile2.desktop"));
+    QVERIFY(data1.isValid());
+    QVERIFY(data2.isValid());
+    runner1 = new FakeRunner(data1);
+    runner2 = new FakeRunner(data2);
 }
 
 RunnerContextMatchMethodsTest::~RunnerContextMatchMethodsTest()
@@ -64,8 +76,7 @@
 
 void RunnerContextMatchMethodsTest::init()
 {
-    delete ctx;
-    ctx = new RunnerContext();
+    ctx.reset(new RunnerContext());
 }
 
 void RunnerContextMatchMethodsTest::testAdd()
@@ -141,7 +152,7 @@
     QCOMPARE(ctx->matches().count(), 3);
     QCOMPARE(ctx->match(m1.id()), m1);
     // ID gets internally concatenated with runner id
-    QCOMPARE(ctx->match(QStringLiteral("metadata_m1")), m1);
+    QCOMPARE(ctx->match(QStringLiteral("m1")), m1);
 }
 #endif
 
@@ -158,6 +169,29 @@
     QVERIFY(!ctx->match(QStringLiteral("does_not_exist")).isValid());
     QCOMPARE(ctx->match(QStringLiteral("does_not_exist")).runner(), nullptr);
 }
+
+void RunnerContextMatchMethodsTest::testDuplicateIds()
+{
+    const QueryMatch match1 = createMatch(QStringLiteral("id1"), runner1);
+    QVERIFY(ctx->addMatch(match1));
+    const QueryMatch match2 = createMatch(QStringLiteral("id1"), runner2);
+    QVERIFY(ctx->addMatch(match2));
+    const QueryMatch match3 = createMatch(QStringLiteral("id2"), runner1);
+    QVERIFY(ctx->addMatch(match3));
+    const QueryMatch match4 = createMatch(QStringLiteral("id3"), runner2);
+    QVERIFY(ctx->addMatch(match4));
+    const QueryMatch match5 = createMatch(QStringLiteral("id3"), runner2);
+    QVERIFY(ctx->addMatch(match5));
+
+    const QList<QueryMatch> matches = ctx->matches();
+    QCOMPARE(matches.size(), 3);
+    // match2 should have replaced match1
+    QCOMPARE(matches.at(0), match2);
+    QCOMPARE(matches.at(1), match3);
+    // match4 should not have been replaced, the runner does not have the weak 
property set
+    QCOMPARE(matches.at(2), match4);
+}
+
 #endif
 
 QTEST_MAIN(RunnerContextMatchMethodsTest)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/CMakeLists.txt 
new/krunner-5.82.0/src/CMakeLists.txt
--- old/krunner-5.81.0/src/CMakeLists.txt       2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/CMakeLists.txt       2021-05-01 11:45:28.000000000 
+0200
@@ -35,7 +35,7 @@
     GROUP_BASE_NAME KF
     VERSION ${KF_VERSION}
     DEPRECATED_BASE_VERSION 0
-    DEPRECATION_VERSIONS 5.28 5.71 5.72 5.73 5.76 5.77 5.79 5.81
+    DEPRECATION_VERSIONS 5.28 5.71 5.72 5.73 5.76 5.77 5.79 5.81 5.82
     EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
 )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/abstractrunner.cpp 
new/krunner-5.82.0/src/abstractrunner.cpp
--- old/krunner-5.81.0/src/abstractrunner.cpp   2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/abstractrunner.cpp   2021-05-01 11:45:28.000000000 
+0200
@@ -112,6 +112,16 @@
     d->syntaxes.append(syntax);
 }
 
+bool AbstractRunner::hasUniqueResults()
+{
+    return d->hasUniqueResults;
+}
+
+bool AbstractRunner::hasWeakResults()
+{
+    return d->hasWeakResults;
+}
+
 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 76)
 void AbstractRunner::setDefaultSyntax(const RunnerSyntax &syntax)
 {
@@ -475,6 +485,8 @@
             matchRegex = 
QRegularExpression(rawData.value(QStringLiteral("X-Plasma-Runner-Match-Regex")).toString());
             hasMatchRegex = matchRegex.isValid() && 
!matchRegex.pattern().isEmpty();
         }
+        hasUniqueResults = 
rawData.value(QStringLiteral("X-Plasma-Runner-Unique-Results")).toBool();
+        hasWeakResults = 
rawData.value(QStringLiteral("X-Plasma-Runner-Weak-Results")).toBool();
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/abstractrunner.h 
new/krunner-5.82.0/src/abstractrunner.h
--- old/krunner-5.81.0/src/abstractrunner.h     2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/abstractrunner.h     2021-05-01 11:45:28.000000000 
+0200
@@ -641,6 +641,11 @@
 
 private:
     AbstractRunnerPrivate *const d;
+    bool hasUniqueResults();
+    bool hasWeakResults();
+    friend class RunnerContext;
+    friend class RunnerContextPrivate;
+    friend class QueryMatch;
 };
 
 } // Plasma namespace
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/abstractrunner_p.h 
new/krunner-5.82.0/src/abstractrunner_p.h
--- old/krunner-5.81.0/src/abstractrunner_p.h   2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/abstractrunner_p.h   2021-05-01 11:45:28.000000000 
+0200
@@ -53,6 +53,8 @@
     int minLetterCount = 0;
     QRegularExpression matchRegex;
     bool hasMatchRegex = false;
+    bool hasUniqueResults = false;
+    bool hasWeakResults = false;
 };
 
 } // namespace Plasma
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/data/org.kde.krunner1.xml 
new/krunner-5.82.0/src/data/org.kde.krunner1.xml
--- old/krunner-5.81.0/src/data/org.kde.krunner1.xml    2021-04-03 
11:37:00.000000000 +0200
+++ new/krunner-5.82.0/src/data/org.kde.krunner1.xml    2021-05-01 
11:45:28.000000000 +0200
@@ -59,7 +59,7 @@
               has alpha, bits per sample, number of channels, pixmap data.
       -->
       <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" 
value="RemoteMatches"/>
-      <arg name="matches" type="a(sssuda{sv})" direction="out"/>
+      <arg name="matches" type="a(sssida{sv})" direction="out"/>
     </method>
   </interface>
 </node>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/krunner-5.81.0/src/data/servicetypes/plasma-runner.desktop 
new/krunner-5.82.0/src/data/servicetypes/plasma-runner.desktop
--- old/krunner-5.81.0/src/data/servicetypes/plasma-runner.desktop      
2021-04-03 11:37:00.000000000 +0200
+++ new/krunner-5.82.0/src/data/servicetypes/plasma-runner.desktop      
2021-05-01 11:45:28.000000000 +0200
@@ -95,3 +95,12 @@
 # In case both the regex and the letter count is set the letter count is 
checked first
 [PropertyDef::X-Plasma-Runner-Match-Regex]
 Type=QString
+
+# If this property is set to true the RunnerContext will check if a match with 
the same Id already exists
+# if yes it is not added. This also removed the <runnername>_ prefix from the 
match id.
+[PropertyDef::X-Plasma-Runner-Unique-Results]
+Type=bool
+
+# If a runner has produced a match with the same id the match will be removed 
in favor of the other runner's match
+[PropertyDef::X-Plasma-Runner-Weak-Results]
+Type=bool
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/dbusrunner.cpp 
new/krunner-5.82.0/src/dbusrunner.cpp
--- old/krunner-5.81.0/src/dbusrunner.cpp       2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/dbusrunner.cpp       2021-05-01 11:45:28.000000000 
+0200
@@ -34,6 +34,7 @@
 
     QString requestedServiceName = 
pluginMetaData.value(QStringLiteral("X-Plasma-DBusRunner-Service"));
     m_path = pluginMetaData.value(QStringLiteral("X-Plasma-DBusRunner-Path"));
+    m_hasUniqueResults = 
pluginMetaData.rawData().value(QStringLiteral("X-Plasma-Runner-Unique-Results")).toBool();
 
     if (requestedServiceName.isEmpty() || m_path.isEmpty()) {
         qCWarning(KRUNNER) << "Invalid entry:" << pluginMetaData.name();
@@ -156,7 +157,6 @@
                     Plasma::QueryMatch m(this);
 
                     m.setText(match.text);
-                    m.setId(match.id);
                     m.setIconName(match.iconName);
                     m.setType(match.type);
                     m.setRelevance(match.relevance);
@@ -170,6 +170,7 @@
                     } else {
                         m.setData(QVariantList({service}));
                     }
+                    m.setId(match.id);
 
                     const QVariant iconData = 
match.properties.value(QStringLiteral("icon-data"));
                     if (iconData.isValid()) {
@@ -224,7 +225,12 @@
     Q_UNUSED(context);
 
     QString actionId;
-    const QString matchId = match.id().mid(id().length() + 1); // 
QueryMatch::setId mangles the match ID with runnerID + '_'. This unmangles it
+    QString matchId;
+    if (m_hasUniqueResults) {
+        matchId = match.id();
+    } else {
+        matchId = match.id().mid(id().length() + 1); // QueryMatch::setId 
mangles the match ID with runnerID + '_'. This unmangles it
+    }
     const QString service = match.data().toList().constFirst().toString();
 
     if (match.selectedAction()) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/dbusrunner_p.h 
new/krunner-5.82.0/src/dbusrunner_p.h
--- old/krunner-5.81.0/src/dbusrunner_p.h       2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/dbusrunner_p.h       2021-05-01 11:45:28.000000000 
+0200
@@ -35,4 +35,5 @@
     QString m_path;
     QSet<QString> m_matchingServices;
     QHash<QString, QList<QAction *>> m_actions;
+    bool m_hasUniqueResults = false;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/dbusutils_p.h 
new/krunner-5.82.0/src/dbusutils_p.h
--- old/krunner-5.81.0/src/dbusutils_p.h        2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/dbusutils_p.h        2021-05-01 11:45:28.000000000 
+0200
@@ -56,7 +56,7 @@
     argument >> match.id;
     argument >> match.text;
     argument >> match.iconName;
-    uint type;
+    int type;
     argument >> type;
     match.type = static_cast<Plasma::QueryMatch::Type>(type);
     argument >> match.relevance;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/querymatch.cpp 
new/krunner-5.82.0/src/querymatch.cpp
--- old/krunner-5.81.0/src/querymatch.cpp       2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/querymatch.cpp       2021-05-01 11:45:28.000000000 
+0200
@@ -23,19 +23,12 @@
 public:
     QueryMatchPrivate(AbstractRunner *r)
         : QSharedData()
-        , lock(new QReadWriteLock(QReadWriteLock::Recursive))
         , runner(r)
-        , type(QueryMatch::ExactMatch)
-        , relevance(.7)
-        , selAction(nullptr)
-        , enabled(true)
-        , idSetByData(false)
     {
     }
 
     QueryMatchPrivate(const QueryMatchPrivate &other)
         : QSharedData(other)
-        , lock(new QReadWriteLock(QReadWriteLock::Recursive))
     {
         QReadLocker l(other.lock);
         runner = other.runner;
@@ -51,9 +44,12 @@
         icon = other.icon;
         iconName = other.iconName;
         data = other.data;
+#if KRUNNER_BUILD_DEPRECATED_SINCE(5, 82)
         mimeType = other.mimeType;
+#endif
         urls = other.urls;
         actions = other.actions;
+        multiLine = other.multiLine;
     }
 
     ~QueryMatchPrivate()
@@ -61,9 +57,9 @@
         delete lock;
     }
 
-    QReadWriteLock *lock;
+    QReadWriteLock *lock = new QReadWriteLock(QReadWriteLock::Recursive);
     QPointer<AbstractRunner> runner;
-    QueryMatch::Type type;
+    QueryMatch::Type type = QueryMatch::ExactMatch;
     QString matchCategory;
     QString id;
     QString text;
@@ -73,11 +69,12 @@
     QIcon icon;
     QString iconName;
     QVariant data;
-    qreal relevance;
-    QAction *selAction;
-    bool enabled : 1;
-    bool idSetByData : 1;
+    qreal relevance = .7;
+    QAction *selAction = nullptr;
+    bool enabled = true;
+    bool idSetByData = false;
     QList<QAction *> actions;
+    bool multiLine = false;
 };
 
 QueryMatch::QueryMatch(AbstractRunner *runner)
@@ -175,14 +172,16 @@
 void QueryMatch::setId(const QString &id)
 {
     QWriteLocker locker(d->lock);
-    if (d->runner) {
-        d->id = d->runner.data()->id();
-    }
-
-    if (!id.isEmpty()) {
-        d->id.append(QLatin1Char('_')).append(id);
+    if (d->runner && d->runner->hasUniqueResults()) {
+        d->id = id;
+    } else {
+        if (d->runner) {
+            d->id = d->runner.data()->id();
+        }
+        if (!id.isEmpty()) {
+            d->id.append(QLatin1Char('_')).append(id);
+        }
     }
-
     d->idSetByData = false;
 }
 
@@ -228,6 +227,7 @@
     return d->iconName;
 }
 
+#if KRUNNER_BUILD_DEPRECATED_SINCE(5, 82)
 void QueryMatch::setMimeType(const QString &mimeType)
 {
     QWriteLocker locker(d->lock);
@@ -239,6 +239,7 @@
     QReadLocker locker(d->lock);
     return d->mimeType;
 }
+#endif
 
 void QueryMatch::setUrls(const QList<QUrl> &urls)
 {
@@ -293,6 +294,16 @@
     return d->type < other.d->type;
 }
 
+void QueryMatch::setMultiLine(bool multiLine)
+{
+    d->multiLine = multiLine;
+}
+
+bool QueryMatch::isMultiLine() const
+{
+    return d->multiLine;
+}
+
 QueryMatch &QueryMatch::operator=(const QueryMatch &other)
 {
     if (d != other.d) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/querymatch.h 
new/krunner-5.82.0/src/querymatch.h
--- old/krunner-5.81.0/src/querymatch.h 2021-04-03 11:37:00.000000000 +0200
+++ new/krunner-5.82.0/src/querymatch.h 2021-05-01 11:45:28.000000000 +0200
@@ -230,17 +230,23 @@
      */
     QString iconName() const;
 
+#if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 82)
     /**
      * Sets the MimeType, if any, associated with this match.
      * This overrides the MimeType provided by QueryContext, and should only be
      * set when it is different from the QueryContext MimeType
+     * @deprecated Since 5.82, deprecated for lack of usage
      */
+    KRUNNER_DEPRECATED_VERSION(5, 82, "deprecated for lack of usage")
     void setMimeType(const QString &mimeType);
 
     /**
      * @return the mimtype for this match, or QString() is none
+     * @deprecated Since 5.82, deprecated for lack of usage
      */
+    KRUNNER_DEPRECATED_VERSION(5, 82, "deprecated for lack of usage")
     QString mimeType() const;
+#endif
 
     /**
      * Sets the urls, if any, associated with this match
@@ -296,6 +302,21 @@
      */
     void setSelectedAction(QAction *action);
 
+    /**
+     * Set if the text should be displayed as a multiLine string
+     * @param multiLine
+     * @since 5.82
+     */
+    void setMultiLine(bool multiLine);
+
+    /**
+     * If the text should be displayed as a multiLine string
+     * If no explicit value is set set using setMultiline it will default to 
false
+     * @return bool
+     * @since 5.82
+     */
+    bool isMultiLine() const;
+
 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 71)
     /**
      * @return true if this match can be configured before being run
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/runnercontext.cpp 
new/krunner-5.82.0/src/runnercontext.cpp
--- old/krunner-5.81.0/src/runnercontext.cpp    2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/runnercontext.cpp    2021-05-01 11:45:28.000000000 
+0200
@@ -39,7 +39,6 @@
         : QSharedData()
         , type(RunnerContext::UnknownType)
         , q(context)
-        , singleRunnerQueryMode(false)
     {
     }
 
@@ -48,7 +47,6 @@
         , launchCounts(p.launchCounts)
         , type(RunnerContext::None)
         , q(p.q)
-        , singleRunnerQueryMode(false)
     {
     }
 
@@ -142,6 +140,27 @@
     }
 #endif
 
+    void addMatch(const QueryMatch &match)
+    {
+        if (match.runner() && match.runner()->hasUniqueResults()) {
+            if (uniqueIds.contains(match.id())) {
+                const QueryMatch &existentMatch = uniqueIds.value(match.id());
+                if (existentMatch.runner() && 
existentMatch.runner()->hasWeakResults()) {
+                    // There is an existing match with the same ID and we are 
allowed to replace it
+                    matches.removeOne(existentMatch);
+                    matches.append(match);
+                }
+            } else {
+                // There is no existing match with the same id
+                uniqueIds.insert(match.id(), match);
+                matches.append(match);
+            }
+        } else {
+            // Runner has the unique results property not set
+            matches.append(match);
+        }
+    }
+
     QReadWriteLock lock;
     QList<QueryMatch> matches;
     QHash<QString, int> launchCounts;
@@ -151,7 +170,8 @@
     RunnerContext::Type type;
     RunnerContext *q;
     static RunnerContext s_dummyContext;
-    bool singleRunnerQueryMode;
+    bool singleRunnerQueryMode = false;
+    QMap<QString, QueryMatch> uniqueIds;
 };
 
 RunnerContext RunnerContextPrivate::s_dummyContext;
@@ -218,6 +238,7 @@
 
     d->term.clear();
     d->mimeType.clear();
+    d->uniqueIds.clear();
     d->type = UnknownType;
     d->singleRunnerQueryMode = false;
 }
@@ -295,8 +316,7 @@
         if (int count = d->launchCounts.value(match.id())) {
             match.setRelevance(match.relevance() + 0.5 * (1 - exp(-count * 
0.3)));
         }
-
-        d->matches.append(match);
+        d->addMatch(match);
     }
     UNLOCK(d);
     // A copied searchContext may share the d pointer,
@@ -321,8 +341,7 @@
     if (int count = d->launchCounts.value(m.id())) {
         m.setRelevance(m.relevance() + 0.05 * count);
     }
-
-    d->matches.append(m);
+    d->addMatch(match);
     UNLOCK(d);
     Q_EMIT d->q->matchesChanged();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/runnercontext.h 
new/krunner-5.82.0/src/runnercontext.h
--- old/krunner-5.81.0/src/runnercontext.h      2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/runnercontext.h      2021-05-01 11:45:28.000000000 
+0200
@@ -234,8 +234,10 @@
     /**
      * Sets single runner query mode. Note that a call to reset() will
      * turn off single runner query mode.
+     * TODO KF6 Make private
      *
      * @see reset()
+     * @internal
      * @since 4.4
      */
     void setSingleRunnerQueryMode(bool enabled);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/runnermanager.cpp 
new/krunner-5.82.0/src/runnermanager.cpp
--- old/krunner-5.81.0/src/runnermanager.cpp    2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/runnermanager.cpp    2021-05-01 11:45:28.000000000 
+0200
@@ -84,13 +84,6 @@
 public:
     RunnerManagerPrivate(RunnerManager *parent)
         : q(parent)
-        , deferredRun(nullptr)
-        , currentSingleRunner(nullptr)
-        , prepped(false)
-        , allRunnersPrepped(false)
-        , singleRunnerPrepped(false)
-        , teardownRequested(false)
-        , singleMode(false)
     {
         matchChangeTimer.setSingleShot(true);
         delayTimer.setSingleShot(true);
@@ -163,13 +156,16 @@
         if (currentSingleRunner && currentSingleRunner->id() == 
singleModeRunnerId) {
             return;
         }
-        if (runners.isEmpty()) {
-            loadRunners();
-        }
         currentSingleRunner = q->runner(singleModeRunnerId);
+        // If there are no runners loaded or the single runner could no be 
loaded,
+        // this is the case if it was disabled but gets queries using the 
singleRunnerMode, BUG: 435050
+        if (runners.isEmpty() || !currentSingleRunner) {
+            loadRunners(singleModeRunnerId);
+            currentSingleRunner = q->runner(singleModeRunnerId);
+        }
     }
 
-    void loadRunners()
+    void loadRunners(const QString &singleRunnerId = QString())
     {
         QVector<KPluginMetaData> offers = RunnerManager::runnerMetaDataList();
 
@@ -177,9 +173,6 @@
         const bool noWhiteList = whiteList.isEmpty();
         KConfigGroup pluginConf = configPrt->group("Plugins");
 
-        advertiseSingleRunnerIds.clear();
-
-        QStringList allCategories;
         QSet<AbstractRunner *> deadRunners;
         QMutableVectorIterator<KPluginMetaData> it(offers);
         while (it.hasNext()) {
@@ -195,12 +188,10 @@
             const QString runnerName = description.pluginId();
             const bool isPluginEnabled = pluginConf.readEntry(runnerName + 
QLatin1String("Enabled"), description.isEnabledByDefault());
             const bool loaded = runners.contains(runnerName);
-            const bool selected = loadAll || (isPluginEnabled && (noWhiteList 
|| whiteList.contains(runnerName)));
-
-            const bool singleQueryModeEnabled = 
description.rawData().value(QStringLiteral("X-Plasma-AdvertiseSingleRunnerQueryMode")).toVariant().toBool();
-
-            if (singleQueryModeEnabled) {
-                advertiseSingleRunnerIds.insert(runnerName, 
description.name());
+            bool selected = loadAll || disabledRunnerIds.contains(runnerName) 
|| (isPluginEnabled && (noWhiteList || whiteList.contains(runnerName)));
+            if (!selected && runnerName == singleRunnerId) {
+                selected = true;
+                disabledRunnerIds << runnerName;
             }
 
             if (selected) {
@@ -215,7 +206,6 @@
                     bool allCategoriesDisabled = true;
 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 76)
                     const QStringList categories = runner->categories();
-                    allCategories << categories;
 
                     for (const QString &cat : categories) {
                         if (enabledCategories.contains(cat)) {
@@ -241,10 +231,6 @@
             }
         }
 
-        if (enabledCategories.isEmpty()) {
-            enabledCategories = allCategories;
-        }
-
         if (!deadRunners.isEmpty()) {
             QSet<QSharedPointer<FindMatchesJob>> deadJobs;
             auto it = searchJobs.begin();
@@ -343,12 +329,6 @@
             return;
         }
 
-        if (deferredRun.isEnabled() && runJob->runner() == 
deferredRun.runner()) {
-            QueryMatch tmpRun = deferredRun;
-            deferredRun = QueryMatch(nullptr);
-            tmpRun.run(context);
-        }
-
         searchJobs.remove(runJob);
         oldSearchJobs.remove(runJob);
 
@@ -505,34 +485,32 @@
     static const int slowRunDelay = 400;
 
     RunnerManager *const q;
-    QueryMatch deferredRun;
     RunnerContext context;
     QTimer matchChangeTimer;
     QTimer delayTimer; // Timer to control when to run slow runners
     QElapsedTimer lastMatchChangeSignalled;
     QHash<QString, AbstractRunner *> runners;
-    QHash<QString, QString> advertiseSingleRunnerIds;
-    AbstractRunner *currentSingleRunner;
+    AbstractRunner *currentSingleRunner = nullptr;
     QSet<QSharedPointer<FindMatchesJob>> searchJobs;
     QSet<QSharedPointer<FindMatchesJob>> oldSearchJobs;
     QStringList enabledCategories;
     QString singleModeRunnerId;
-    bool prepped : 1;
-    bool allRunnersPrepped : 1;
-    bool singleRunnerPrepped : 1;
-    bool teardownRequested : 1;
-    bool singleMode : 1;
-    bool activityAware : 1;
-    bool historyEnabled : 1;
-    bool retainPriorSearch : 1;
+    bool prepped = false;
+    bool allRunnersPrepped = false;
+    bool singleRunnerPrepped = false;
+    bool teardownRequested = false;
+    bool singleMode = false;
+    bool activityAware = false;
+    bool historyEnabled = false;
+    bool retainPriorSearch = false;
     QStringList whiteList;
-    QString configFile;
     KConfigWatcher::Ptr watcher;
     QHash<QString, QString> priorSearch;
     QString untrimmedTerm;
     QString nulluuid = QStringLiteral("00000000-0000-0000-0000-000000000000");
     KSharedConfigPtr configPrt;
     KConfigGroup stateData;
+    QSet<QString> disabledRunnerIds; // Runners that are disabled but were 
loaded as single runners
 #ifdef HAVE_KACTIVITIES
     const KActivities::Consumer activitiesConsumer;
 #endif
@@ -675,6 +653,7 @@
     return d->runners.value(name, nullptr);
 }
 
+#if KRUNNER_BUILD_DEPRECATED_SINCE(5, 82)
 AbstractRunner *RunnerManager::singleModeRunner() const
 {
     return d->currentSingleRunner;
@@ -718,23 +697,26 @@
     }
 }
 
-QList<AbstractRunner *> RunnerManager::runners() const
+QStringList RunnerManager::singleModeAdvertisedRunnerIds() const
 {
-    return d->runners.values();
+    QStringList advertiseSingleRunnerIds;
+    for (auto *runner : qAsConst(d->runners)) {
+        if 
(runner->metadata(RunnerReturnPluginMetaData).rawData().value(QStringLiteral("X-Plasma-AdvertiseSingleRunnerQueryMode")).toVariant().toBool())
 {
+            advertiseSingleRunnerIds << runner->id();
+        }
+    }
+    return advertiseSingleRunnerIds;
 }
 
-QStringList RunnerManager::singleModeAdvertisedRunnerIds() const
+QString RunnerManager::runnerName(const QString &id) const
 {
-    return d->advertiseSingleRunnerIds.keys();
+    return d->runners.contains(id) ? d->runners.value(id)->name() : QString();
 }
+#endif
 
-QString RunnerManager::runnerName(const QString &id) const
+QList<AbstractRunner *> RunnerManager::runners() const
 {
-    if (runner(id)) {
-        return runner(id)->name();
-    } else {
-        return d->advertiseSingleRunnerIds.value(id, QString());
-    }
+    return d->runners.values();
 }
 
 RunnerContext *RunnerManager::searchContext() const
@@ -757,25 +739,9 @@
 
 void RunnerManager::run(const QueryMatch &match)
 {
-    if (!match.isEnabled()) {
-        return;
-    }
-
-    // TODO: this function is not const as it may be used for learning
-    AbstractRunner *runner = match.runner();
-
-    for (auto it = d->searchJobs.constBegin(); it != d->searchJobs.constEnd(); 
++it) {
-        if ((*it)->runner() == runner && !(*it)->isFinished()) {
-            d->deferredRun = match;
-            return;
-        }
-    }
-
-    if (d->deferredRun.isValid()) {
-        d->deferredRun = QueryMatch(nullptr);
+    if (match.isEnabled()) {
+        d->context.run(match);
     }
-
-    d->context.run(match);
 }
 
 bool RunnerManager::runMatch(const QueryMatch &match)
@@ -880,7 +846,9 @@
         }
     } else {
         for (AbstractRunner *runner : qAsConst(d->runners)) {
-            Q_EMIT runner->prepare();
+            if (!d->disabledRunnerIds.contains(runner->name())) {
+                Q_EMIT runner->prepare();
+            }
         }
 
         d->allRunnersPrepped = true;
@@ -909,16 +877,20 @@
 {
     setupMatchSession();
     QString term = untrimmedTerm.trimmed();
+    const QString prevSingleRunner = d->singleModeRunnerId;
     d->untrimmedTerm = untrimmedTerm;
 
-    setSingleModeRunnerId(runnerName);
-    setSingleMode(d->currentSingleRunner);
+    // Set the required values and load the runner
+    d->singleModeRunnerId = runnerName;
+    d->singleMode = !runnerName.isEmpty();
+    d->loadSingleRunner();
+    // If we could not load the single runner we reset
     if (!runnerName.isEmpty() && !d->currentSingleRunner) {
         reset();
         return;
     }
 
-    if (d->context.query() == term) {
+    if (d->context.query() == term && prevSingleRunner == runnerName) {
         // we already are searching for this!
         return;
     }
@@ -948,6 +920,10 @@
         if (r->isMatchingSuspended()) {
             continue;
         }
+        // If this runner is loaded but disabled
+        if (!d->singleMode && d->disabledRunnerIds.contains(r->id())) {
+            continue;
+        }
         // The runners can set the min letter count as a property, this way we 
don't
         // have to spawn threads just for the runner to reject the query, 
because it is too short
         if (!d->singleMode && queryLetterCount < r->minLetterCount()) {
@@ -1017,12 +993,6 @@
 
     d->searchJobs.clear();
 
-    if (d->deferredRun.isEnabled()) {
-        QueryMatch tmpRun = d->deferredRun;
-        d->deferredRun = QueryMatch(nullptr);
-        tmpRun.run(d->context);
-    }
-
     d->context.reset();
     Q_EMIT queryFinished();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/src/runnermanager.h 
new/krunner-5.82.0/src/runnermanager.h
--- old/krunner-5.81.0/src/runnermanager.h      2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/src/runnermanager.h      2021-05-01 11:45:28.000000000 
+0200
@@ -61,10 +61,15 @@
      */
     AbstractRunner *runner(const QString &pluginName) const;
 
+#if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 82)
     /**
      * @return the currently active "single mode" runner, or null if none
      * @since 4.4
+     * @deprecated Since 5.81, the dedicated singleRunnerMode methods are 
deprecated, use runner(const QString &pluginName) with the singleRunnerId 
instead"
      */
+    KRUNNER_DEPRECATED_VERSION(5,
+                               82,
+                               "The dedicated singleRunnerMode methods are 
deprecated, use runner(const QString &pluginName) with the singleRunnerId 
instead")
     AbstractRunner *singleModeRunner() const;
 
     /**
@@ -74,19 +79,30 @@
      * will return NULL
      * @param id the id of the runner to use
      * @since 4.4
+     * @deprecated Since 5.82, the dedicated singleRunnerMode methods are 
deprecated, pass in the singleModeRunnerId into the launchQuery overload instead
      */
+    KRUNNER_DEPRECATED_VERSION(5,
+                               82,
+                               "The dedicated singleRunnerMode methods are 
deprecated, pass in the singleModeRunnerId into the launchQuery overload 
instead")
     void setSingleModeRunnerId(const QString &id);
 
     /**
      * @return the id of the runner to use in single mode
      * @since 4.4
+     * @deprecated Since 5.82, the dedicated singleRunnerMode methods are 
deprecated, use runner(const QString &pluginName) with the singleRunnerId 
instead
      */
+    KRUNNER_DEPRECATED_VERSION(5, 82, "The dedicated singleRunnerMode methods 
are deprecated, save the variable before using it in launchQuery() instead")
     QString singleModeRunnerId() const;
 
     /**
      * @return true if the manager is set to run in single runner mode
      * @since 4.4
+     * @deprecated Since 5.82, the dedicated singleRunnerMode methods are 
deprecated, call the RunnerContext::singleRunnerQueryMode on the searchContext 
instead
      */
+    KRUNNER_DEPRECATED_VERSION(
+        5,
+        82,
+        "The dedicated singleRunnerMode methods are deprecated, call the 
RunnerContext::singleRunnerQueryMode on the searchContext instead")
     bool singleMode() const;
 
     /**
@@ -94,16 +110,33 @@
      *
      * @param singleMode true if the manager should be in single mode, false 
otherwise
      * @since 4.4
+     * @deprecated Since 5.82, the dedicated singleRunnerMode methods are 
deprecated, the single mode is set to true when launchQuery is called with a non
+     * empty and existing runnerId
      */
+    KRUNNER_DEPRECATED_VERSION(5,
+                               82,
+                               "The dedicated singleRunnerMode methods are 
deprecated, the single mode is set to true when launchQuery is called with a 
non "
+                               "empty and existing runnerId")
     void setSingleMode(bool singleMode);
 
     /**
+     * @return the names of all runners that advertise single query mode
+     * @since 4.4
+     * @deprecated Since 5.81, filter the runners manually using the 
X-Plasma-AdvertiseSingleRunnerQueryMode of the metadata
+     */
+    KRUNNER_DEPRECATED_VERSION(5, 81, "filter the runners manually using the 
X-Plasma-AdvertiseSingleRunnerQueryMode of the metadata")
+    QStringList singleModeAdvertisedRunnerIds() const;
+
+    /**
      * Returns the translated name of a runner
      * @param id the id of the runner
      *
      * @since 4.4
+     * @deprecated Since 5.81, call runner(const QString &id) and fetch the 
name from the returned object instead
      */
+    KRUNNER_DEPRECATED_VERSION(5, 81, "call runner(const QString &id) and 
fetch the name from the returned object instead")
     QString runnerName(const QString &id) const;
+#endif
 
     /**
      * @return the list of all currently loaded runners
@@ -111,12 +144,6 @@
     QList<AbstractRunner *> runners() const;
 
     /**
-     * @return the names of all runners that advertise single query mode
-     * @since 4.4
-     */
-    QStringList singleModeAdvertisedRunnerIds() const;
-
-    /**
      * Retrieves the current context
      * @return pointer to the current context
      */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/tests/CMakeLists.txt 
new/krunner-5.82.0/tests/CMakeLists.txt
--- old/krunner-5.81.0/tests/CMakeLists.txt     2021-04-03 11:37:00.000000000 
+0200
+++ new/krunner-5.82.0/tests/CMakeLists.txt     1970-01-01 01:00:00.000000000 
+0100
@@ -1,3 +0,0 @@
-add_executable(runnermodeltest runnermodeltest.cpp 
../src/declarative/runnermodel.cpp)
-target_link_libraries(runnermodeltest Qt5::Widgets KF5::Service KF5Runner)
-ecm_mark_as_test(runnermodeltest)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/krunner-5.81.0/tests/runnermodeltest.cpp 
new/krunner-5.82.0/tests/runnermodeltest.cpp
--- old/krunner-5.81.0/tests/runnermodeltest.cpp        2021-04-03 
11:37:00.000000000 +0200
+++ new/krunner-5.82.0/tests/runnermodeltest.cpp        1970-01-01 
01:00:00.000000000 +0100
@@ -1,34 +0,0 @@
-#include <QAction>
-#include <QApplication>
-#include <QLineEdit>
-#include <QTreeView>
-#include <QVBoxLayout>
-
-#include "declarative/runnermodel.h"
-// #include "modeltest.h"
-
-int main(int argc, char *argv[])
-{
-    QApplication app(argc, argv);
-    QWidget *widget = new QWidget;
-    QVBoxLayout *layout = new QVBoxLayout(widget);
-
-    RunnerModel *runnerModel = new RunnerModel(widget);
-    //     new ModelTest(runnerModel, widget);
-
-    QLineEdit *input = new QLineEdit(widget);
-    QObject::connect(input, &QLineEdit::textChanged, runnerModel, 
&RunnerModel::scheduleQuery);
-    layout->addWidget(input);
-
-    QTreeView *view = new QTreeView(widget);
-    view->setModel(runnerModel);
-    layout->addWidget(view);
-
-    QAction *quit = new QAction(widget);
-    quit->setShortcut(Qt::CTRL | Qt::Key_Q);
-    QObject::connect(quit, SIGNAL(triggered()), &app, SLOT(quit()));
-
-    widget->addAction(quit);
-    widget->show();
-    return app.exec();
-}

Reply via email to