From 9f3940514b950bcc68ec8354d93f36cdd13702a3 Mon Sep 17 00:00:00 2001 From: ericek111 Date: Thu, 15 Oct 2026 10:13:49 +0200 Subject: [PATCH] Fake input: check the bound protocol version Qt binds the lower of the asked and advertised versions; sending keyboard_keysym (v6) or destroy (v5) to an older KWin makes libwayland abort. Those requests are skipped there, with a warning. Co-Authored-By: Claude Opus 5.5 --- src/backend/KWinFakeInput.cpp | 30 ++++++++++++++++++++++++------ src/backend/KWinFakeInput.h | 6 ++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/backend/KWinFakeInput.cpp b/src/backend/KWinFakeInput.cpp index a0472ed..d65d8c7 100644 --- a/src/backend/KWinFakeInput.cpp +++ b/src/backend/KWinFakeInput.cpp @@ -1,9 +1,13 @@ #include "KWinFakeInput.h" +#include #include namespace { +constexpr uint32_t KeysymVersion = 6; // keyboard_keysym; keyboard_key is 4 +constexpr uint32_t DestroyVersion = 5; + constexpr uint32_t Released = 0; constexpr uint32_t Pressed = 1; @@ -22,24 +26,38 @@ constexpr ModifierKey ModifierKeys[] = { } // namespace KWinFakeInput::KWinFakeInput() - : QWaylandClientExtensionTemplate(6) // 6: keyboard_keysym + : QWaylandClientExtensionTemplate(KeysymVersion) { connect(this, &QWaylandClientExtension::activeChanged, this, [this] { - if (isActive()) - authenticate(QStringLiteral("sloposk"), QStringLiteral("On-screen keyboard: type into any window")); + if (!isActive()) + return; + if (!canSendKeysyms()) + qWarning("KWin's fake input is too old (version %u, need %u): typing outside text fields is off", + boundVersion(), KeysymVersion); + authenticate(QStringLiteral("sloposk"), QStringLiteral("On-screen keyboard: type into any window")); }); initialize(); } KWinFakeInput::~KWinFakeInput() { - if (isActive()) + if (isActive() && boundVersion() >= DestroyVersion) destroy(); } +uint32_t KWinFakeInput::boundVersion() const +{ + return QtWayland::org_kde_kwin_fake_input::version(); // the proxy's, not the one asked for +} + +bool KWinFakeInput::canSendKeysyms() const +{ + return isActive() && boundVersion() >= KeysymVersion; +} + void KWinFakeInput::sendKeysym(quint32 keysym, Qt::KeyboardModifiers modifiers) { - if (!isActive()) + if (!canSendKeysyms()) return; for (const ModifierKey &key : ModifierKeys) { if (modifiers & key.flag) @@ -55,7 +73,7 @@ void KWinFakeInput::sendKeysym(quint32 keysym, Qt::KeyboardModifiers modifiers) void KWinFakeInput::setKeyPressed(quint32 keysym, bool pressed) { - if (isActive()) + if (canSendKeysyms()) keyboard_keysym(keysym, pressed ? Pressed : Released); } diff --git a/src/backend/KWinFakeInput.h b/src/backend/KWinFakeInput.h index 7f62a64..639d3c5 100644 --- a/src/backend/KWinFakeInput.h +++ b/src/backend/KWinFakeInput.h @@ -24,4 +24,10 @@ public: void setKeyPressed(quint32 keysym, bool pressed); // Types each character as its keysym. void typeText(const QString &text); + +private: + // The version KWin bound, which may be older than the one asked for: + // sending a request it lacks makes libwayland abort. + uint32_t boundVersion() const; + bool canSendKeysyms() const; };