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
This commit is contained in:
Jonas Ådahl 2018-07-25 11:49:36 +02:00
parent b30c907ef9
commit d791710197
3 changed files with 18 additions and 8 deletions

View File

@ -90,11 +90,16 @@ meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
} }
} }
static void void
queue_surface_actor_frame_callbacks (MetaSurfaceActorWayland *surface_actor, meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
MetaWaylandPendingState *pending) 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); &pending->frame_callback_list);
wl_list_init (&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, meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending) MetaWaylandPendingState *pending)
{ {
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role));
MetaWaylandActorSurface *actor_surface = MetaWaylandActorSurface *actor_surface =
META_WAYLAND_ACTOR_SURFACE (surface_role); META_WAYLAND_ACTOR_SURFACE (surface_role);
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role); meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandSurface *toplevel_surface; MetaWaylandSurface *toplevel_surface;
queue_surface_actor_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor), meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
pending);
toplevel_surface = meta_wayland_surface_get_toplevel (surface); toplevel_surface = meta_wayland_surface_get_toplevel (surface);
if (!toplevel_surface || !toplevel_surface->window) if (!toplevel_surface || !toplevel_surface->window)

View File

@ -43,4 +43,7 @@ double meta_wayland_actor_surface_calculate_scale (MetaWaylandActorSurface *acto
MetaSurfaceActor * meta_wayland_actor_surface_get_actor (MetaWaylandActorSurface *actor_surface); 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_reset_actor (MetaWaylandActorSurface *actor_surface);
void meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
MetaWaylandPendingState *pending);
#endif /* META_WAYLAND_ACTOR_SURFACE_H */ #endif /* META_WAYLAND_ACTOR_SURFACE_H */

View File

@ -626,7 +626,12 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached) 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_xdg_surface_reset (xdg_surface);
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface,
pending);
return; return;
} }