diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c index 5eb19026a..801cda487 100644 --- a/src/compositor/meta-cullable.c +++ b/src/compositor/meta-cullable.c @@ -70,10 +70,16 @@ meta_cullable_cull_out_children (MetaCullable *cullable, while (clutter_actor_iter_prev (&iter, &child)) { float x, y; + gboolean needs_culling; - if (!CLUTTER_ACTOR_IS_VISIBLE (child)) + if (!META_IS_CULLABLE (child)) continue; + needs_culling = (unobscured_region != NULL && clip_region != NULL); + + if (needs_culling && !CLUTTER_ACTOR_IS_VISIBLE (child)) + needs_culling = FALSE; + /* If an actor has effects applied, then that can change the area * it paints and the opacity, so we no longer can figure out what * portion of the actor is obscured and what portion of the screen @@ -90,25 +96,29 @@ meta_cullable_cull_out_children (MetaCullable *cullable, * as well for the same reason, but omitted for simplicity in the * hopes that no-one will do that. */ - if (clutter_actor_has_effects (child)) - continue; + if (needs_culling && clutter_actor_has_effects (child)) + needs_culling = FALSE; - if (!META_IS_CULLABLE (child)) - continue; + if (needs_culling && !meta_actor_is_untransformed (child, NULL, NULL)) + needs_culling = FALSE; - if (!meta_actor_is_untransformed (child, NULL, NULL)) - continue; + if (needs_culling) + { + clutter_actor_get_position (child, &x, &y); - clutter_actor_get_position (child, &x, &y); + /* Temporarily move to the coordinate system of the actor */ + cairo_region_translate (unobscured_region, - x, - y); + cairo_region_translate (clip_region, - x, - y); - /* Temporarily move to the coordinate system of the actor */ - cairo_region_translate (unobscured_region, - x, - y); - cairo_region_translate (clip_region, - x, - y); + meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); - meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); - - cairo_region_translate (unobscured_region, x, y); - cairo_region_translate (clip_region, x, y); + cairo_region_translate (unobscured_region, x, y); + cairo_region_translate (clip_region, x, y); + } + else + { + meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL); + } } } diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 4a97199f3..985859bba 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -857,8 +857,10 @@ meta_shaped_texture_cull_out (MetaCullable *cullable, { if (priv->opaque_region) { - cairo_region_subtract (unobscured_region, priv->opaque_region); - cairo_region_subtract (clip_region, priv->opaque_region); + if (unobscured_region) + cairo_region_subtract (unobscured_region, priv->opaque_region); + if (clip_region) + cairo_region_subtract (clip_region, priv->opaque_region); } } } diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 76aaf3360..75a19e1a3 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -55,9 +55,6 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame); -void meta_window_actor_set_unobscured_region (MetaWindowActor *self, - cairo_region_t *unobscured_region); - void meta_window_actor_effect_completed (MetaWindowActor *actor, gulong event); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 4b1d0db16..00a005eb4 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1650,7 +1650,7 @@ see_region (cairo_region_t *region, * Provides a hint as to what areas of the window need to queue * redraws when damaged. Regions not in @unobscured_region are completely obscured. */ -void +static void meta_window_actor_set_unobscured_region (MetaWindowActor *self, cairo_region_t *unobscured_region) { @@ -1687,13 +1687,19 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow) { g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); - priv->shadow_clip = cairo_region_copy (beneath_region); - if (clip_shadow_under_window (self)) + if (beneath_region) { - cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window); - cairo_region_subtract (priv->shadow_clip, frame_bounds); + priv->shadow_clip = cairo_region_copy (beneath_region); + + if (clip_shadow_under_window (self)) + { + cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window); + cairo_region_subtract (priv->shadow_clip, frame_bounds); + } } + else + priv->shadow_clip = NULL; } } diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index b15486b4c..49a58b711 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -115,8 +115,6 @@ meta_window_group_paint (ClutterActor *actor) { cairo_region_t *clip_region; cairo_region_t *unobscured_region; - ClutterActorIter iter; - ClutterActor *child; cairo_rectangle_int_t visible_rect, clip_rect; int paint_x_offset, paint_y_offset; int paint_x_origin, paint_y_origin; @@ -126,18 +124,6 @@ meta_window_group_paint (ClutterActor *actor) ClutterActor *stage = clutter_actor_get_stage (actor); MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen); - /* Start off by treating all windows as completely unobscured, so damage anywhere - * in a window queues redraws, but confine it more below. */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_set_unobscured_region (window_actor, NULL); - } - } - /* Normally we expect an actor to be drawn at it's position on the screen. * However, if we're inside the paint of a ClutterClone, that won't be the * case and we need to compensate. We look at the position of the window