https://bugs.kde.org/show_bug.cgi?id=519973

            Bug ID: 519973
           Summary: fakeinput keyboard_keysym broadcasts modifier state to
                    all Wayland clients causing key corruption on
                    non-QWERTY layouts
    Classification: Plasma
           Product: kwin
      Version First 6.6.4
       Reported In:
          Platform: Fedora RPMs
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: virtual-keyboard
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

Overview
When using org_kde_kwin_fake_input protocol's keyboard_keysym request (used by
KDE Connect via xdg-desktop-portal-kde's RemoteDesktop portal), uppercase
letters and AltGr characters are injected incorrectly on non-QWERTY keyboard
layouts (confirmed on French AZERTY).
Root cause
In src/backends/fakeinput/fakeinputbackend.cpp,
org_kde_kwin_fake_input_keyboard_keysym calls
input()->keyboard()->xkb()->updateModifiers() to temporarily set the
Shift/AltGr modifier state before sending the key. This function broadcasts the
modifier state change to all connected Wayland clients via forwardModifiers().
The terminal or application receiving the keypress sees the Shift modifier
arrive, then the key, then Shift release — but the timing and ordering causes
the modifier state to bleed into subsequent keystrokes, resulting in random
capitalization and symbol corruption on AZERTY and other non-QWERTY layouts.
Steps to reproduce

Use a French AZERTY keyboard layout on KDE Plasma Wayland
Use KDE Connect Android app with the remote keyboard feature
Type uppercase letters or AltGr characters
Observe that characters arrive incorrectly — uppercase letters appear as
lowercase, numbers appear as their shifted symbols (e.g. 1 → &, 2 → é), and
modifier state bleeds into subsequent keystrokes

Fix
Instead of calling updateModifiers() (which broadcasts globally), send explicit
KEY_LEFTSHIFT / KEY_RIGHTALT key press and release events around the actual
keypress. The key level from keycodeFromKeysym() already tells us which
modifier is needed:
cppstd::optional<Xkb::KeyCode> keyCode =
input()->keyboard()->xkb()->keycodeFromKeysym(keySym);
if (keyCode) {
    const bool needsShift = keyCode->level == 1;
    const bool needsAltGr = keyCode->level == 2;
    if (needsShift) sendKey(device, KEY_LEFTSHIFT, KeyboardKeyState::Pressed);
    if (needsAltGr) sendKey(device, KEY_RIGHTALT, KeyboardKeyState::Pressed);
    sendKey(device, keyCode->keyCode, nativeState);
    if (needsAltGr) sendKey(device, KEY_RIGHTALT, KeyboardKeyState::Released);
    if (needsShift) sendKey(device, KEY_LEFTSHIFT, KeyboardKeyState::Released);
    return;
}
KEY_LEFTSHIFT (42) and KEY_RIGHTALT (100) are already defined in
linux/input-event-codes.h which is included via the existing headers.
Tested on

Nobara Linux 43, KDE Plasma 6.6.2 / KWin 6.6.4
French AZERTY layout (localectl set-x11-keymap fr pc105)
KDE Connect Android 1.35.5 → xdg-desktop-portal-kde → KWin fakeinput

Patch confirmed working on both KWin 6.6.2 and 6.6.4.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to