From 0e5a5df5fe4d147197d85d4191d8a5c2eefb1561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Oct 2019 18:20:31 +0100 Subject: [PATCH] wayland/actor-surface: Always store away frame callbacks on commit We're expected by MetaWaylandSurface to always pick the frame callbacks out from the pending state when committing (applying) so that no frame callbacks are unaccounted for. We failed to do this if our actor for some reason (e.g. associated window was unmanaged) was destroyed. To handle this situation better, store away the frame callbacks until we some later point in time need to pass them on forward. https://gitlab.gnome.org/GNOME/mutter/merge_requests/893 --- src/wayland/meta-wayland-actor-surface.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c index a61a80eff..bf93f9564 100644 --- a/src/wayland/meta-wayland-actor-surface.c +++ b/src/wayland/meta-wayland-actor-surface.c @@ -38,6 +38,8 @@ struct _MetaWaylandActorSurfacePrivate MetaSurfaceActor *actor; gulong actor_destroyed_handler_id; + + struct wl_list frame_callback_list; }; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandActorSurface, @@ -78,6 +80,7 @@ meta_wayland_actor_surface_dispose (GObject *object) MetaWaylandActorSurface *actor_surface = META_WAYLAND_ACTOR_SURFACE (object); MetaWaylandActorSurfacePrivate *priv = meta_wayland_actor_surface_get_instance_private (actor_surface); + MetaWaylandFrameCallback *cb, *next; if (priv->actor) { @@ -85,6 +88,9 @@ meta_wayland_actor_surface_dispose (GObject *object) clear_surface_actor (actor_surface); } + wl_list_for_each_safe (cb, next, &priv->frame_callback_list, link) + wl_resource_destroy (cb->resource); + G_OBJECT_CLASS (meta_wayland_actor_surface_parent_class)->dispose (object); } @@ -113,6 +119,9 @@ meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor if (!priv->actor) return; + meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland, + &priv->frame_callback_list); + wl_list_init (&priv->frame_callback_list); meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland, &pending->frame_callback_list); wl_list_init (&pending->frame_callback_list); @@ -239,7 +248,12 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role, meta_wayland_actor_surface_get_instance_private (actor_surface); if (!priv->actor) - return; + { + wl_list_insert_list (&priv->frame_callback_list, + &pending->frame_callback_list); + wl_list_init (&pending->frame_callback_list); + return; + } if (!wl_list_empty (&pending->frame_callback_list) && cairo_region_is_empty (pending->surface_damage) && @@ -292,8 +306,12 @@ meta_wayland_actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surfac } static void -meta_wayland_actor_surface_init (MetaWaylandActorSurface *role) +meta_wayland_actor_surface_init (MetaWaylandActorSurface *actor_surface) { + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + + wl_list_init (&priv->frame_callback_list); } static void