[mutter] wayland: Destroy pending frame callbacks when destroying a surface



commit d3988c04d622bdad61ef649ffe04897b6f8eb829
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Feb 25 16:26:01 2015 +0100

    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(+), 0 deletions(-)
---
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index 9a776a9..245d496 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 bfec8b9..c62e8eb 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 4521b41..f11f8c5 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 09701a6..ec12e06 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);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]