From 8369fde7f868f8052d6b0d651945b242caad3a08 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 13 Mar 2018 21:19:03 -0400 Subject: [PATCH] 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. --- src/compositor/meta-surface-actor-wayland.c | 15 +++++++++++++++ src/compositor/meta-window-actor.c | 7 +++++-- src/wayland/meta-wayland-surface.c | 16 ++++++++++++++++ src/wayland/meta-wayland-surface.h | 4 ++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index 7505b7d79..c70e44461 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -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; diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 768ce3acb..a10e6e573 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -346,8 +346,11 @@ meta_window_actor_freeze (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - if (priv->freeze_count == 0 && priv->surface) - meta_surface_actor_set_frozen (priv->surface, TRUE); + if (priv->freeze_count == 0) + { + if (priv->surface) + meta_surface_actor_set_frozen (priv->surface, TRUE); + } priv->freeze_count ++; } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0c1d2cd54..159e6f86e 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -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); +} diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 05d2a0a24..28682022a 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -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