[gtk+/wip/simple-draw3: 10/23] Add gdk_window_set_update_handler



commit 8251523e1df75b10a0c097f194178d975777dca9
Author: Alexander Larsson <alexl redhat com>
Date:   Sun Apr 21 01:27:07 2013 +0200

    Add gdk_window_set_update_handler
    
    This lets you register callbacks for when child widgets invalidate
    areas of the window read it and/or change it.
    
    For instance, this lets you do rendering effects and keeping offscreen
    caches uptodate.

 gdk/gdkinternals.h |    1 +
 gdk/gdkwindow.c    |   54 ++++++++++++++++++++++++++++++++++++---------------
 gdk/gdkwindow.h    |    4 +++
 3 files changed, 43 insertions(+), 16 deletions(-)
---
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index d512220..604a601 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -266,6 +266,7 @@ struct _GdkWindow
   guint num_offscreen_children;
 
   GdkFrameClock *frame_clock; /* NULL to use from parent or default */
+  GdkWindowUpdateHandlerFunc update_handler;
 };
 
 #define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 3086bb3..313abc0 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -3662,6 +3662,13 @@ gdk_window_invalidate_rect (GdkWindow          *window,
   gdk_window_invalidate_rect_full (window, rect, invalidate_children);
 }
 
+void
+gdk_window_set_update_handler (GdkWindow *window,
+                              GdkWindowUpdateHandlerFunc handler)
+{
+  window->update_handler = handler;
+}
+
 static void
 draw_ugly_color (GdkWindow       *window,
                 const cairo_region_t *region)
@@ -3749,8 +3756,8 @@ gdk_window_invalidate_maybe_recurse_full (GdkWindow            *window,
                                           GdkWindowChildFunc    child_func,
                                          gpointer              user_data)
 {
-  GdkWindow *impl_window;
   cairo_region_t *visible_region;
+  cairo_rectangle_int_t r;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3763,26 +3770,41 @@ gdk_window_invalidate_maybe_recurse_full (GdkWindow            *window,
       window->window_type == GDK_WINDOW_ROOT)
     return;
 
-  visible_region = gdk_window_get_visible_region (window);
-  cairo_region_intersect (visible_region, region);
+  r.x = 0;
+  r.y = 0;
+  r.width = window->width;
+  r.height = window->height;
+
+  visible_region = cairo_region_copy (region);
+  cairo_region_intersect_rectangle (visible_region, &r);
 
   invalidate_impl_subwindows (window, region, child_func, user_data, 0, 0);
 
-  impl_window = gdk_window_get_impl_window (window);
+  if (debug_updates)
+    draw_ugly_color (window, visible_region);
 
-  if (!cairo_region_is_empty (visible_region))
+  while (window != NULL && 
+        !cairo_region_is_empty (visible_region))
     {
-      if (debug_updates)
-       draw_ugly_color (window, visible_region);
-
-      /* Convert to impl coords */
-      cairo_region_translate (visible_region, window->abs_x, window->abs_y);
-
-      /* Only invalidate area if app requested expose events or if
-        we need to clear the area (by request or to emulate background
-        clearing for non-native windows or native windows with no support
-        for window backgrounds */
-      impl_window_add_update_area (impl_window, visible_region);
+      if (gdk_window_has_impl (window))
+       {
+         impl_window_add_update_area (window, visible_region);
+         break;
+       }
+      else
+       {
+         if (window->update_handler)
+           {
+             if (!window->update_handler (window, visible_region))
+               break;
+           }
+         cairo_region_translate (visible_region,
+                                 window->x, window->y);
+         window = window->parent;
+         r.width = window->width;
+         r.height = window->height;
+         cairo_region_intersect_rectangle (visible_region, &r);
+       }
     }
 
   cairo_region_destroy (visible_region);
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index d2ee972..81d325a 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -633,6 +633,10 @@ gboolean gdk_window_set_static_gravities (GdkWindow *window,
                                           gboolean   use_static);
 
 /* GdkWindow */
+typedef gboolean (*GdkWindowUpdateHandlerFunc)  (GdkWindow *window,
+                                                cairo_region_t *region);
+void gdk_window_set_update_handler (GdkWindow *window,
+                                   GdkWindowUpdateHandlerFunc handler);
 
 gboolean      gdk_window_has_native         (GdkWindow       *window);
 void              gdk_window_set_type_hint (GdkWindow        *window,


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