From d3988c04d622bdad61ef649ffe04897b6f8eb829 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 25 Feb 2015 16:26:01 +0100 Subject: [PATCH] wayland: Destroy pending frame callbacks when destroying a surface MetaWaylandFrameCallback has been added a surface field, which is then checked when destroying the surfaces. This prevents unintended callbacks to run after a surface has been destroyed. https://bugzilla.gnome.org/show_bug.cgi?id=745163 --- src/wayland/meta-wayland-private.h | 1 + src/wayland/meta-wayland-surface.c | 11 +++++++++++ src/wayland/meta-wayland.c | 13 +++++++++++++ src/wayland/meta-wayland.h | 3 +++ 4 files changed, 28 insertions(+) diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index 9a776a9ee..245d4963b 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -37,6 +37,7 @@ typedef struct { struct wl_list link; struct wl_resource *resource; + MetaWaylandSurface *surface; } MetaWaylandFrameCallback; typedef struct diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index bfec8b9ff..c62e8ebc1 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -523,6 +523,7 @@ wl_surface_frame (struct wl_client *client, return; callback = g_slice_new0 (MetaWaylandFrameCallback); + callback->surface = surface; callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id); wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback); @@ -679,6 +680,8 @@ wl_surface_destructor (struct wl_resource *resource) g_object_unref (surface->surface_actor); + meta_wayland_compositor_destroy_frame_callbacks (compositor, surface); + if (surface->resource) wl_resource_set_user_data (surface->resource, NULL); g_slice_free (MetaWaylandSurface, surface); @@ -739,6 +742,8 @@ xdg_surface_destructor (struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_wayland_compositor_destroy_frame_callbacks (surface->compositor, + surface); destroy_window (surface); surface->xdg_surface = NULL; } @@ -1006,6 +1011,8 @@ xdg_popup_destructor (struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_wayland_compositor_destroy_frame_callbacks (surface->compositor, + surface); if (surface->popup.parent) { wl_list_remove (&surface->popup.parent_destroy_listener.link); @@ -1194,6 +1201,8 @@ wl_shell_surface_destructor (struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_wayland_compositor_destroy_frame_callbacks (surface->compositor, + surface); surface->wl_shell_surface = NULL; } @@ -1593,6 +1602,8 @@ wl_subsurface_destructor (struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_wayland_compositor_destroy_frame_callbacks (surface->compositor, + surface); if (surface->sub.parent) { wl_list_remove (&surface->sub.parent_destroy_listener.link); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 4521b41a3..f11f8c593 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -207,6 +207,19 @@ meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, return meta_wayland_seat_handle_event (compositor->seat, event); } +void +meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor, + MetaWaylandSurface *surface) +{ + MetaWaylandFrameCallback *callback, *next; + + wl_list_for_each_safe (callback, next, &compositor->frame_callbacks, link) + { + if (callback->surface == surface) + wl_resource_destroy (callback->resource); + } +} + static void set_gnome_env (const char *name, const char *value) diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h index 09701a605..ec12e06c5 100644 --- a/src/wayland/meta-wayland.h +++ b/src/wayland/meta-wayland.h @@ -46,6 +46,9 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor); +void meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor, + MetaWaylandSurface *surface); + const char *meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor); const char *meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor);