window-actor/x11: Compute client area from surface size
Commit7dbb4bc3
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 commit1ce933e2
. This partly reverts commit7dbb4bc3
- "window-actor/x11: Cache the client area" https://gitlab.gnome.org/GNOME/mutter/issues/1007 https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
This commit is contained in:
parent
be11525b28
commit
2d09e95934
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user