171 lines
6.7 KiB
Diff
171 lines
6.7 KiB
Diff
From 2d09e959344009563c9f4c7ffb026f6b98265d05 Mon Sep 17 00:00:00 2001
|
|
From: Olivier Fourdan <ofourdan@redhat.com>
|
|
Date: Wed, 26 Feb 2020 11:09:30 +0100
|
|
Subject: [PATCH 10/48] window-actor/x11: Compute client area from surface size
|
|
|
|
Commit 7dbb4bc3 cached the client area when the client was frozen.
|
|
|
|
This is not sufficient though, because the buffer size might still be
|
|
lagging waiting for the buffer from Xwayland to be committed.
|
|
|
|
So instead of caching the client size from the expected size, deduce the
|
|
client area rectangle from the surface size, like we did for the frame
|
|
bounds in commit 1ce933e2.
|
|
|
|
This partly reverts commit 7dbb4bc3 - "window-actor/x11: Cache the
|
|
client area"
|
|
|
|
https://gitlab.gnome.org/GNOME/mutter/issues/1007
|
|
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
|
|
---
|
|
src/compositor/meta-window-actor-x11.c | 69 ++++++++++++++++++++------
|
|
1 file changed, 55 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c
|
|
index 04b0ab5c5..5c0db02ce 100644
|
|
--- a/src/compositor/meta-window-actor-x11.c
|
|
+++ b/src/compositor/meta-window-actor-x11.c
|
|
@@ -99,8 +99,6 @@ struct _MetaWindowActorX11
|
|
gboolean recompute_focused_shadow;
|
|
gboolean recompute_unfocused_shadow;
|
|
gboolean is_frozen;
|
|
-
|
|
- cairo_rectangle_int_t client_area;
|
|
};
|
|
|
|
static MetaCullableInterface *cullable_parent_iface;
|
|
@@ -839,6 +837,41 @@ scan_visible_region (guchar *mask_data,
|
|
return meta_region_builder_finish (&builder);
|
|
}
|
|
|
|
+static void
|
|
+get_client_area_rect_from_texture (MetaWindowActorX11 *actor_x11,
|
|
+ MetaShapedTexture *shaped_texture,
|
|
+ cairo_rectangle_int_t *client_area)
|
|
+{
|
|
+ MetaWindow *window =
|
|
+ meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
|
|
+ cairo_rectangle_int_t surface_rect = { 0 };
|
|
+
|
|
+ surface_rect.width = meta_shaped_texture_get_width (shaped_texture);
|
|
+ surface_rect.height = meta_shaped_texture_get_height (shaped_texture);
|
|
+ meta_window_x11_surface_rect_to_client_rect (window,
|
|
+ &surface_rect,
|
|
+ client_area);
|
|
+}
|
|
+
|
|
+static void
|
|
+get_client_area_rect (MetaWindowActorX11 *actor_x11,
|
|
+ cairo_rectangle_int_t *client_area)
|
|
+{
|
|
+ MetaSurfaceActor *surface =
|
|
+ meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
|
|
+ MetaWindow *window =
|
|
+ meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
|
|
+ MetaShapedTexture *stex = meta_surface_actor_get_texture (surface);
|
|
+
|
|
+ if (!meta_window_x11_always_update_shape (window) || !stex)
|
|
+ {
|
|
+ meta_window_get_client_area_rect (window, client_area);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ get_client_area_rect_from_texture (actor_x11, stex, client_area);
|
|
+}
|
|
+
|
|
static void
|
|
build_and_scan_frame_mask (MetaWindowActorX11 *actor_x11,
|
|
cairo_region_t *shape_region)
|
|
@@ -890,6 +923,7 @@ build_and_scan_frame_mask (MetaWindowActorX11 *actor_x11,
|
|
{
|
|
cairo_region_t *frame_paint_region, *scanned_region;
|
|
cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
|
|
+ cairo_rectangle_int_t client_area;
|
|
cairo_rectangle_int_t frame_rect;
|
|
|
|
/* If we update the shape regardless of the frozen state of the actor,
|
|
@@ -899,14 +933,19 @@ build_and_scan_frame_mask (MetaWindowActorX11 *actor_x11,
|
|
* point.
|
|
*/
|
|
if (meta_window_x11_always_update_shape (window))
|
|
- meta_window_x11_buffer_rect_to_frame_rect (window, &rect, &frame_rect);
|
|
+ {
|
|
+ meta_window_x11_buffer_rect_to_frame_rect (window, &rect, &frame_rect);
|
|
+ get_client_area_rect_from_texture (actor_x11, stex, &client_area);
|
|
+ }
|
|
else
|
|
- meta_window_get_frame_rect (window, &frame_rect);
|
|
+ {
|
|
+ meta_window_get_frame_rect (window, &frame_rect);
|
|
+ meta_window_get_client_area_rect (window, &client_area);
|
|
+ }
|
|
|
|
/* Make sure we don't paint the frame over the client window. */
|
|
frame_paint_region = cairo_region_create_rectangle (&rect);
|
|
- cairo_region_subtract_rectangle (frame_paint_region,
|
|
- &actor_x11->client_area);
|
|
+ cairo_region_subtract_rectangle (frame_paint_region, &client_area);
|
|
|
|
gdk_cairo_region (cr, frame_paint_region);
|
|
cairo_clip (cr);
|
|
@@ -964,13 +1003,14 @@ update_shape_region (MetaWindowActorX11 *actor_x11)
|
|
MetaWindow *window =
|
|
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
|
|
cairo_region_t *region = NULL;
|
|
+ cairo_rectangle_int_t client_area;
|
|
+
|
|
+ get_client_area_rect (actor_x11, &client_area);
|
|
|
|
if (window->frame && window->shape_region)
|
|
{
|
|
region = cairo_region_copy (window->shape_region);
|
|
- cairo_region_translate (region,
|
|
- actor_x11->client_area.x,
|
|
- actor_x11->client_area.y);
|
|
+ cairo_region_translate (region, client_area.x, client_area.y);
|
|
}
|
|
else if (window->shape_region != NULL)
|
|
{
|
|
@@ -981,7 +1021,7 @@ update_shape_region (MetaWindowActorX11 *actor_x11)
|
|
/* If we don't have a shape on the server, that means that
|
|
* we have an implicit shape of one rectangle covering the
|
|
* entire window. */
|
|
- region = cairo_region_create_rectangle (&actor_x11->client_area);
|
|
+ region = cairo_region_create_rectangle (&client_area);
|
|
}
|
|
|
|
if (window->shape_region || window->frame)
|
|
@@ -1059,6 +1099,10 @@ update_opaque_region (MetaWindowActorX11 *actor_x11)
|
|
is_maybe_transparent = is_actor_maybe_transparent (actor_x11);
|
|
if (is_maybe_transparent && window->opaque_region)
|
|
{
|
|
+ cairo_rectangle_int_t client_area;
|
|
+
|
|
+ get_client_area_rect (actor_x11, &client_area);
|
|
+
|
|
/* The opaque region is defined to be a part of the
|
|
* window which ARGB32 will always paint with opaque
|
|
* pixels. For these regions, we want to avoid painting
|
|
@@ -1070,9 +1114,7 @@ update_opaque_region (MetaWindowActorX11 *actor_x11)
|
|
* case, graphical glitches will occur.
|
|
*/
|
|
opaque_region = cairo_region_copy (window->opaque_region);
|
|
- cairo_region_translate (opaque_region,
|
|
- actor_x11->client_area.x,
|
|
- actor_x11->client_area.y);
|
|
+ cairo_region_translate (opaque_region, client_area.x, client_area.y);
|
|
cairo_region_intersect (opaque_region, actor_x11->shape_region);
|
|
}
|
|
else if (is_maybe_transparent)
|
|
@@ -1148,7 +1190,6 @@ handle_updates (MetaWindowActorX11 *actor_x11)
|
|
if (!meta_surface_actor_is_visible (surface))
|
|
return;
|
|
|
|
- meta_window_get_client_area_rect (window, &actor_x11->client_area);
|
|
check_needs_reshape (actor_x11);
|
|
check_needs_shadow (actor_x11);
|
|
}
|
|
--
|
|
2.26.0.rc2
|
|
|