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 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 10:13:49 +02:00
co-authored by Claude Opus 5.5
parent 5f7873995b
commit 9f3940514b
2 changed files with 30 additions and 6 deletions
+23 -5
View File
@@ -1,9 +1,13 @@
#include "KWinFakeInput.h"
#include <QtLogging>
#include <xkbcommon/xkbcommon.h>
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,10 +26,14 @@ constexpr ModifierKey ModifierKeys[] = {
} // namespace
KWinFakeInput::KWinFakeInput()
: QWaylandClientExtensionTemplate(6) // 6: keyboard_keysym
: QWaylandClientExtensionTemplate(KeysymVersion)
{
connect(this, &QWaylandClientExtension::activeChanged, this, [this] {
if (isActive())
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();
@@ -33,13 +41,23 @@ KWinFakeInput::KWinFakeInput()
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);
}
+6
View File
@@ -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;
};