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.
This commit is contained in:
Hiroaki Yamamoto 2024-05-15 05:15:28 +09:00 committed by GitHub
parent daa0308932
commit ad15c0474d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -31,19 +31,6 @@ input_device_destroy(struct wl_listener *listener, void *data)
wl_list_remove(&keyboard->key.link); wl_list_remove(&keyboard->key.link);
wl_list_remove(&keyboard->modifier.link); wl_list_remove(&keyboard->modifier.link);
keyboard_cancel_keybind_repeat(keyboard); 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); free(input);
} }
@ -648,6 +635,15 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, bool is_lock_surface)
return; 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) * Key events associated with keybindings (both pressed and released)
* are not sent to clients. When changing surface-focus it is therefore * are not sent to clients. When changing surface-focus it is therefore