Fix: detect key repeat in libei input

For libei, there's no indication that a key is repeated.
However, sending repeated key down events (DKDN instead
of DKRP for the synergy protocol) can be confusing to
clients, which then causes issues like in #7971.

Detect repeated key down events in EiScreen server and
send them to the client with the repeat flag set, so in
e.g. synergy that causes the DKRP messages, to be less
confusing.

For me this fixes an issue where the synergy client is
creating a USB device, which requires repeated events
to be entirely dropped since the host OS where the USB
device is connected will do its own repeat when a key
is held down.
This commit is contained in:
Johannes Berg
2026-01-26 18:28:02 +01:00
committed by Nick Bolton
parent 933617d5b1
commit f065979b3f
2 changed files with 12 additions and 2 deletions

View File

@ -621,18 +621,26 @@ void EiScreen::onKeyEvent(ei_event *event)
bool pressed = ei_event_keyboard_get_key_is_press(event);
KeyID keyid = m_keyState->mapKeyFromKeyval(keyval);
auto keybutton = static_cast<KeyButton>(keyval);
bool repeat;
m_keyState->updateXkbState(keyval, pressed);
KeyModifierMask mask = m_keyState->pollActiveModifiers();
LOG_DEBUG1("event: key %s keycode=%d keyid=%d mask=0x%x", pressed ? "press" : "release", keycode, keyid, mask);
repeat = pressed && m_lastPressed == keyid && keyid != kKeyNone;
m_lastPressed = pressed ? keyid : kKeyNone;
LOG_DEBUG1(
"event: key %s%s keycode=%d keyid=%d mask=0x%x", pressed ? "press" : "release", repeat ? " (repeat)" : "",
keycode, keyid, mask
);
if (m_isPrimary && onHotkey(keyid, pressed, mask)) {
return;
}
if (keyid != kKeyNone) {
m_keyState->sendKeyEvent(getEventTarget(), pressed, false, keyid, mask, 1, keybutton);
m_keyState->sendKeyEvent(getEventTarget(), pressed, repeat, keyid, mask, 1, keybutton);
}
}

View File

@ -122,6 +122,8 @@ private:
// keyboard stuff
EiKeyState *m_keyState = nullptr;
KeyID m_lastPressed = kKeyNone;
// clipboard stuff
WlClipboardCollection *m_clipboard = nullptr;