compositor: delay surface commits for frozen actors

Right now we defer processing damage on frozen actors, but don't defer
processing surface changes on frozen actors (like for instance when the
surface is changed during a resize).

This commit stops the compositor from processing xwayland client events
for a surface when the actor associated with it is frozen waiting for
the client to draw on the underlying window.

By deferring xwayland client event processing, we'll ensure the surface
commit comes after the corresponding sync counter update from the app,
and ensure we don't update the surface associated with an X window
until after client has finished drawing.
This commit is contained in:
Ray Strode 2018-03-13 21:19:03 -04:00 committed by Ray Strode
parent 80562bbb10
commit 8369fde7f8
4 changed files with 40 additions and 2 deletions

View File

@ -99,6 +99,20 @@ meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
wl_list_insert_list (&priv->frame_callback_list, frame_callbacks);
}
static void
meta_surface_actor_wayland_set_frozen (MetaSurfaceActor *actor,
gboolean is_frozen)
{
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
META_SURFACE_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->set_frozen (actor,
is_frozen);
if (surface)
meta_wayland_surface_set_frozen (surface, is_frozen);
}
static MetaWindow *
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
{
@ -220,6 +234,7 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
surface_actor_class->set_unredirected = meta_surface_actor_wayland_set_unredirected;
surface_actor_class->is_unredirected = meta_surface_actor_wayland_is_unredirected;
surface_actor_class->set_frozen = meta_surface_actor_wayland_set_frozen;
surface_actor_class->get_window = meta_surface_actor_wayland_get_window;
object_class->dispose = meta_surface_actor_wayland_dispose;

View File

@ -346,8 +346,11 @@ meta_window_actor_freeze (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->freeze_count == 0 && priv->surface)
if (priv->freeze_count == 0)
{
if (priv->surface)
meta_surface_actor_set_frozen (priv->surface, TRUE);
}
priv->freeze_count ++;
}

View File

@ -703,6 +703,9 @@ cleanup:
static void
meta_wayland_surface_commit (MetaWaylandSurface *surface)
{
if (surface->is_frozen)
return;
/*
* If this is a sub-surface and it is in effective synchronous mode, only
* cache the pending surface state until either one of the following two
@ -1719,3 +1722,16 @@ meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
}
void
meta_wayland_surface_set_frozen (MetaWaylandSurface *surface,
gboolean is_frozen)
{
if (surface->is_frozen == is_frozen)
return;
surface->is_frozen = is_frozen;
if (!surface->is_frozen && surface->pending)
meta_wayland_surface_commit (surface);
}

View File

@ -203,6 +203,8 @@ struct _MetaWaylandSurface
/* table of seats for which shortcuts are inhibited */
GHashTable *shortcut_inhibited_seats;
guint32 is_frozen : 1;
};
void meta_wayland_shell_init (MetaWaylandCompositor *compositor);
@ -302,5 +304,7 @@ void meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *
gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
MetaWaylandSeat *seat);
void meta_wayland_surface_set_frozen (MetaWaylandSurface *surface,
gboolean is_frozen);
#endif