From 65ef15812bc889a2158732d0519c899fb9e436cf Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 5 Dec 2011 12:16:55 +0100 Subject: [PATCH] gdk: gdk_window_move_region gdk_window_move_region doesn't move children, so we can't copy transparent child window regions with copyarea, so we remove these from the copy region. --- gdk/gdkwindow.c | 64 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 912b9b4e3..2fd50769b 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -650,7 +650,60 @@ gdk_window_has_no_impl (GdkWindow *window) } static void -remove_child_area (GdkWindow *private, +remove_layered_child_area (GdkWindow *window, + cairo_region_t *region) +{ + GdkWindow *child; + cairo_region_t *child_region; + GdkRectangle r; + GList *l; + + for (l = window->children; l; l = l->next) + { + child = l->data; + + /* If region is empty already, no need to do + anything potentially costly */ + if (cairo_region_is_empty (region)) + break; + + if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited) + continue; + + /* Ignore offscreen children, as they don't draw in their parent and + * don't take part in the clipping */ + if (gdk_window_is_offscreen (child)) + continue; + + /* Only non-impl children with alpha add to the layered region */ + if (!child->has_alpha_background && gdk_window_has_impl (child)) + continue; + + r.x = child->x; + r.y = child->y; + r.width = child->width; + r.height = child->height; + + /* Bail early if child totally outside region */ + if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT) + continue; + + child_region = cairo_region_create_rectangle (&r); + if (child->shape) + { + /* Adjust shape region to parent window coords */ + cairo_region_translate (child->shape, child->x, child->y); + cairo_region_intersect (child_region, child->shape); + cairo_region_translate (child->shape, -child->x, -child->y); + } + + cairo_region_subtract (region, child_region); + cairo_region_destroy (child_region); + } +} + +static void +remove_child_area (GdkWindow *window, GdkWindow *until, gboolean for_input, cairo_region_t *region, @@ -662,7 +715,7 @@ remove_child_area (GdkWindow *private, GList *l; cairo_region_t *shape; - for (l = private->children; l; l = l->next) + for (l = window->children; l; l = l->next) { child = l->data; @@ -700,7 +753,7 @@ remove_child_area (GdkWindow *private, cairo_region_intersect (child_region, child->shape); cairo_region_translate (child->shape, -child->x, -child->y); } - else if (private->window_type == GDK_WINDOW_FOREIGN) + else if (window->window_type == GDK_WINDOW_FOREIGN) { shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_shape (child); if (shape) @@ -714,7 +767,7 @@ remove_child_area (GdkWindow *private, { if (child->input_shape) cairo_region_intersect (child_region, child->input_shape); - else if (private->window_type == GDK_WINDOW_FOREIGN) + else if (window->window_type == GDK_WINDOW_FOREIGN) { shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_input_shape (child); if (shape) @@ -733,7 +786,6 @@ remove_child_area (GdkWindow *private, else cairo_region_subtract (region, child_region); cairo_region_destroy (child_region); - } } @@ -6442,11 +6494,13 @@ gdk_window_move_region (GdkWindow *window, copy_area = cairo_region_copy (region); cairo_region_intersect (copy_area, window->clip_region_with_children); cairo_region_subtract (copy_area, window->layered_region); + remove_layered_child_area (window, copy_area); /* compute destination regions */ cairo_region_translate (copy_area, dx, dy); cairo_region_intersect (copy_area, window->clip_region_with_children); cairo_region_subtract (copy_area, window->layered_region); + remove_layered_child_area (window, copy_area); /* Invalidate parts of the region (source and dest) not covered by the copy */ -- 2.43.2