[gtk+/layered-windows: 4/10] gdk: Track the layered area



commit 114702a02b91e7f898714791a6a0a83b3d5271f9
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Dec 1 13:57:47 2011 +0100

    gdk: Track the layered area

 gdk/gdkinternals.h |    5 ++++-
 gdk/gdkwindow.c    |   30 +++++++++++++++++++++++-------
 2 files changed, 27 insertions(+), 8 deletions(-)
---
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 62a58ed..e503572 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -231,7 +231,10 @@ struct _GdkWindow
   gint width, height;
 
   cairo_region_t *clip_region; /* Clip region (wrt toplevel) in window coords */
-  cairo_region_t *clip_region_with_children; /* Clip region in window coords */
+  cairo_region_t *clip_region_with_children; /* Clip region in window coords with non-layered children removed */
+  cairo_region_t *layered_region; /* Region inside clip_region that
+				     has a layered window covering it,
+				     or is layered by itself. */
   GdkCursor *cursor;
   GHashTable *device_cursor;
 
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index ef39150..22062a0 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -652,7 +652,8 @@ static void
 remove_child_area (GdkWindow *private,
 		   GdkWindow *until,
 		   gboolean for_input,
-		   cairo_region_t *region)
+		   cairo_region_t *region,
+		   cairo_region_t *layered_region)
 {
   GdkWindow *child;
   cairo_region_t *child_region;
@@ -723,7 +724,13 @@ remove_child_area (GdkWindow *private,
 	    }
 	}
 
-      cairo_region_subtract (region, child_region);
+      if (child->effective_layered)
+	{
+	  if (layered_region != NULL)
+	    cairo_region_union (layered_region, child_region);
+	}
+      else
+	cairo_region_subtract (region, child_region);
       cairo_region_destroy (child_region);
 
     }
@@ -893,7 +900,7 @@ recompute_visible_regions_internal (GdkWindow *private,
   GdkRectangle r;
   GList *l;
   GdkWindow *child;
-  cairo_region_t *new_clip, *old_clip_region_with_children;
+  cairo_region_t *new_clip, *old_clip_region_with_children, *new_layered;
   gboolean clip_region_changed;
   gboolean abs_pos_changed;
   int old_abs_x, old_abs_y;
@@ -926,6 +933,7 @@ recompute_visible_regions_internal (GdkWindow *private,
   clip_region_changed = FALSE;
   if (recalculate_clip)
     {
+      new_layered = cairo_region_create ();
       if (private->viewable)
 	{
 	  /* Calculate visible region (sans children) in parent window coords */
@@ -940,11 +948,12 @@ recompute_visible_regions_internal (GdkWindow *private,
 	      cairo_region_intersect (new_clip, private->parent->clip_region);
 
 	      /* Remove all overlapping children from parent. */
-	      remove_child_area (private->parent, private, FALSE, new_clip);
+	      remove_child_area (private->parent, private, FALSE, new_clip, new_layered);
 	    }
 
 	  /* Convert from parent coords to window coords */
 	  cairo_region_translate (new_clip, -private->x, -private->y);
+	  cairo_region_translate (new_layered, -private->x, -private->y);
 
 	  if (private->shape)
 	    cairo_region_intersect (new_clip, private->shape);
@@ -963,10 +972,17 @@ recompute_visible_regions_internal (GdkWindow *private,
       old_clip_region_with_children = private->clip_region_with_children;
       private->clip_region_with_children = cairo_region_copy (private->clip_region);
       if (private->window_type != GDK_WINDOW_ROOT)
-	remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
+	remove_child_area (private, NULL, FALSE, private->clip_region_with_children, new_layered);
 
       if (old_clip_region_with_children)
 	cairo_region_destroy (old_clip_region_with_children);
+
+      cairo_region_intersect (new_layered, private->clip_region_with_children);
+      if (private->effective_layered)
+	cairo_region_union (new_layered, private->clip_region_with_children);
+      if (private->layered_region != NULL)
+	cairo_region_destroy (private->layered_region);
+      private->layered_region = new_layered;
     }
 
   if (clip_region_changed)
@@ -7144,7 +7160,7 @@ do_child_shapes (GdkWindow *window,
   r.height = window->height;
 
   region = cairo_region_create_rectangle (&r);
-  remove_child_area (window, NULL, FALSE, region);
+  remove_child_area (window, NULL, FALSE, region, NULL);
 
   if (merge && window->shape)
     cairo_region_subtract (region, window->shape);
@@ -7263,7 +7279,7 @@ do_child_input_shapes (GdkWindow *window,
   r.height = window->height;
 
   region = cairo_region_create_rectangle (&r);
-  remove_child_area (window, NULL, TRUE, region);
+  remove_child_area (window, NULL, TRUE, region, NULL);
 
   if (merge && window->shape)
     cairo_region_subtract (region, window->shape);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]