input: fix reloading crash due to keyboard group configuring

Keyboard group keyboards should not call sway_keyboard_configure. They
do not have an input config and they derive their state from the
keyboards within the group.

For some reason, I got sway_keyboard_configure and
seat_configure_keyboard mixed up and thought seat_reset_device called
the latter.

Calling sway_keyboard_configure with a keyboard group's keyboard is not
supported and can cause issues. If any clients are listening to the ipc
input event, a sigsegv will occur due to not every property - such as
identifier - being wired up for keyboard group keyboard's.

This also adds an assertion to sway_keyboard_configure to ensure that
this does not occur in the future and any instances are quickly caught.
This commit is contained in:
Brian Ashworth 2020-05-18 17:52:13 -04:00 committed by Tudor Brindus
parent 9b5895be63
commit 5c32a48453
3 changed files with 9 additions and 9 deletions

View file

@ -558,13 +558,12 @@ void input_manager_reset_all_inputs() {
// If there is at least one keyboard using the default keymap, repeat delay, // If there is at least one keyboard using the default keymap, repeat delay,
// and repeat rate, then it is possible that there is a keyboard group that // and repeat rate, then it is possible that there is a keyboard group that
// needs to be reset. This will disarm the keyboards as well as exit and // need their keyboard disarmed.
// re-enter any focus views.
struct sway_seat *seat; struct sway_seat *seat;
wl_list_for_each(seat, &server.input->seats, link) { wl_list_for_each(seat, &server.input->seats, link) {
struct sway_keyboard_group *group; struct sway_keyboard_group *group;
wl_list_for_each(group, &seat->keyboard_groups, link) { wl_list_for_each(group, &seat->keyboard_groups, link) {
seat_reset_device(seat, group->seat_device->input_device); sway_keyboard_disarm_key_repeat(group->seat_device->keyboard);
} }
} }
} }

View file

@ -853,6 +853,12 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
struct wlr_input_device *wlr_device = struct wlr_input_device *wlr_device =
keyboard->seat_device->input_device->wlr_device; keyboard->seat_device->input_device->wlr_device;
if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard),
"sway_keyboard_configure should not be called with a "
"keyboard group's keyboard")) {
return;
}
struct xkb_keymap *keymap = sway_keyboard_compile_keymap(input_config, NULL); struct xkb_keymap *keymap = sway_keyboard_compile_keymap(input_config, NULL);
if (!keymap) { if (!keymap) {
sway_log(SWAY_ERROR, "Failed to compile keymap. Attempting defaults"); sway_log(SWAY_ERROR, "Failed to compile keymap. Attempting defaults");

View file

@ -692,12 +692,7 @@ static void seat_configure_keyboard(struct sway_seat *seat,
if (!seat_device->keyboard) { if (!seat_device->keyboard) {
sway_keyboard_create(seat, seat_device); sway_keyboard_create(seat, seat_device);
} }
if (!wlr_keyboard_group_from_wlr_keyboard(
seat_device->input_device->wlr_device->keyboard)) {
// Do not configure keyboard group keyboards. They will be configured
// based on the keyboards in the group.
sway_keyboard_configure(seat_device->keyboard); sway_keyboard_configure(seat_device->keyboard);
}
wlr_seat_set_keyboard(seat->wlr_seat, wlr_seat_set_keyboard(seat->wlr_seat,
seat_device->input_device->wlr_device); seat_device->input_device->wlr_device);
struct sway_node *focus = seat_get_focus(seat); struct sway_node *focus = seat_get_focus(seat);