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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user