wayland-server: Listen for pointer current surface destruction

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
This commit is contained in:
Rob Bradford 2013-04-03 15:20:49 +01:00 committed by Kristian Høgsberg
parent 858fcbde59
commit db19b443cc
2 changed files with 28 additions and 0 deletions

View file

@ -946,6 +946,31 @@ 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)
{
if (pointer->current)
wl_list_remove(&pointer->current_listener.link);
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)
{

View file

@ -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);