From ad01ef1695a94e6805d57014f23b38ab70e85d40 Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Thu, 12 May 2022 03:59:56 +0200 Subject: [PATCH] Fix activating existing settings window on Wayland Add the necessary bits for XDG activation to work Move the code for launching the settings from the daemon to the respective processes so that we don't need to pass activation tokens over another process boundary --- core/CMakeLists.txt | 3 +- core/daemon.cpp | 20 -------- core/daemon.h | 2 - core/openconfig.cpp | 47 +++++++++++++++++++ core/openconfig.h | 20 ++++++++ daemon/CMakeLists.txt | 1 + daemon/kdeconnectd.cpp | 9 +++- .../kdeconnectdeclarativeplugin.cpp | 7 +++ plasmoid/package/contents/ui/main.qml | 2 +- plugins/runcommand/runcommandplugin.cpp | 4 +- settings/CMakeLists.txt | 2 +- settings/main.cpp | 3 ++ 12 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 core/openconfig.cpp create mode 100644 core/openconfig.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 021384f16..42b486d92 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -47,6 +47,7 @@ set(kdeconnectcore_SRCS device.cpp core_debug.cpp notificationserverinfo.cpp + openconfig.cpp ${debug_file_SRCS} ) @@ -66,7 +67,7 @@ PRIVATE ) if(${KF5KIO_FOUND}) - target_link_libraries(kdeconnectcore PUBLIC KF5::KIOCore) + target_link_libraries(kdeconnectcore PUBLIC KF5::KIOCore KF5::KIOGui) endif() if (BLUETOOTH_ENABLED) diff --git a/core/daemon.cpp b/core/daemon.cpp index a6ea74dd2..f9b2eb189 100644 --- a/core/daemon.cpp +++ b/core/daemon.cpp @@ -332,23 +332,3 @@ QString Daemon::selfId() const { return KdeConnectConfig::instance().deviceId(); } - -void Daemon::openConfiguration(const QString &deviceId, const QString &pluginId) -{ - QStringList args; - - QString argument; - - if (!deviceId.isEmpty()) { - args << QStringLiteral("--args"); - argument = deviceId; - - if (!pluginId.isEmpty()) { - argument += QLatin1Char(':') + pluginId; - } - - args << argument; - } - - QProcess::startDetached(QStringLiteral("kdeconnect-settings"), args); -} diff --git a/core/daemon.h b/core/daemon.h index 9c58fa7ff..409488dec 100644 --- a/core/daemon.h +++ b/core/daemon.h @@ -74,8 +74,6 @@ public Q_SLOTS: Q_SCRIPTABLE virtual void sendSimpleNotification(const QString &eventId, const QString &title, const QString &text, const QString &iconName) = 0; - Q_SCRIPTABLE void openConfiguration(const QString &deviceId = QString(), const QString &pluginId = QString()); - Q_SIGNALS: Q_SCRIPTABLE void deviceAdded(const QString& id); Q_SCRIPTABLE void deviceRemoved(const QString& id); //Note that paired devices will never be removed diff --git a/core/openconfig.cpp b/core/openconfig.cpp new file mode 100644 index 000000000..65a4f2487 --- /dev/null +++ b/core/openconfig.cpp @@ -0,0 +1,47 @@ +/** + * SPDX-FileCopyrightText: 2022 Nicolas Fella + * + * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + */ + +#include "openconfig.h" + +#include + +#if HAVE_KIO +#include +#endif + +void OpenConfig::setXdgActivationToken(const QString &token) +{ + m_currentToken = token; +} + +void OpenConfig::openConfiguration(const QString &deviceId, const QString &pluginId) +{ + QStringList args; + + QString argument; + + if (!deviceId.isEmpty()) { + args << QStringLiteral("--args"); + argument = deviceId; + + if (!pluginId.isEmpty()) { + argument += QLatin1Char(':') + pluginId; + } + + args << argument; + } + +#if HAVE_KIO + auto job = new KIO::CommandLauncherJob(QStringLiteral("kdeconnect-settings"), args); + job->setDesktopName(QStringLiteral("org.kde.kdeconnect-settings")); + job->setStartupId(m_currentToken.toUtf8()); + job->start(); +#else + QProcess::startDetached(QStringLiteral("kdeconnect-settings"), args); +#endif + + m_currentToken = QString(); +} diff --git a/core/openconfig.h b/core/openconfig.h new file mode 100644 index 000000000..e3370c703 --- /dev/null +++ b/core/openconfig.h @@ -0,0 +1,20 @@ +/** + * SPDX-FileCopyrightText: 2022 Nicolas Fella + * + * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + */ + +#include + +#include "kdeconnectcore_export.h" + +class KDECONNECTCORE_EXPORT OpenConfig : public QObject +{ + Q_OBJECT +public: + void setXdgActivationToken(const QString &token); + Q_INVOKABLE void openConfiguration(const QString &deviceId = QString(), const QString &pluginName = QString()); + +private: + QString m_currentToken; +}; diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 042305a85..844f1c1a6 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -16,6 +16,7 @@ target_link_libraries(kdeconnectd KF5::DBusAddons KF5::Notifications KF5::I18n + KF5::WindowSystem Qt5::Widgets) ecm_mark_nongui_executable(kdeconnectd) diff --git a/daemon/kdeconnectd.cpp b/daemon/kdeconnectd.cpp index fa654bce5..ec1ffc763 100644 --- a/daemon/kdeconnectd.cpp +++ b/daemon/kdeconnectd.cpp @@ -20,11 +20,13 @@ #include #include #include +#include #include #include "core/daemon.h" #include "core/device.h" +#include "core/openconfig.h" #include "core/backends/pairinghandler.h" #include "kdeconnect-version.h" #include "kdeconnectd_debug.h" @@ -54,8 +56,11 @@ public: connect(notification, &KNotification::action1Activated, device, &Device::acceptPairing); connect(notification, &KNotification::action2Activated, device, &Device::rejectPairing); QString deviceId = device->id(); - auto openSettings = [this, deviceId] { - openConfiguration(deviceId); + auto openSettings = [deviceId, notification] { + OpenConfig oc; + oc.setXdgActivationToken(notification->xdgActivationToken()); + oc.openConfiguration(deviceId); + }; connect(notification, &KNotification::action3Activated, openSettings); connect(notification, QOverload<>::of(&KNotification::activated), openSettings); diff --git a/declarativeplugin/kdeconnectdeclarativeplugin.cpp b/declarativeplugin/kdeconnectdeclarativeplugin.cpp index 188f2688c..09b214403 100644 --- a/declarativeplugin/kdeconnectdeclarativeplugin.cpp +++ b/declarativeplugin/kdeconnectdeclarativeplugin.cpp @@ -22,6 +22,7 @@ #include #include #include "core/kdeconnectpluginconfig.h" +#include "openconfig.h" #include "interfaces/commandsmodel.h" #include "pointerlocker.h" #if WITH_WAYLAND == 1 @@ -79,6 +80,12 @@ void KdeConnectDeclarativePlugin::registerTypes(const char* uri) return ret; }); + qmlRegisterSingletonType(uri, 1, 0, "OpenConfig", + [](QQmlEngine*, QJSEngine*) -> QObject* { + return new OpenConfig; + } + ); + #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) qmlRegisterAnonymousType(uri, 1); #else diff --git a/plasmoid/package/contents/ui/main.qml b/plasmoid/package/contents/ui/main.qml index a183333af..851433cab 100644 --- a/plasmoid/package/contents/ui/main.qml +++ b/plasmoid/package/contents/ui/main.qml @@ -40,7 +40,7 @@ Item Plasmoid.preferredRepresentation: isConstrained ? Plasmoid.compactRepresentation : Plasmoid.fullRepresentation function action_launchkcm() { - DaemonDbusInterface.openConfiguration() + OpenConfig.openConfiguration() } Component.onCompleted: { diff --git a/plugins/runcommand/runcommandplugin.cpp b/plugins/runcommand/runcommandplugin.cpp index 60a715f0f..cc340f791 100644 --- a/plugins/runcommand/runcommandplugin.cpp +++ b/plugins/runcommand/runcommandplugin.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "plugin_runcommand_debug.h" @@ -68,7 +69,8 @@ bool RunCommandPlugin::receivePacket(const NetworkPacket& np) #endif return true; } else if (np.has(QStringLiteral("setup"))) { - Daemon::instance()->openConfiguration(device()->id(), QStringLiteral("kdeconnect_runcommand")); + OpenConfig oc; + oc.openConfiguration(device()->id(), QStringLiteral("kdeconnect_runcommand")); } return false; diff --git a/settings/CMakeLists.txt b/settings/CMakeLists.txt index df22010fb..4f135459f 100644 --- a/settings/CMakeLists.txt +++ b/settings/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable(kdeconnect-settings ${kdeconnect_custom_icons_SRCS} ) -target_link_libraries(kdeconnect-settings kdeconnectversion KF5::I18n KF5::KCMUtils KF5::DBusAddons) +target_link_libraries(kdeconnect-settings kdeconnectversion KF5::I18n KF5::KCMUtils KF5::DBusAddons KF5::WindowSystem) install(TARGETS kdeconnect-settings ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES org.kde.kdeconnect-settings.desktop DESTINATION ${KDE_INSTALL_APPDIR}) diff --git a/settings/main.cpp b/settings/main.cpp index d072eadd3..7f9b6df14 100644 --- a/settings/main.cpp +++ b/settings/main.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "kdeconnect-version.h" int main(int argc, char** argv) @@ -47,6 +48,8 @@ int main(int argc, char** argv) dialog->show(); QObject::connect(&dbusService, &KDBusService::activateRequested, dialog, [dialog](const QStringList &args, const QString &/*workingDir*/) { + KWindowSystem::updateStartupId(dialog->windowHandle()); + KWindowSystem::activateWindow(dialog->windowHandle()); QCommandLineParser parser; parser.addOption(QCommandLineOption(QStringLiteral("args"), i18n("Arguments for the config module"), QStringLiteral("args")));