backend/wayland: fix seat caps handling
Previously, each time a wl_seat.capabilities event was received the Wayland backend created new input devices. It now only does so the first time. Input devices are now destroyed when the cap is removed. Closes: https://github.com/swaywm/sway/issues/5055
This commit is contained in:
parent
348f52b5fc
commit
a3c699eee5
|
@ -289,8 +289,9 @@ static struct wlr_wl_input_device *get_wl_input_device_from_input_device(
|
|||
static void input_device_destroy(struct wlr_input_device *wlr_dev) {
|
||||
struct wlr_wl_input_device *dev =
|
||||
get_wl_input_device_from_input_device(wlr_dev);
|
||||
if (dev->resource) {
|
||||
wl_proxy_destroy(dev->resource);
|
||||
if (dev->wlr_input_device.type == WLR_INPUT_DEVICE_KEYBOARD) {
|
||||
wl_keyboard_release(dev->backend->keyboard);
|
||||
dev->backend->keyboard = NULL;
|
||||
}
|
||||
wl_list_remove(&dev->wlr_input_device.link);
|
||||
free(dev);
|
||||
|
@ -535,6 +536,7 @@ void create_wl_pointer(struct wl_pointer *wl_pointer, struct wlr_wl_output *outp
|
|||
&relative_pointer_listener, dev);
|
||||
}
|
||||
|
||||
wl_pointer_add_listener(wl_pointer, &pointer_listener, backend);
|
||||
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
|
||||
}
|
||||
|
||||
|
@ -556,7 +558,6 @@ void create_wl_keyboard(struct wl_keyboard *wl_keyboard, struct wlr_wl_backend *
|
|||
wlr_keyboard_init(wlr_dev->keyboard, NULL);
|
||||
|
||||
wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, wlr_dev);
|
||||
dev->resource = wl_keyboard;
|
||||
wlr_signal_emit_safe(&wl->backend.events.new_input, wlr_dev);
|
||||
}
|
||||
|
||||
|
@ -565,7 +566,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
struct wlr_wl_backend *backend = data;
|
||||
assert(backend->seat == wl_seat);
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_POINTER)) {
|
||||
if ((caps & WL_SEAT_CAPABILITY_POINTER) && backend->pointer == NULL) {
|
||||
wlr_log(WLR_DEBUG, "seat %p offered pointer", (void *)wl_seat);
|
||||
|
||||
struct wl_pointer *wl_pointer = wl_seat_get_pointer(wl_seat);
|
||||
|
@ -575,10 +576,22 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
wl_list_for_each(output, &backend->outputs, link) {
|
||||
create_wl_pointer(wl_pointer, output);
|
||||
}
|
||||
|
||||
wl_pointer_add_listener(wl_pointer, &pointer_listener, backend);
|
||||
}
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
|
||||
if (!(caps & WL_SEAT_CAPABILITY_POINTER) && backend->pointer != NULL) {
|
||||
wlr_log(WLR_DEBUG, "seat %p dropped pointer", (void *)wl_seat);
|
||||
|
||||
struct wlr_input_device *device, *tmp;
|
||||
wl_list_for_each_safe(device, tmp, &backend->devices, link) {
|
||||
if (device->type == WLR_INPUT_DEVICE_POINTER) {
|
||||
wlr_input_device_destroy(device);
|
||||
}
|
||||
}
|
||||
|
||||
wl_pointer_release(backend->pointer);
|
||||
backend->pointer = NULL;
|
||||
}
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && backend->keyboard == NULL) {
|
||||
wlr_log(WLR_DEBUG, "seat %p offered keyboard", (void *)wl_seat);
|
||||
|
||||
struct wl_keyboard *wl_keyboard = wl_seat_get_keyboard(wl_seat);
|
||||
|
@ -588,6 +601,17 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
create_wl_keyboard(wl_keyboard, backend);
|
||||
}
|
||||
}
|
||||
if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && backend->keyboard != NULL) {
|
||||
wlr_log(WLR_DEBUG, "seat %p dropped keyboard", (void *)wl_seat);
|
||||
|
||||
struct wlr_input_device *device, *tmp;
|
||||
wl_list_for_each_safe(device, tmp, &backend->devices, link) {
|
||||
if (device->type == WLR_INPUT_DEVICE_KEYBOARD) {
|
||||
wlr_input_device_destroy(device);
|
||||
}
|
||||
}
|
||||
assert(backend->keyboard == NULL); // free'ed by input_device_destroy
|
||||
}
|
||||
}
|
||||
|
||||
static void seat_handle_name(void *data, struct wl_seat *wl_seat,
|
||||
|
|
Loading…
Reference in New Issue