[mutter/gnome-3-36] window-actor/x11: Cache the frame bounds



commit adbe09afc3e37dba19f03f94c5ad82f75c68f818
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Fri Apr 24 12:19:02 2020 +0200

    window-actor/x11: Cache the frame bounds
    
    When resizing an X11 window with client side decorations, the shadow is
    clipped by the frame bounds so that we don't need to paint the shadow
    under the opaque areas covered by the window and its frame.
    
    When the X11 client uses the EMWH synchronization mechanism (like all
    gtk-3 based clients), the actual window may not be updated so that the
    actual window and it frame may be behind the expected window frame
    bounds, which gives the impression of de-synchronized shadows.
    
    To avoid the issue, keep a copy of the frame bounds as a cache and only
    update it when the client is not frozen so that the clipping occurs on
    the actual content.
    
    Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1178
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/1214
    
    (cherry picked from commit bd45a00fa33f2f9a999ead3ffaa178322d84f4d0)

 src/compositor/meta-window-actor-x11.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)
---
diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c
index a8d137316..53ae6ad68 100644
--- a/src/compositor/meta-window-actor-x11.c
+++ b/src/compositor/meta-window-actor-x11.c
@@ -85,6 +85,8 @@ struct _MetaWindowActorX11
   cairo_region_t *shape_region;
   /* The region we should clip to when painting the shadow */
   cairo_region_t *shadow_clip;
+  /* The frame region */
+  cairo_region_t *frame_bounds;
 
   /* Extracted size-invariant shape used for shadows */
   MetaWindowShape *shadow_shape;
@@ -702,11 +704,8 @@ set_clip_region_beneath (MetaWindowActorX11 *actor_x11,
 
           if (clip_shadow_under_window (actor_x11))
             {
-              cairo_region_t *frame_bounds;
-
-              frame_bounds = meta_window_get_frame_bounds (window);
-              if (frame_bounds)
-                cairo_region_subtract (actor_x11->shadow_clip, frame_bounds);
+              if (actor_x11->frame_bounds)
+                cairo_region_subtract (actor_x11->shadow_clip, actor_x11->frame_bounds);
             }
         }
       else
@@ -1126,6 +1125,17 @@ update_opaque_region (MetaWindowActorX11 *actor_x11)
   cairo_region_destroy (opaque_region);
 }
 
+static void
+update_frame_bounds (MetaWindowActorX11 *actor_x11)
+{
+  MetaWindow *window =
+    meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
+
+  g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
+  actor_x11->frame_bounds =
+    cairo_region_copy (meta_window_get_frame_bounds (window));
+}
+
 static void
 update_regions (MetaWindowActorX11 *actor_x11)
 {
@@ -1197,6 +1207,7 @@ handle_updates (MetaWindowActorX11 *actor_x11)
   if (!meta_surface_actor_is_visible (surface))
     return;
 
+  update_frame_bounds (actor_x11);
   check_needs_reshape (actor_x11);
   check_needs_shadow (actor_x11);
 }
@@ -1250,15 +1261,13 @@ meta_window_actor_x11_paint (ClutterActor        *actor,
        */
       if (!clip && clip_shadow_under_window (actor_x11))
         {
-          cairo_region_t *frame_bounds;
           cairo_rectangle_int_t bounds;
 
           get_shadow_bounds (actor_x11, appears_focused, &bounds);
           clip = cairo_region_create_rectangle (&bounds);
 
-          frame_bounds = meta_window_get_frame_bounds (window);
-          if (frame_bounds)
-            cairo_region_subtract (clip, frame_bounds);
+          if (actor_x11->frame_bounds)
+            cairo_region_subtract (clip, actor_x11->frame_bounds);
         }
 
       framebuffer = clutter_paint_context_get_framebuffer (paint_context);
@@ -1545,6 +1554,7 @@ meta_window_actor_x11_dispose (GObject *object)
 
   g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy);
   g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy);
+  g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
 
   g_clear_pointer (&actor_x11->shadow_class, g_free);
   g_clear_pointer (&actor_x11->focused_shadow, meta_shadow_unref);


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