summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2018-02-22 16:55:15 +0200
committerDaniel Stone <daniels@collabora.com>2018-03-09 10:54:51 +0000
commit72e183bd2b41b888a4d26e3c6b389948964df85c (patch)
tree1561b6d6f6b4b88bb020d86b5442d0477f5ee1b8
parent8d6e14c991346a70830cd9788e213d77191aba6e (diff)
downloadweston-72e183bd2b41b888a4d26e3c6b389948964df85c.tar.gz
input: never set keyboard focus without wl_resource
Do not attempt to set keyboard focus to a surface that has no wl_resource. The destroy listener hangs off the wl_resource, so if that is not present, nothing will clean up the pointer when the weston_surface gets destroyed and it goes stale. As keyboard_focus_resource_destroyed() sets the focus to NULL, this patch should be enough to guarantee that the keyboard focus surface will always have a wl_resource. I have confirmed the added branch in weston_keyboard_set_focus() can be hit, but doing so is hard. My test case has weston/x11 with two outputs, and weston/wayland --sprawl running on top of that, then closing the parent compositor output windows one by one. Sometimes it hits, often it does not. Having the window closing animation enabled may help to hit it. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--libweston/input.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/libweston/input.c b/libweston/input.c
index 3f616941..3e91c266 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -1460,6 +1460,14 @@ weston_keyboard_set_focus(struct weston_keyboard *keyboard,
uint32_t serial;
struct wl_list *focus_resource_list;
+ /* Keyboard focus on a surface without a client is equivalent to NULL
+ * focus as nothing would react to the keyboard events anyway.
+ * Just set focus to NULL instead - the destroy listener hangs on the
+ * wl_resource anyway.
+ */
+ if (surface && !surface->resource)
+ surface = NULL;
+
focus_resource_list = &keyboard->focus_resource_list;
if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
@@ -1495,7 +1503,7 @@ weston_keyboard_set_focus(struct weston_keyboard *keyboard,
wl_list_remove(&keyboard->focus_resource_listener.link);
wl_list_init(&keyboard->focus_resource_listener.link);
- if (surface && surface->resource)
+ if (surface)
wl_resource_add_destroy_listener(surface->resource,
&keyboard->focus_resource_listener);