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 "KWinFakeInput.h"
|
||||||
|
|
||||||
|
#include <QtLogging>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
namespace {
|
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 Released = 0;
|
||||||
constexpr uint32_t Pressed = 1;
|
constexpr uint32_t Pressed = 1;
|
||||||
|
|
||||||
@@ -22,10 +26,14 @@ constexpr ModifierKey ModifierKeys[] = {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
KWinFakeInput::KWinFakeInput()
|
KWinFakeInput::KWinFakeInput()
|
||||||
: QWaylandClientExtensionTemplate(6) // 6: keyboard_keysym
|
: QWaylandClientExtensionTemplate(KeysymVersion)
|
||||||
{
|
{
|
||||||
connect(this, &QWaylandClientExtension::activeChanged, this, [this] {
|
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"));
|
authenticate(QStringLiteral("sloposk"), QStringLiteral("On-screen keyboard: type into any window"));
|
||||||
});
|
});
|
||||||
initialize();
|
initialize();
|
||||||
@@ -33,13 +41,23 @@ KWinFakeInput::KWinFakeInput()
|
|||||||
|
|
||||||
KWinFakeInput::~KWinFakeInput()
|
KWinFakeInput::~KWinFakeInput()
|
||||||
{
|
{
|
||||||
if (isActive())
|
if (isActive() && boundVersion() >= DestroyVersion)
|
||||||
destroy();
|
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)
|
void KWinFakeInput::sendKeysym(quint32 keysym, Qt::KeyboardModifiers modifiers)
|
||||||
{
|
{
|
||||||
if (!isActive())
|
if (!canSendKeysyms())
|
||||||
return;
|
return;
|
||||||
for (const ModifierKey &key : ModifierKeys) {
|
for (const ModifierKey &key : ModifierKeys) {
|
||||||
if (modifiers & key.flag)
|
if (modifiers & key.flag)
|
||||||
@@ -55,7 +73,7 @@ void KWinFakeInput::sendKeysym(quint32 keysym, Qt::KeyboardModifiers modifiers)
|
|||||||
|
|
||||||
void KWinFakeInput::setKeyPressed(quint32 keysym, bool pressed)
|
void KWinFakeInput::setKeyPressed(quint32 keysym, bool pressed)
|
||||||
{
|
{
|
||||||
if (isActive())
|
if (canSendKeysyms())
|
||||||
keyboard_keysym(keysym, pressed ? Pressed : Released);
|
keyboard_keysym(keysym, pressed ? Pressed : Released);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,4 +24,10 @@ public:
|
|||||||
void setKeyPressed(quint32 keysym, bool pressed);
|
void setKeyPressed(quint32 keysym, bool pressed);
|
||||||
// Types each character as its keysym.
|
// Types each character as its keysym.
|
||||||
void typeText(const QString &text);
|
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