[PATCH wayland] wayland-server: Listen for pointer current surface destruction

Kristian Høgsberg hoegsberg at gmail.com
Wed Apr 3 09:34:19 PDT 2013


On Wed, Apr 03, 2013 at 03:20:49PM +0100, Rob Bradford wrote:
> From: Rob Bradford <rob at linux.intel.com>
> 
> Add a destroy listener so that when the current surface associated with the
> pointer is destroyed we can reset the pointer to the current surface. In order
> to achieve this add a wl_pointer_set_current() which handles assigning the
> surface and creating the listener.
> 
> This resolves a use-after-free error triggered with nested popup surfaces
> 
> Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=696946

Yup, this is good, let's use a helper to set current and set up the
destroy listener.  Just one important detail below.

>  src/wayland-server.c | 22 ++++++++++++++++++++++
>  src/wayland-server.h |  3 +++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/src/wayland-server.c b/src/wayland-server.c
> index 384b465..3710d8b 100644
> --- a/src/wayland-server.c
> +++ b/src/wayland-server.c
> @@ -946,6 +946,28 @@ wl_pointer_end_grab(struct wl_pointer *pointer)
>  			 pointer->current_x, pointer->current_y);
>  }
>  
> +static void
> +current_surface_destroy(struct wl_listener *listener, void *data)
> +{
> +	struct wl_pointer *pointer =
> +		container_of(listener, struct wl_pointer, current_listener);
> +
> +	pointer->current = NULL;
> +}
> +
> +WL_EXPORT void
> +wl_pointer_set_current(struct wl_pointer *pointer, struct wl_surface *surface)
> +{

We need to wl_list_remove() the old listener here, if pointer->current != NULL.

> +	pointer->current = surface;
> +
> +	if (!surface)
> +		return;
> +
> +	wl_signal_add(&surface->resource.destroy_signal,
> +		      &pointer->current_listener);
> +	pointer->current_listener.notify = current_surface_destroy;
> +}
> +
>  WL_EXPORT void
>  wl_touch_start_grab(struct wl_touch *touch, struct wl_touch_grab *grab)
>  {
> diff --git a/src/wayland-server.h b/src/wayland-server.h
> index e5a862a..af2be62 100644
> --- a/src/wayland-server.h
> +++ b/src/wayland-server.h
> @@ -312,6 +312,7 @@ struct wl_pointer {
>  
>  	wl_fixed_t x, y;
>  	struct wl_surface *current;
> +	struct wl_listener current_listener;
>  	wl_fixed_t current_x, current_y;
>  
>  	uint32_t button_count;
> @@ -450,6 +451,8 @@ wl_pointer_start_grab(struct wl_pointer *pointer,
>  		      struct wl_pointer_grab *grab);
>  void
>  wl_pointer_end_grab(struct wl_pointer *pointer);
> +void
> +wl_pointer_set_current(struct wl_pointer *pointer, struct wl_surface *surface);
>  
>  void
>  wl_keyboard_init(struct wl_keyboard *keyboard);
> -- 
> 1.8.1.4
> 
> _______________________________________________
> 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