Blob Blame History Raw
From 998e3279c24278c947832917706cf5a31b80fa26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 25 Jul 2018 11:49:36 +0200
Subject: [PATCH 1/8] 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
(cherry picked from commit d791710197205028be40750d6ee4119f2b7f0e26)
---
 src/wayland/meta-wayland-actor-surface.c | 12 ++++++++----
 src/wayland/meta-wayland-actor-surface.h |  3 +++
 src/wayland/meta-wayland-xdg-shell.c     |  5 +++++
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
index c10694a2a..b6dbd3326 100644
--- a/src/wayland/meta-wayland-actor-surface.c
+++ b/src/wayland/meta-wayland-actor-surface.c
@@ -47,10 +47,14 @@ meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
   wl_list_init (&surface->pending_frame_callback_list);
 }
 
-static void
-queue_surface_actor_frame_callbacks (MetaWaylandSurface      *surface,
-                                     MetaWaylandPendingState *pending)
+void
+meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
+                                                  MetaWaylandPendingState *pending)
 {
+  MetaWaylandSurfaceRole *surface_role =
+    META_WAYLAND_SURFACE_ROLE (actor_surface);
+  MetaWaylandSurface *surface =
+    meta_wayland_surface_role_get_surface (surface_role);
   MetaSurfaceActorWayland *surface_actor =
     META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
 
@@ -167,7 +171,7 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole  *surface_role,
     meta_wayland_surface_role_get_surface (surface_role);
   MetaWaylandSurface *toplevel_surface;
 
-  queue_surface_actor_frame_callbacks (surface, 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 a5cc24455..ab9b229ed 100644
--- a/src/wayland/meta-wayland-actor-surface.h
+++ b/src/wayland/meta-wayland-actor-surface.h
@@ -40,4 +40,7 @@ void meta_wayland_actor_surface_sync_actor_state (MetaWaylandActorSurface *actor
 
 double meta_wayland_actor_surface_calculate_scale (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 2b1a71b19..4ab638f74 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;
     }
 
-- 
2.19.0