mirror of
https://github.com/swaywm/sway.git
synced 2024-12-27 07:26:55 +01:00
input: reset keyboard groups keyboard on reset all
If the keyboard that triggers the reload binding is using the default keymap, default repeat delay, and default repeat rate, the associated keyboard group is never being destroyed on reload. This was causing the keyboard group's keyboard not to get disarmed and result in a use-after-free in handle_keyboard_repeat. If the keyboard was not using the defaults for all three settings, then it's associated keyboard would get destroyed during the reset - which did disarm the keyboard group's keyboard. In this case, the use-after-free would not occur. This adds a block to input_manager_reset_all_inputs that resets the keyboard for all keyboard groups in all seats, which will disarm them. Since the inputs are all being reset anyway, which will reset all individual keyboards, it is not necessary to be selective on which ones get reset.
This commit is contained in:
parent
aa48b926be
commit
975b8a90ad
2 changed files with 30 additions and 3 deletions
|
@ -4,15 +4,17 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <wlr/backend/libinput.h>
|
#include <wlr/backend/libinput.h>
|
||||||
|
#include <wlr/types/wlr_cursor.h>
|
||||||
|
#include <wlr/types/wlr_keyboard_group.h>
|
||||||
#include <wlr/types/wlr_input_inhibitor.h>
|
#include <wlr/types/wlr_input_inhibitor.h>
|
||||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||||
#include <wlr/types/wlr_cursor.h>
|
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
|
#include "sway/input/cursor.h"
|
||||||
#include "sway/input/input-manager.h"
|
#include "sway/input/input-manager.h"
|
||||||
|
#include "sway/input/keyboard.h"
|
||||||
#include "sway/input/libinput.h"
|
#include "sway/input/libinput.h"
|
||||||
#include "sway/input/seat.h"
|
#include "sway/input/seat.h"
|
||||||
#include "sway/input/cursor.h"
|
|
||||||
#include "sway/ipc-server.h"
|
#include "sway/ipc-server.h"
|
||||||
#include "sway/server.h"
|
#include "sway/server.h"
|
||||||
#include "sway/tree/view.h"
|
#include "sway/tree/view.h"
|
||||||
|
@ -553,6 +555,18 @@ void input_manager_reset_all_inputs() {
|
||||||
wl_list_for_each(input_device, &server.input->devices, link) {
|
wl_list_for_each(input_device, &server.input->devices, link) {
|
||||||
input_manager_reset_input(input_device);
|
input_manager_reset_input(input_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// needs to be reset. This will disarm the keyboards as well as exit and
|
||||||
|
// re-enter any focus views.
|
||||||
|
struct sway_seat *seat;
|
||||||
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
|
struct sway_keyboard_group *group;
|
||||||
|
wl_list_for_each(group, &seat->keyboard_groups, link) {
|
||||||
|
seat_reset_device(seat, group->seat_device->input_device);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <wlr/types/wlr_cursor.h>
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <wlr/types/wlr_data_device.h>
|
#include <wlr/types/wlr_data_device.h>
|
||||||
#include <wlr/types/wlr_idle.h>
|
#include <wlr/types/wlr_idle.h>
|
||||||
|
#include <wlr/types/wlr_keyboard_group.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
#include <wlr/types/wlr_primary_selection.h>
|
#include <wlr/types/wlr_primary_selection.h>
|
||||||
#include <wlr/types/wlr_tablet_v2.h>
|
#include <wlr/types/wlr_tablet_v2.h>
|
||||||
|
@ -691,7 +692,12 @@ 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);
|
||||||
}
|
}
|
||||||
sway_keyboard_configure(seat_device->keyboard);
|
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);
|
||||||
|
}
|
||||||
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);
|
||||||
|
@ -746,6 +752,13 @@ static struct sway_seat_device *seat_get_device(struct sway_seat *seat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sway_keyboard_group *group = NULL;
|
||||||
|
wl_list_for_each(group, &seat->keyboard_groups, link) {
|
||||||
|
if (group->seat_device->input_device == input_device) {
|
||||||
|
return group->seat_device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue