From ad15c0474db518ece55846ef624fa2d85358d89e Mon Sep 17 00:00:00 2001 From: Hiroaki Yamamoto Date: Wed, 15 May 2024 05:15:28 +0900 Subject: [PATCH] seat: prevent xwayland from using incorrect keymap (#1816) With commit cafdcd8e, the keyboard from the keyboard group is set to the seat when the active keyboard is destroyed, but this broke `wtype` against XWayland surfaces. This is likely because XWayland caches keycodes from the compositor and convert them with the last keymap received from the compositor. So when we run `wtype a` over a XWayland surface, the keycode for `a` is cached by XWayland, the keymap from the keyboard group is sent to XWayland, then Xwayland converts the keycode using the keymap from the keyboard group, not the one `wtype` set. This commit fixes this by setting the keyboard from the keyboard group to the seat when the keyboard focus is moved to a surface, not when the active keyboard is destroyed. --- src/seat.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/seat.c b/src/seat.c index c16cdcda..34158f2f 100644 --- a/src/seat.c +++ b/src/seat.c @@ -31,19 +31,6 @@ input_device_destroy(struct wl_listener *listener, void *data) wl_list_remove(&keyboard->key.link); wl_list_remove(&keyboard->modifier.link); keyboard_cancel_keybind_repeat(keyboard); - /* - * If the active keyboard on the seat is destroyed, fall back - * to the keyboard from keyboard group so we can respond to - * wl_seat.get_keyboard requests with wl_keyboard.keymap event. - * This prevents Chromium from crashing when started just after - * the active keyboard is destroyed. - */ - struct wlr_keyboard *active_keyboard = - wlr_seat_get_keyboard(input->seat->seat); - if (!active_keyboard || active_keyboard == keyboard->wlr_keyboard) { - wlr_seat_set_keyboard(input->seat->seat, - &input->seat->keyboard_group->keyboard); - } } free(input); } @@ -648,6 +635,15 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, bool is_lock_surface) return; } + if (!wlr_seat_get_keyboard(seat->seat)) { + /* + * wlr_seat_keyboard_notify_enter() sends wl_keyboard.modifiers, + * but it may crash some apps (e.g. Chromium) if + * wl_keyboard.keymap is not sent beforehand. + */ + wlr_seat_set_keyboard(seat->seat, &seat->keyboard_group->keyboard); + } + /* * Key events associated with keybindings (both pressed and released) * are not sent to clients. When changing surface-focus it is therefore