[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