[PATCH 2/2] Terminate grabs when the client that initiated them exits

Ander Conselvan de Oliveira conselvan2 at gmail.com
Tue Mar 27 05:12:33 PDT 2012


Hi Kristian,

Any comments about this one? Weston just crashed on me again because of 
this bug.

Thanks,
Ander

On 03/02/2012 03:45 PM, Ander Conselvan de Oliveira wrote:
> Add a client parameter to wl_input_device_start_pointer_focus(). If
> it is non-nil, if that client terminates while the grab is still
> active, the grab is ended and the current focus is set to NULL.
> ---
>   src/data-device.c    |    3 ++-
>   src/wayland-server.c |   28 +++++++++++++++++++++++++++-
>   src/wayland-server.h |    4 +++-
>   3 files changed, 32 insertions(+), 3 deletions(-)
>
> diff --git a/src/data-device.c b/src/data-device.c
> index be2360c..93ad4e7 100644
> --- a/src/data-device.c
> +++ b/src/data-device.c
> @@ -326,7 +326,8 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
>   			&device->drag_icon_listener.link);
>   	}
>
> -	wl_input_device_start_pointer_grab(device,&device->drag_grab, time);
> +	wl_input_device_start_pointer_grab(device,&device->drag_grab, time,
> +					   source_resource->client);
>   }
>
>   static void
> diff --git a/src/wayland-server.c b/src/wayland-server.c
> index 6a8cbcb..6538a29 100644
> --- a/src/wayland-server.c
> +++ b/src/wayland-server.c
> @@ -649,12 +649,38 @@ wl_input_device_end_keyboard_grab(struct wl_input_device *device, uint32_t time)
>   	device->keyboard_grab =&device->default_keyboard_grab;
>   }
>
> +static void
> +destroy_grab_client(struct wl_listener *listener,
> +		    struct wl_resource *resource, uint32_t time)
> +{
> +	struct wl_input_device *device =
> +		container_of(listener, struct wl_input_device,
> +			     grab_client_listener);
> +
> +	wl_input_device_end_pointer_grab(device, time);
> +
> +	/* if the client died, it is very likely the user is still holding a
> +	 * button that caused the grab to start and this probably happened
> +	 * when the focus was in one of the client's surfaces. Since the
> +	 * button down prevents the default grab from resetting the focus and
> +	 * the default grab will have the focus saved as that surfaces,
> +	 * set the focus to NULL here. */
> +	wl_input_device_set_pointer_focus(device, NULL, time, 0, 0);
> +}
> +
>   WL_EXPORT void
>   wl_input_device_start_pointer_grab(struct wl_input_device *device,
> -			   struct wl_pointer_grab *grab, uint32_t time)
> +				   struct wl_pointer_grab *grab, uint32_t time,
> +				   struct wl_client *client)
>   {
>   	const struct wl_pointer_grab_interface *interface;
>
> +	if (client) {
> +		device->grab_client_listener.func = destroy_grab_client;
> +		wl_list_insert(client->display_resource->destroy_listener_list.prev,
> +			&device->grab_client_listener.link);
> +	}
> +
>   	device->pointer_grab = grab;
>   	interface = device->pointer_grab->interface;
>   	grab->input_device = device;
> diff --git a/src/wayland-server.h b/src/wayland-server.h
> index a1ddc68..0ae4bce 100644
> --- a/src/wayland-server.h
> +++ b/src/wayland-server.h
> @@ -224,6 +224,7 @@ struct wl_input_device {
>   	uint32_t grab_button;
>   	uint32_t grab_key;
>   	struct wl_listener grab_listener;
> +	struct wl_listener grab_client_listener;
>
>   	struct wl_list drag_resource_list;
>   	struct wl_data_source *drag_data_source;
> @@ -309,7 +310,8 @@ wl_input_device_end_keyboard_grab(struct wl_input_device *device, uint32_t time)
>
>   void
>   wl_input_device_start_pointer_grab(struct wl_input_device *device,
> -			   struct wl_pointer_grab *grab, uint32_t time);
> +				   struct wl_pointer_grab *grab, uint32_t time,
> +				   struct wl_client *client);
>   void
>   wl_input_device_end_pointer_grab(struct wl_input_device *device, uint32_t time);
>



More information about the wayland-devel mailing list