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>
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) {
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);