From f0892988c0bc590d885701c42c0a93b4cf6c6ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 3 Mar 2020 18:20:53 +0100 Subject: [PATCH] wayland: don't destroy keyboard/pointer if they haven't been removed When the seat capabilities change, we used to destroy all pointers and keyboards, and then re-creating them as necessary. This caused a crash on mutter - probably because we removed a keyboard device the compositor had already sent an event for (or was about to). Now, we only destroy and create devices when it's needed. --- wayland.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/wayland.c b/wayland.c index 26982815..38fafc49 100644 --- a/wayland.c +++ b/wayland.c @@ -103,24 +103,32 @@ seat_handle_capabilities(void *data, struct wl_seat *wl_seat, { struct wayland *wayl = data; - if (wayl->keyboard != NULL) { - wl_keyboard_release(wayl->keyboard); - wayl->keyboard = NULL; - } - - if (wayl->pointer.pointer != NULL) { - wl_pointer_release(wayl->pointer.pointer); - wayl->pointer.pointer = NULL; - } - if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { - wayl->keyboard = wl_seat_get_keyboard(wl_seat); - wl_keyboard_add_listener(wayl->keyboard, &keyboard_listener, wayl); + if (wayl->keyboard == NULL) { + wayl->keyboard = wl_seat_get_keyboard(wl_seat); + LOG_INFO("got KBD %p", wayl->keyboard); + wl_keyboard_add_listener(wayl->keyboard, &keyboard_listener, wayl); + } + } else { + if (wayl->keyboard != NULL) { + LOG_INFO("releasing KBD %p", wayl->keyboard); + wl_keyboard_release(wayl->keyboard); + wayl->keyboard = NULL; + } } if (caps & WL_SEAT_CAPABILITY_POINTER) { - wayl->pointer.pointer = wl_seat_get_pointer(wl_seat); - wl_pointer_add_listener(wayl->pointer.pointer, &pointer_listener, wayl); + if (wayl->pointer.pointer == NULL) { + wayl->pointer.pointer = wl_seat_get_pointer(wl_seat); + LOG_INFO("got pointer %p", wayl->pointer.pointer); + wl_pointer_add_listener(wayl->pointer.pointer, &pointer_listener, wayl); + } + } else { + if (wayl->pointer.pointer != NULL) { + LOG_INFO("releasing pointer %p", wayl->pointer.pointer); + wl_pointer_release(wayl->pointer.pointer); + wayl->pointer.pointer = NULL; + } } }