On Wed, Apr 03, 2013 at 03:20:49PM +0100, Rob Bradford wrote: > From: Rob Bradford <r...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel