From 18d14446bff0b98f8dcba72c4fa72dd8e17d956b Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 16 Dec 2023 20:34:46 -0500 Subject: [PATCH] Prevent collision between KUnifiedPush DBus and KRunner DBus These share the same D-Bus service name (org.kde.neochat) which comes with a fun little addition: KRunner activation! While this is not a problem while NeoChat is running - since it's already registered - this becomes an issue while searching for NeoChat in something like the Kickoff. The Kickoff (and consequently, KRunner) tries to activate the NeoChat D-Bus service which runs our unified push parts. This introduces a "FakeRunner" which watches closely for calls to the KRunner interface while we're in unified push mode (or directly called from D-Bus but not running) so it quits immediately. (cherry picked from commit 35b08d085ce754dd09d7fb9e0a43572982204442) --- src/CMakeLists.txt | 4 ++++ src/fakerunner.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/fakerunner.h | 31 +++++++++++++++++++++++++++++++ src/main.cpp | 13 +++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 src/fakerunner.cpp create mode 100644 src/fakerunner.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9435de305..bd456a24e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -365,6 +365,10 @@ if (NOT ANDROID AND NOT WIN32 AND NOT APPLE) target_compile_definitions(neochat PUBLIC -DHAVE_RUNNER) target_compile_definitions(neochat PUBLIC -DHAVE_X11) target_sources(neochat PRIVATE runner.cpp) + + if (TARGET KUnifiedPush) + target_sources(neochat PRIVATE fakerunner.cpp) + endif() endif() target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models ${CMAKE_CURRENT_SOURCE_DIR}/enums) diff --git a/src/fakerunner.cpp b/src/fakerunner.cpp new file mode 100644 index 000000000..8d82822b8 --- /dev/null +++ b/src/fakerunner.cpp @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +#include "fakerunner.h" + +#include +#include + +Q_SCRIPTABLE RemoteActions FakeRunner::Actions() +{ + QCoreApplication::quit(); + return {}; +} + +Q_SCRIPTABLE RemoteMatches FakeRunner::Match(const QString &searchTerm) +{ + QCoreApplication::quit(); + return {}; +} + +Q_SCRIPTABLE void FakeRunner::Run(const QString &id, const QString &actionId) +{ + QCoreApplication::quit(); +} + +FakeRunner::FakeRunner() + : QObject() +{ + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); +} + +#include "moc_fakerunner.cpp" \ No newline at end of file diff --git a/src/fakerunner.h b/src/fakerunner.h new file mode 100644 index 000000000..a2454d7ca --- /dev/null +++ b/src/fakerunner.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +#pragma once + +#include + +#include "runner.h" + +/** + * This is a close-to-identical copy of the regular Runner interface, + * only used when activated for push notifications. This stubs it out so + * Plasma Search and Kickoff doesn't accidentally activate the push notification + * service. + * + * @sa Runner + */ +class FakeRunner : public QObject, protected QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.krunner1") + +public: + Q_SCRIPTABLE RemoteActions Actions(); + + Q_SCRIPTABLE RemoteMatches Match(const QString &searchTerm); + + Q_SCRIPTABLE void Run(const QString &id, const QString &actionId); + + FakeRunner(); +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d5d876f10..e9515ac97 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,6 +48,11 @@ #ifdef HAVE_RUNNER #include "runner.h" #include +#include +#endif + +#if defined(HAVE_RUNNER) && defined(HAVE_KUNIFIEDPUSH) +#include "fakerunner.h" #endif #ifdef Q_OS_WINDOWS @@ -196,6 +201,14 @@ int main(int argc, char *argv[]) // We want to be replaceable by the main client KDBusService service(KDBusService::Replace); +#ifdef HAVE_RUNNER + // If we are built with KRunner and KUnifiedPush support, we need to do something special. + // Because KRunner may call us on the D-Bus (under the same service name org.kde.neochat) then it may + // accidentally activate us for push notifications instead. If this happens, then immediately quit if the fake + // runner is called. + QDBusConnection::sessionBus().registerObject("/RoomRunner"_ls, new FakeRunner(), QDBusConnection::ExportScriptableContents); +#endif + Controller::listenForNotifications(); return QCoreApplication::exec(); }