349 lines
12 KiB
Diff
349 lines
12 KiB
Diff
From 77b3ec8cf4fb9414167bb15bcc3c69b1be6c2dbf Mon Sep 17 00:00:00 2001
|
|
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
Date: Tue, 16 Sep 2025 15:52:29 +0300
|
|
Subject: [PATCH 1/2] shell: Pass an xdg activation token from DesktopView to
|
|
KRunner
|
|
|
|
This makes sure that krunner gets focused after starting to type while
|
|
a desktop view is focused when using medium or high focus stealing
|
|
prevention level.
|
|
---
|
|
krunner/dbus/org.kde.krunner.App.xml | 4 ++
|
|
krunner/view.cpp | 14 +++++++
|
|
krunner/view.h | 1 +
|
|
shell/desktopview.cpp | 61 ++++++++++++++++++++++++++--
|
|
shell/desktopview.h | 2 +
|
|
5 files changed, 79 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/krunner/dbus/org.kde.krunner.App.xml b/krunner/dbus/org.kde.krunner.App.xml
|
|
index 6553e9a1b56..e6926b1b63a 100644
|
|
--- a/krunner/dbus/org.kde.krunner.App.xml
|
|
+++ b/krunner/dbus/org.kde.krunner.App.xml
|
|
@@ -17,5 +17,9 @@
|
|
<arg name="runnerName" type="s" direction="in"/>
|
|
<arg name="term" type="s" direction="in"/>
|
|
</method>
|
|
+ <method name="queryWithActivationToken">
|
|
+ <arg name="term" type="s" direction="in"/>
|
|
+ <arg name="activationToken" type="s" direction="in"/>
|
|
+ </method>
|
|
</interface>
|
|
</node>
|
|
diff --git a/krunner/view.cpp b/krunner/view.cpp
|
|
index afefe9ab486..bb7edd5d654 100644
|
|
--- a/krunner/view.cpp
|
|
+++ b/krunner/view.cpp
|
|
@@ -263,6 +263,20 @@ void View::querySingleRunner(const QString &runnerName, const QString &term)
|
|
m_engine->rootObject()->setProperty("query", term);
|
|
}
|
|
|
|
+void View::queryWithActivationToken(const QString &term, const QString &activationToken)
|
|
+{
|
|
+ qputenv("XDG_ACTIVATION_TOKEN", activationToken.toUtf8());
|
|
+
|
|
+ if (!isVisible()) {
|
|
+ display();
|
|
+ } else {
|
|
+ requestActivate();
|
|
+ }
|
|
+
|
|
+ m_engine->rootObject()->setProperty("singleRunner", QString());
|
|
+ m_engine->rootObject()->setProperty("query", term);
|
|
+}
|
|
+
|
|
bool View::pinned() const
|
|
{
|
|
return m_pinned;
|
|
diff --git a/krunner/view.h b/krunner/view.h
|
|
index 979c6d3b483..af1d477d6f3 100644
|
|
--- a/krunner/view.h
|
|
+++ b/krunner/view.h
|
|
@@ -93,6 +93,7 @@ public Q_SLOTS:
|
|
void displayWithClipboardContents();
|
|
void query(const QString &term);
|
|
void querySingleRunner(const QString &runnerName, const QString &term);
|
|
+ void queryWithActivationToken(const QString &term, const QString &activationToken);
|
|
|
|
protected Q_SLOTS:
|
|
void loadConfig();
|
|
diff --git a/shell/desktopview.cpp b/shell/desktopview.cpp
|
|
index 36e23149272..744176e6d3e 100644
|
|
--- a/shell/desktopview.cpp
|
|
+++ b/shell/desktopview.cpp
|
|
@@ -23,6 +23,7 @@
|
|
|
|
#include <KAuthorized>
|
|
#include <KStartupInfo>
|
|
+#include <KWaylandExtras>
|
|
#include <KX11Extras>
|
|
#include <klocalizedstring.h>
|
|
#include <kwindowsystem.h>
|
|
@@ -384,11 +385,54 @@ bool DesktopView::event(QEvent *e)
|
|
{
|
|
if (e->type() == QEvent::FocusOut) {
|
|
m_krunnerText.clear();
|
|
+
|
|
+ if (!m_krunnerFuture.isCanceled()) {
|
|
+ m_krunnerFuture.cancel();
|
|
+ m_krunnerFuture = {};
|
|
+ }
|
|
}
|
|
|
|
return PlasmaQuick::ContainmentView::event(e);
|
|
}
|
|
|
|
+class ActivationTokenRequest : public QObject
|
|
+{
|
|
+ Q_OBJECT
|
|
+
|
|
+public:
|
|
+ explicit ActivationTokenRequest(QWindow *window)
|
|
+ : m_serial(KWaylandExtras::lastInputSerial(window))
|
|
+ {
|
|
+ m_promise.start();
|
|
+
|
|
+ connect(KWaylandExtras::self(), &KWaylandExtras::xdgActivationTokenArrived, this, [this](int serial, const QString &token) {
|
|
+ if (m_serial == serial) {
|
|
+ if (!m_promise.isCanceled()) {
|
|
+ m_promise.addResult(token);
|
|
+ }
|
|
+ m_promise.finish();
|
|
+ delete this;
|
|
+ }
|
|
+ });
|
|
+ KWaylandExtras::requestXdgActivationToken(window, m_serial, QString());
|
|
+ }
|
|
+
|
|
+ QFuture<QString> future() const
|
|
+ {
|
|
+ return m_promise.future();
|
|
+ }
|
|
+
|
|
+private:
|
|
+ QPromise<QString> m_promise;
|
|
+ int m_serial;
|
|
+};
|
|
+
|
|
+static QFuture<QString> fetchActivationToken(QWindow *window)
|
|
+{
|
|
+ auto request = new ActivationTokenRequest(window);
|
|
+ return request->future();
|
|
+}
|
|
+
|
|
bool DesktopView::handleKRunnerTextInput(QKeyEvent *e)
|
|
{
|
|
// allow only Shift and GroupSwitch modifiers
|
|
@@ -408,12 +452,22 @@ bool DesktopView::handleKRunnerTextInput(QKeyEvent *e)
|
|
krunnerTextChanged = true;
|
|
}
|
|
if (krunnerTextChanged) {
|
|
- const QString interface(QStringLiteral("org.kde.krunner"));
|
|
if (!KAuthorized::authorize(QStringLiteral("run_command"))) {
|
|
return false;
|
|
}
|
|
- org::kde::krunner::App krunner(interface, QStringLiteral("/App"), QDBusConnection::sessionBus());
|
|
- krunner.query(m_krunnerText);
|
|
+ if (KWindowSystem::isPlatformWayland()) {
|
|
+ if (!m_krunnerFuture.isCanceled()) {
|
|
+ m_krunnerFuture.cancel();
|
|
+ }
|
|
+ m_krunnerFuture = fetchActivationToken(this);
|
|
+ m_krunnerFuture.then(this, [this](const QString &token) {
|
|
+ org::kde::krunner::App krunner(QStringLiteral("org.kde.krunner"), QStringLiteral("/App"), QDBusConnection::sessionBus());
|
|
+ krunner.queryWithActivationToken(m_krunnerText, token);
|
|
+ });
|
|
+ } else {
|
|
+ org::kde::krunner::App krunner(QStringLiteral("org.kde.krunner"), QStringLiteral("/App"), QDBusConnection::sessionBus());
|
|
+ krunner.query(m_krunnerText);
|
|
+ }
|
|
return true;
|
|
}
|
|
return false;
|
|
@@ -596,4 +650,5 @@ void DesktopView::setAccentColorFromWallpaper(const QColor &accentColor)
|
|
QDBusConnection::sessionBus().send(applyAccentColor);
|
|
}
|
|
|
|
+#include "desktopview.moc"
|
|
#include "moc_desktopview.cpp"
|
|
diff --git a/shell/desktopview.h b/shell/desktopview.h
|
|
index c2b642d9a15..9e152611a31 100644
|
|
--- a/shell/desktopview.h
|
|
+++ b/shell/desktopview.h
|
|
@@ -10,6 +10,7 @@
|
|
|
|
#include <PlasmaQuick/ConfigView>
|
|
#include <PlasmaQuick/ContainmentView>
|
|
+#include <QFuture>
|
|
#include <QPointer>
|
|
|
|
#include <KConfigWatcher>
|
|
@@ -127,6 +128,7 @@ private:
|
|
QPointer<QScreen> m_screenToFollow;
|
|
LayerShellQt::Window *m_layerWindow = nullptr;
|
|
QString m_krunnerText;
|
|
+ QFuture<QString> m_krunnerFuture;
|
|
|
|
// KRunner config
|
|
KConfigWatcher::Ptr m_configWatcher;
|
|
--
|
|
GitLab
|
|
|
|
|
|
From b3d97405cb5b0ee9859576309bd826dea6b74274 Mon Sep 17 00:00:00 2001
|
|
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
Date: Wed, 17 Sep 2025 09:59:07 +0300
|
|
Subject: [PATCH 2/2] shell: Use org.freedesktop.Application.ActivateAction to
|
|
pass xdg activation token to krunner
|
|
|
|
---
|
|
krunner/dbus/org.kde.krunner.App.xml | 4 ----
|
|
krunner/main.cpp | 4 +++-
|
|
krunner/view.cpp | 14 ------------
|
|
krunner/view.h | 1 -
|
|
shell/CMakeLists.txt | 4 ----
|
|
shell/desktopview.cpp | 32 +++++++++++++++++++++++-----
|
|
6 files changed, 30 insertions(+), 29 deletions(-)
|
|
|
|
diff --git a/krunner/dbus/org.kde.krunner.App.xml b/krunner/dbus/org.kde.krunner.App.xml
|
|
index e6926b1b63a..6553e9a1b56 100644
|
|
--- a/krunner/dbus/org.kde.krunner.App.xml
|
|
+++ b/krunner/dbus/org.kde.krunner.App.xml
|
|
@@ -17,9 +17,5 @@
|
|
<arg name="runnerName" type="s" direction="in"/>
|
|
<arg name="term" type="s" direction="in"/>
|
|
</method>
|
|
- <method name="queryWithActivationToken">
|
|
- <arg name="term" type="s" direction="in"/>
|
|
- <arg name="activationToken" type="s" direction="in"/>
|
|
- </method>
|
|
</interface>
|
|
</node>
|
|
diff --git a/krunner/main.cpp b/krunner/main.cpp
|
|
index 514c34b032f..02174bb2cda 100644
|
|
--- a/krunner/main.cpp
|
|
+++ b/krunner/main.cpp
|
|
@@ -136,9 +136,11 @@ int main(int argc, char **argv)
|
|
parser.parse(arguments);
|
|
updateVisibility();
|
|
});
|
|
- QObject::connect(&service, &KDBusService::activateActionRequested, &view, [&view](const QString &action) {
|
|
+ QObject::connect(&service, &KDBusService::activateActionRequested, &view, [&view](const QString &action, const QVariant ¶meter) {
|
|
if (action == QLatin1String("RunClipboard")) {
|
|
view.displayWithClipboardContents();
|
|
+ } else if (action == QLatin1String("Query")) {
|
|
+ view.query(parameter.toString());
|
|
}
|
|
});
|
|
|
|
diff --git a/krunner/view.cpp b/krunner/view.cpp
|
|
index bb7edd5d654..afefe9ab486 100644
|
|
--- a/krunner/view.cpp
|
|
+++ b/krunner/view.cpp
|
|
@@ -263,20 +263,6 @@ void View::querySingleRunner(const QString &runnerName, const QString &term)
|
|
m_engine->rootObject()->setProperty("query", term);
|
|
}
|
|
|
|
-void View::queryWithActivationToken(const QString &term, const QString &activationToken)
|
|
-{
|
|
- qputenv("XDG_ACTIVATION_TOKEN", activationToken.toUtf8());
|
|
-
|
|
- if (!isVisible()) {
|
|
- display();
|
|
- } else {
|
|
- requestActivate();
|
|
- }
|
|
-
|
|
- m_engine->rootObject()->setProperty("singleRunner", QString());
|
|
- m_engine->rootObject()->setProperty("query", term);
|
|
-}
|
|
-
|
|
bool View::pinned() const
|
|
{
|
|
return m_pinned;
|
|
diff --git a/krunner/view.h b/krunner/view.h
|
|
index af1d477d6f3..979c6d3b483 100644
|
|
--- a/krunner/view.h
|
|
+++ b/krunner/view.h
|
|
@@ -93,7 +93,6 @@ public Q_SLOTS:
|
|
void displayWithClipboardContents();
|
|
void query(const QString &term);
|
|
void querySingleRunner(const QString &runnerName, const QString &term);
|
|
- void queryWithActivationToken(const QString &term, const QString &activationToken);
|
|
|
|
protected Q_SLOTS:
|
|
void loadConfig();
|
|
diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt
|
|
index 96b91888f1b..814413ac827 100644
|
|
--- a/shell/CMakeLists.txt
|
|
+++ b/shell/CMakeLists.txt
|
|
@@ -92,10 +92,6 @@ qt6_generate_wayland_protocol_client_sources(plasmashell
|
|
${PLASMA_WAYLAND_PROTOCOLS_DIR}/plasma-shell.xml
|
|
)
|
|
|
|
-set(krunner_xml ${plasma-workspace_SOURCE_DIR}/krunner/dbus/org.kde.krunner.App.xml)
|
|
-qt_add_dbus_interface(plasma_shell_SRCS ${krunner_xml} krunner_interface)
|
|
-
|
|
-
|
|
target_sources(plasmashell PRIVATE ${plasma_shell_SRCS})
|
|
|
|
target_link_libraries(plasmashell PRIVATE
|
|
diff --git a/shell/desktopview.cpp b/shell/desktopview.cpp
|
|
index 744176e6d3e..9c3baa84b91 100644
|
|
--- a/shell/desktopview.cpp
|
|
+++ b/shell/desktopview.cpp
|
|
@@ -6,12 +6,12 @@
|
|
|
|
#include "desktopview.h"
|
|
#include "containmentconfigview.h"
|
|
-#include "krunner_interface.h"
|
|
#include "screenpool.h"
|
|
#include "shellcorona.h"
|
|
|
|
#include <QDBusConnection>
|
|
#include <QDBusMessage>
|
|
+#include <QDBusPendingCall>
|
|
#include <QGuiApplication>
|
|
#include <QQmlContext>
|
|
#include <QQmlEngine>
|
|
@@ -461,12 +461,34 @@ bool DesktopView::handleKRunnerTextInput(QKeyEvent *e)
|
|
}
|
|
m_krunnerFuture = fetchActivationToken(this);
|
|
m_krunnerFuture.then(this, [this](const QString &token) {
|
|
- org::kde::krunner::App krunner(QStringLiteral("org.kde.krunner"), QStringLiteral("/App"), QDBusConnection::sessionBus());
|
|
- krunner.queryWithActivationToken(m_krunnerText, token);
|
|
+ auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.krunner"),
|
|
+ QStringLiteral("/org/kde/krunner"),
|
|
+ QStringLiteral("org.freedesktop.Application"),
|
|
+ QStringLiteral("ActivateAction"));
|
|
+ message.setArguments({
|
|
+ QStringLiteral("Query"),
|
|
+ QVariantList{
|
|
+ m_krunnerText,
|
|
+ },
|
|
+ QVariantMap{
|
|
+ {QStringLiteral("activation-token"), token},
|
|
+ },
|
|
+ });
|
|
+ QDBusConnection::sessionBus().asyncCall(message);
|
|
});
|
|
} else {
|
|
- org::kde::krunner::App krunner(QStringLiteral("org.kde.krunner"), QStringLiteral("/App"), QDBusConnection::sessionBus());
|
|
- krunner.query(m_krunnerText);
|
|
+ auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.krunner"),
|
|
+ QStringLiteral("/org/kde/krunner"),
|
|
+ QStringLiteral("org.freedesktop.Application"),
|
|
+ QStringLiteral("ActivateAction"));
|
|
+ message.setArguments({
|
|
+ QStringLiteral("Query"),
|
|
+ QVariantList{
|
|
+ m_krunnerText,
|
|
+ },
|
|
+ QVariantMap{},
|
|
+ });
|
|
+ QDBusConnection::sessionBus().asyncCall(message);
|
|
}
|
|
return true;
|
|
}
|
|
--
|
|
GitLab
|
|
|