[PATCH 3/3] Terminate a drag if the origin surface is destroyed

Kristian Hoegsberg hoegsberg at gmail.com
Thu Mar 1 08:54:01 PST 2012


On Thu, Mar 01, 2012 at 02:09:43PM +0200, Ander Conselvan de Oliveira wrote:

This one I'm not sure about.  Obviously if the source client goes
away, we need to end the grab, but we only need the origin surface to
verify that the client has an implicit grab.  Once the drag is started
I think it should be legal for the origin surface to disappear.

Kristian

> ---
>  src/data-device.c    |   57 ++++++++++++++++++++++++++++++++++++--------------
>  src/wayland-server.h |    1 +
>  2 files changed, 42 insertions(+), 16 deletions(-)
> 
> diff --git a/src/data-device.c b/src/data-device.c
> index f0f6baa..184f2aa 100644
> --- a/src/data-device.c
> +++ b/src/data-device.c
> @@ -230,6 +230,28 @@ drag_grab_motion(struct wl_pointer_grab *grab,
>  }
>  
>  static void
> +data_device_end_drag_grab(struct wl_input_device *device, uint32_t time)
> +{
> +	struct wl_resource *surface_resource;
> +	struct wl_surface_interface *implementation;
> +
> +	if (device->drag_surface) {
> +		surface_resource = &device->drag_surface->resource;
> +		implementation = (struct wl_surface_interface *)
> +			surface_resource->object.implementation;
> +
> +		implementation->attach(surface_resource->client,
> +				       surface_resource, NULL, 0, 0);
> +		wl_list_remove(&device->drag_icon_listener.link);
> +	}
> +
> +	wl_input_device_end_pointer_grab(device, time);
> +
> +	device->drag_data_source = NULL;
> +	device->drag_surface = NULL;
> +}
> +
> +static void
>  drag_grab_button(struct wl_pointer_grab *grab,
>  		 uint32_t time, int32_t button, int32_t state)
>  {
> @@ -242,22 +264,8 @@ drag_grab_button(struct wl_pointer_grab *grab,
>  				       WL_DATA_DEVICE_DROP);
>  
>  	if (device->button_count == 0 && state == 0) {
> -		wl_input_device_end_pointer_grab(device, time);
> -
> -		if (device->drag_surface) {
> -			struct wl_resource *surface_resource =
> -				&device->drag_surface->resource;
> -			struct wl_surface_interface *implementation =
> -				(struct wl_surface_interface *)
> -				surface_resource->object.implementation;
> -
> -			implementation->attach(surface_resource->client,
> -					       surface_resource, NULL, 0, 0);
> -			wl_list_remove(&device->drag_icon_listener.link);
> -		}
> -
> -		device->drag_data_source = NULL;
> -		device->drag_surface = NULL;
> +		data_device_end_drag_grab(device, time);
> +		wl_list_remove(&device->drag_origin_listener.link);
>  	}
>  }
>  
> @@ -268,6 +276,19 @@ static const struct wl_pointer_grab_interface drag_grab_interface = {
>  };
>  
>  static void
> +destroy_data_device_origin(struct wl_listener *listener,
> +			   struct wl_resource *resource, uint32_t time)
> +{
> +	struct wl_input_device *device;
> +
> +	device = container_of(listener, struct wl_input_device,
> +			      drag_origin_listener);
> +
> +	data_device_end_drag_grab(device, time);
> +	wl_input_device_set_pointer_focus(device, NULL, 0, 0, 0);
> +}
> +
> +static void
>  destroy_data_device_icon(struct wl_listener *listener,
>  			 struct wl_resource *resource, uint32_t time)
>  {
> @@ -292,6 +313,10 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
>  
>  	/* FIXME: Check that the data source type array isn't empty. */
>  
> +	device->drag_origin_listener.func = destroy_data_device_origin;
> +	wl_list_insert(origin_resource->destroy_listener_list.prev,
> +		       &device->drag_origin_listener.link);
> +
>  	device->drag_grab.interface = &drag_grab_interface;
>  	device->drag_data_source = source_resource->data;
>  
> diff --git a/src/wayland-server.h b/src/wayland-server.h
> index 49ab5b1..e8fc5a1 100644
> --- a/src/wayland-server.h
> +++ b/src/wayland-server.h
> @@ -230,6 +230,7 @@ struct wl_input_device {
>  	struct wl_surface *drag_focus;
>  	struct wl_resource *drag_focus_resource;
>  	struct wl_listener drag_focus_listener;
> +	struct wl_listener drag_origin_listener;
>  	struct wl_pointer_grab drag_grab;
>  	struct wl_surface *drag_surface;
>  	struct wl_listener drag_icon_listener;
> -- 
> 1.7.4.1
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list