[mutter] wayland/xdg-shell: Queue frame callbacks on new actor after resetting



commit d791710197205028be40750d6ee4119f2b7f0e26
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Jul 25 11:49:36 2018 +0200

    wayland/xdg-shell: Queue frame callbacks on new actor after resetting
    
    When a xdg-toplevel is reset, the window and actor are recreated, and
    all state is cleared. When this happened, we earlied out from the
    xdg-toplevel commit handler, which would mean that if the client had
    queued frame callbacks when resetting, they'd be left in the pending
    commit state, later hitting an assert as they were not handled.
    
    Fix this by queuing the frame callbacks no the new actor, so that they
    are emitted whenever the actor is eventually painted.
    
    https://gitlab.gnome.org/GNOME/mutter/issues/240

 src/wayland/meta-wayland-actor-surface.c | 18 ++++++++++--------
 src/wayland/meta-wayland-actor-surface.h |  3 +++
 src/wayland/meta-wayland-xdg-shell.c     |  5 +++++
 3 files changed, 18 insertions(+), 8 deletions(-)
---
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
index c4f8619a6..b69c31f72 100644
--- a/src/wayland/meta-wayland-actor-surface.c
+++ b/src/wayland/meta-wayland-actor-surface.c
@@ -90,11 +90,16 @@ meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
     }
 }
 
-static void
-queue_surface_actor_frame_callbacks (MetaSurfaceActorWayland *surface_actor,
-                                     MetaWaylandPendingState *pending)
+void
+meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
+                                                  MetaWaylandPendingState *pending)
 {
-  meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
+  MetaWaylandActorSurfacePrivate *priv =
+    meta_wayland_actor_surface_get_instance_private (actor_surface);
+  MetaSurfaceActorWayland *surface_actor_wayland =
+    META_SURFACE_ACTOR_WAYLAND (priv->actor);
+
+  meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland,
                                                   &pending->frame_callback_list);
   wl_list_init (&pending->frame_callback_list);
 }
@@ -223,16 +228,13 @@ static void
 meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole  *surface_role,
                                    MetaWaylandPendingState *pending)
 {
-  MetaWaylandActorSurfacePrivate *priv =
-    meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role));
   MetaWaylandActorSurface *actor_surface =
     META_WAYLAND_ACTOR_SURFACE (surface_role);
   MetaWaylandSurface *surface =
     meta_wayland_surface_role_get_surface (surface_role);
   MetaWaylandSurface *toplevel_surface;
 
-  queue_surface_actor_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
-                                       pending);
+  meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
 
   toplevel_surface = meta_wayland_surface_get_toplevel (surface);
   if (!toplevel_surface || !toplevel_surface->window)
diff --git a/src/wayland/meta-wayland-actor-surface.h b/src/wayland/meta-wayland-actor-surface.h
index 7c771dc70..444b3b178 100644
--- a/src/wayland/meta-wayland-actor-surface.h
+++ b/src/wayland/meta-wayland-actor-surface.h
@@ -43,4 +43,7 @@ double meta_wayland_actor_surface_calculate_scale (MetaWaylandActorSurface *acto
 MetaSurfaceActor * meta_wayland_actor_surface_get_actor (MetaWaylandActorSurface *actor_surface);
 void meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surface);
 
+void meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
+                                                       MetaWaylandPendingState *pending);
+
 #endif /* META_WAYLAND_ACTOR_SURFACE_H */
diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c
index b5f347095..4bd44e4cd 100644
--- a/src/wayland/meta-wayland-xdg-shell.c
+++ b/src/wayland/meta-wayland-xdg-shell.c
@@ -626,7 +626,12 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole  *surface_role,
 
   if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
     {
+      MetaWaylandActorSurface *actor_surface =
+        META_WAYLAND_ACTOR_SURFACE (xdg_toplevel);
+
       meta_wayland_xdg_surface_reset (xdg_surface);
+      meta_wayland_actor_surface_queue_frame_callbacks (actor_surface,
+                                                        pending);
       return;
     }
 


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