[gtk+/client-side-windows] Better implementation of native clear_area



commit c84c0e92f8c80ef0d75a05f1bea94c21a6020674
Author: Alexander Larsson <alexl redhat com>
Date:   Fri Jun 26 17:07:24 2009 +0200

    Better implementation of native clear_area
    
    Last commit was bad, as it didn't clip against client side
    children. This implements such clipping first and then
    only clears the rectangles that need to be cleared.

 gdk/gdkwindow.c         |   28 ++++++++++++++++++----------
 gdk/gdkwindowimpl.h     |    7 ++-----
 gdk/x11/gdkwindow-x11.c |   28 ++++++++++++++++++----------
 3 files changed, 38 insertions(+), 25 deletions(-)
---
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 665e01f..201f84a 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -4039,9 +4039,24 @@ gdk_window_clear_region_internal (GdkWindow *window,
       if (private->redirect)
 	gdk_window_clear_backing_region_redirect (window, region);
 
-      gdk_window_clear_backing_region_direct (window, region);
-      if (send_expose)
-	gdk_window_invalidate_region (window, region, FALSE);
+      if (GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_region &&
+	  gdk_window_has_impl (private))
+	{
+	  GdkRegion *copy;
+	  copy = gdk_region_copy (region);
+	  gdk_region_intersect (copy, private->clip_region_with_children);
+
+	  GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_region
+	    (window, copy, send_expose);
+
+	  gdk_region_destroy (copy);
+	}
+      else
+	{
+	  gdk_window_clear_backing_region_direct (window, region);
+	  if (send_expose)
+	    gdk_window_invalidate_region (window, region, FALSE);
+	}
     }
 }
 
@@ -4062,13 +4077,6 @@ gdk_window_clear_area_internal (GdkWindow *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
-    {
-      GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_area
-	(window, x, y, width, height, send_expose);
-      return;
-    }
-
   /* This is what XClearArea does, and e.g. GtkCList uses it,
      so we need to duplicate that */
   if (width == 0)
diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h
index d12a872..ad1ae6b 100644
--- a/gdk/gdkwindowimpl.h
+++ b/gdk/gdkwindowimpl.h
@@ -71,11 +71,8 @@ struct _GdkWindowImplIface
                                          GdkWindow       *new_parent,
                                          gint             x,
                                          gint             y);
-  void         (* clear_area)           (GdkWindow       *window,
-                                         gint             x,
-                                         gint             y,
-					 gint             width,
-					 gint             height,
+  void         (* clear_region)         (GdkWindow       *window,
+					 GdkRegion       *region,
 					 gboolean         send_expose);
   
   void         (* set_cursor)           (GdkWindow       *window,
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index cd5a377..1c7c669 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -1661,16 +1661,24 @@ gdk_window_x11_reparent (GdkWindow *window,
 }
 
 static void
-gdk_window_x11_clear_area (GdkWindow *window,
-			   gint       x,
-			   gint       y,
-			   gint       width,
-			   gint       height,
-			   gboolean   send_expose)
+gdk_window_x11_clear_region (GdkWindow *window,
+			     GdkRegion *region,
+			     gboolean   send_expose)
 {
-  XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
-	      x, y, width, height,
-	      send_expose);
+  GdkRectangle *rectangles;
+  int n_rectangles, i;
+
+  gdk_region_get_rectangles  (region,
+			      &rectangles,
+			      &n_rectangles);
+
+  for (i = 0; i < n_rectangles; i++)
+    XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
+		rectangles[i].x, rectangles[i].y,
+		rectangles[i].width, rectangles[i].height,
+		send_expose);
+
+  g_free (rectangles);
 }
 
 static void
@@ -5569,7 +5577,7 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->set_background = gdk_window_x11_set_background;
   iface->set_back_pixmap = gdk_window_x11_set_back_pixmap;
   iface->reparent = gdk_window_x11_reparent;
-  iface->clear_area = gdk_window_x11_clear_area;
+  iface->clear_region = gdk_window_x11_clear_region;
   iface->set_cursor = gdk_window_x11_set_cursor;
   iface->get_geometry = gdk_window_x11_get_geometry;
   iface->get_root_coords = gdk_window_x11_get_root_coords;



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