pointer/keyboard: Properly handle destruction

If the client destroys the pointer resource, we shouldn't unfocus the
surface, and we should regrab it when the client gets the pointer
resource again.

This also fixes a crash at surface destruction because of the unchecked
wl_link_remove that will happen on both pointer and surface destroy.
This commit is contained in:
Jasper St. Pierre 2014-02-20 11:29:28 -05:00
parent 7499621ecb
commit 7ebf5aa69a
2 changed files with 13 additions and 25 deletions

View File

@ -217,28 +217,22 @@ err_keymap_str:
return; return;
} }
static void
release_focus (MetaWaylandKeyboard *keyboard)
{
wl_list_remove (&keyboard->focus_surface_listener.link);
wl_list_remove (&keyboard->focus_resource_listener.link);
keyboard->focus_resource = NULL;
keyboard->focus_surface = NULL;
}
static void static void
keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
{ {
MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener); MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener);
release_focus (keyboard);
wl_list_remove (&keyboard->focus_surface_listener.link);
keyboard->focus_surface = NULL;
} }
static void static void
keyboard_handle_focus_resource_destroy (struct wl_listener *listener, void *data) keyboard_handle_focus_resource_destroy (struct wl_listener *listener, void *data)
{ {
MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_resource_listener); MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_resource_listener);
release_focus (keyboard);
wl_list_remove (&keyboard->focus_resource_listener.link);
keyboard->focus_resource = NULL;
} }
static gboolean static gboolean

View File

@ -55,28 +55,22 @@
static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer); static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer);
static void
release_focus (MetaWaylandPointer *pointer)
{
wl_list_remove (&pointer->focus_surface_listener.link);
wl_list_remove (&pointer->focus_resource_listener.link);
pointer->focus_resource = NULL;
pointer->focus_surface = NULL;
}
static void static void
pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
{ {
MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener); MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener);
release_focus (pointer);
wl_list_remove (&pointer->focus_surface_listener.link);
pointer->focus_surface = NULL;
} }
static void static void
pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data) pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data)
{ {
MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_resource_listener); MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_resource_listener);
release_focus (pointer);
wl_list_remove (&pointer->focus_resource_listener.link);
pointer->focus_resource = NULL;
} }
static void static void
@ -302,7 +296,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer)
void void
meta_wayland_pointer_release (MetaWaylandPointer *pointer) meta_wayland_pointer_release (MetaWaylandPointer *pointer)
{ {
release_focus (pointer); /* Do nothing. */
} }
static struct wl_resource * static struct wl_resource *