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.
This commit is contained in:
@@ -266,6 +266,7 @@ struct _GdkWindow
|
|||||||
guint num_offscreen_children;
|
guint num_offscreen_children;
|
||||||
|
|
||||||
GdkFrameClock *frame_clock; /* NULL to use from parent or default */
|
GdkFrameClock *frame_clock; /* NULL to use from parent or default */
|
||||||
|
GdkWindowUpdateHandlerFunc update_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
|
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
|
||||||
|
|||||||
@@ -3662,6 +3662,13 @@ gdk_window_invalidate_rect (GdkWindow *window,
|
|||||||
gdk_window_invalidate_rect_full (window, rect, invalidate_children);
|
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
|
static void
|
||||||
draw_ugly_color (GdkWindow *window,
|
draw_ugly_color (GdkWindow *window,
|
||||||
const cairo_region_t *region)
|
const cairo_region_t *region)
|
||||||
@@ -3749,8 +3756,8 @@ gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
|
|||||||
GdkWindowChildFunc child_func,
|
GdkWindowChildFunc child_func,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GdkWindow *impl_window;
|
|
||||||
cairo_region_t *visible_region;
|
cairo_region_t *visible_region;
|
||||||
|
cairo_rectangle_int_t r;
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
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)
|
window->window_type == GDK_WINDOW_ROOT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
visible_region = gdk_window_get_visible_region (window);
|
r.x = 0;
|
||||||
cairo_region_intersect (visible_region, region);
|
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);
|
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)
|
if (gdk_window_has_impl (window))
|
||||||
draw_ugly_color (window, visible_region);
|
{
|
||||||
|
impl_window_add_update_area (window, visible_region);
|
||||||
/* Convert to impl coords */
|
break;
|
||||||
cairo_region_translate (visible_region, window->abs_x, window->abs_y);
|
}
|
||||||
|
else
|
||||||
/* Only invalidate area if app requested expose events or if
|
{
|
||||||
we need to clear the area (by request or to emulate background
|
if (window->update_handler)
|
||||||
clearing for non-native windows or native windows with no support
|
{
|
||||||
for window backgrounds */
|
if (!window->update_handler (window, visible_region))
|
||||||
impl_window_add_update_area (impl_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);
|
cairo_region_destroy (visible_region);
|
||||||
|
|||||||
@@ -633,6 +633,10 @@ gboolean gdk_window_set_static_gravities (GdkWindow *window,
|
|||||||
gboolean use_static);
|
gboolean use_static);
|
||||||
|
|
||||||
/* GdkWindow */
|
/* 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);
|
gboolean gdk_window_has_native (GdkWindow *window);
|
||||||
void gdk_window_set_type_hint (GdkWindow *window,
|
void gdk_window_set_type_hint (GdkWindow *window,
|
||||||
|
|||||||
Reference in New Issue
Block a user