From c84c0e92f8c80ef0d75a05f1bea94c21a6020674 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 26 Jun 2009 17:07:24 +0200 Subject: [PATCH] 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 665e01f78d..201f84af73 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 d12a872c5d..ad1ae6b5e3 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 cd5a3778f6..1c7c669e70 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;