fix(wayland): route keys by keyboard focus, not pointer focus

keyboard_enter and keyboard_leave were empty and keyboard_key dereferenced
Device::focusedWindow, which only a pointer-enter sets: the first key
event in a window the pointer never entered — every key on a touch phone,
or a key typed while the pointer hovers another window — dereferenced a
null pointer, and keys typed after the pointer left went nowhere.

Keyboard focus is its own thing in Wayland. wl_keyboard.enter now resolves
its surface to the Window into Device::keyboardWindow, leave clears it
together with the held keys (their releases happen elsewhere) and stops
the repeat, and keyboard_key and TickKeyRepeats deliver to that window and
drop a key that has none.
This commit is contained in:
Jorijn van der Graaf 2026-10-17 23:48:01 +02:00
commit bfc5e108e5
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
2 changed files with 34 additions and 13 deletions

View file

@ -49,6 +49,11 @@ export namespace Crafter {
inline static xkb_keymap* xkb_keymap;
inline static wl_compositor* compositor = nullptr;
inline static Window* focusedWindow = nullptr;
// The window with keyboard focus (wl_keyboard.enter/leave), apart from
// the pointer's: a key arrives without the pointer ever having entered
// (a touch phone, a key typed while the pointer hovers elsewhere), so the
// keyboard handlers route by this and never by focusedWindow.
inline static Window* keyboardWindow = nullptr;
inline static wl_shm* shm = nullptr;
inline static wp_viewporter* wpViewporter = nullptr;
inline static xkb_context* xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);