mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
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
This commit is contained in:
parent
793a9d45e1
commit
bd45a00fa3
@ -86,6 +86,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;
|
||||
@ -709,11 +711,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
|
||||
@ -1133,6 +1132,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)
|
||||
{
|
||||
@ -1204,6 +1214,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);
|
||||
}
|
||||
@ -1257,15 +1268,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);
|
||||
@ -1552,6 +1561,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);
|
||||
|
Loading…
Reference in New Issue
Block a user