summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2001-11-04 22:57:03 +0000
committerOwen Taylor <otaylor@src.gnome.org>2001-11-04 22:57:03 +0000
commit21457ced17e61cf260e83a64152fe4573a2883da (patch)
tree73fd9a02301ff278680f3761fec932a32b2e4ee1
parentbc5849a5e0d3c30a781cd433691bf3caef989c12 (diff)
downloadgdk-pixbuf-21457ced17e61cf260e83a64152fe4573a2883da.tar.gz
Add a function gdk_window_invalidate_maybe_recurse() for use in "shallow
Sun Nov 4 16:02:08 2001 Owen Taylor <otaylor@redhat.com> * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse() for use in "shallow invalidation" of a widget. (Windows belonging to the widget, but not to the widget's children) * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED. These flags are set up on ancestors up to the resize container on queue_resize. Size requests only actually take place if GTK_REQUEST_NEEDED, size allocations only take place if GTK_ALLOC_NEEDED or the size changed. * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove container->resize_widgets and the RESIZE_NEEDED flag since the above flags are sufficient to figure out what needs to be resized/reallocated. Remove code manipulating container->resize_widget. * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this allows widgets to turn off being automatically invalidated is when they are resized. * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when a widget is resized or moved is "shallow" as described above - only the windows that need to be invalidated are invalidated. * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt: Make these widget's init functions call gtk_widget_set_redraw_on_allocate(widget,FALSE). * gtk/gtkwindow.c (gtk_window_configure_event): Call _gtk_container_queue_resize(), since we don't want redrawing. (Probably could be done for other calls to gtk_widget_queue_resize() in gtkwindow.c, but this is the most important one.) * gtk/gtkwindow.c (gtk_window_move_resize): Don't call gtk_widget_queue_draw() - size_allocate() handles that as appropriate. * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead of queue_clear() to avoid invalidating children.
-rw-r--r--ChangeLog44
-rw-r--r--ChangeLog.pre-2-044
-rw-r--r--ChangeLog.pre-2-1044
-rw-r--r--ChangeLog.pre-2-244
-rw-r--r--ChangeLog.pre-2-444
-rw-r--r--ChangeLog.pre-2-644
-rw-r--r--ChangeLog.pre-2-844
-rw-r--r--docs/Changes-2.0.txt6
-rw-r--r--docs/reference/gtk/tmpl/gtkimcontext.sgml18
-rw-r--r--gdk/gdkwindow.c68
-rw-r--r--gdk/gdkwindow.h16
-rw-r--r--gtk/gtkalignment.c1
-rw-r--r--gtk/gtkbox.c3
-rw-r--r--gtk/gtkcontainer.c250
-rw-r--r--gtk/gtkcontainer.h4
-rw-r--r--gtk/gtkframe.c2
-rw-r--r--gtk/gtkprivate.h10
-rw-r--r--gtk/gtksizegroup.c25
-rw-r--r--gtk/gtktable.c1
-rw-r--r--gtk/gtkwidget.c224
-rw-r--r--gtk/gtkwidget.h40
-rw-r--r--gtk/gtkwindow.c6
22 files changed, 641 insertions, 341 deletions
diff --git a/ChangeLog b/ChangeLog
index ec47b7bbb..620483d82 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+Sun Nov 4 16:02:08 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse()
+ for use in "shallow invalidation" of a widget. (Windows belonging
+ to the widget, but not to the widget's children)
+
+ * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+ flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED. These flags are set
+ up on ancestors up to the resize container on queue_resize. Size
+ requests only actually take place if GTK_REQUEST_NEEDED, size
+ allocations only take place if GTK_ALLOC_NEEDED or the size
+ changed.
+
+ * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+ container->resize_widgets and the RESIZE_NEEDED flag since the
+ above flags are sufficient to figure out what needs to be
+ resized/reallocated. Remove code manipulating
+ container->resize_widget.
+
+ * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+ allows widgets to turn off being automatically invalidated is when
+ they are resized.
+
+ * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+ a widget is resized or moved is "shallow" as described above -
+ only the windows that need to be invalidated are invalidated.
+
+ * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt:
+ Make these widget's init functions call
+ gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+ * gtk/gtkwindow.c (gtk_window_configure_event): Call
+ _gtk_container_queue_resize(), since we don't want
+ redrawing. (Probably could be done for other
+ calls to gtk_widget_queue_resize() in gtkwindow.c,
+ but this is the most important one.)
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+ gtk_widget_queue_draw() - size_allocate() handles
+ that as appropriate.
+
+ * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+ of queue_clear() to avoid invalidating children.
+
2001-11-04 jacob berkman <jacob@ximian.com>
* gtk/gtkmain.c (find_module): don't free the module name until
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index ec47b7bbb..620483d82 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,47 @@
+Sun Nov 4 16:02:08 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse()
+ for use in "shallow invalidation" of a widget. (Windows belonging
+ to the widget, but not to the widget's children)
+
+ * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+ flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED. These flags are set
+ up on ancestors up to the resize container on queue_resize. Size
+ requests only actually take place if GTK_REQUEST_NEEDED, size
+ allocations only take place if GTK_ALLOC_NEEDED or the size
+ changed.
+
+ * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+ container->resize_widgets and the RESIZE_NEEDED flag since the
+ above flags are sufficient to figure out what needs to be
+ resized/reallocated. Remove code manipulating
+ container->resize_widget.
+
+ * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+ allows widgets to turn off being automatically invalidated is when
+ they are resized.
+
+ * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+ a widget is resized or moved is "shallow" as described above -
+ only the windows that need to be invalidated are invalidated.
+
+ * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt:
+ Make these widget's init functions call
+ gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+ * gtk/gtkwindow.c (gtk_window_configure_event): Call
+ _gtk_container_queue_resize(), since we don't want
+ redrawing. (Probably could be done for other
+ calls to gtk_widget_queue_resize() in gtkwindow.c,
+ but this is the most important one.)
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+ gtk_widget_queue_draw() - size_allocate() handles
+ that as appropriate.
+
+ * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+ of queue_clear() to avoid invalidating children.
+
2001-11-04 jacob berkman <jacob@ximian.com>
* gtk/gtkmain.c (find_module): don't free the module name until
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index ec47b7bbb..620483d82 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,47 @@
+Sun Nov 4 16:02:08 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse()
+ for use in "shallow invalidation" of a widget. (Windows belonging
+ to the widget, but not to the widget's children)
+
+ * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+ flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED. These flags are set
+ up on ancestors up to the resize container on queue_resize. Size
+ requests only actually take place if GTK_REQUEST_NEEDED, size
+ allocations only take place if GTK_ALLOC_NEEDED or the size
+ changed.
+
+ * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+ container->resize_widgets and the RESIZE_NEEDED flag since the
+ above flags are sufficient to figure out what needs to be
+ resized/reallocated. Remove code manipulating
+ container->resize_widget.
+
+ * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+ allows widgets to turn off being automatically invalidated is when
+ they are resized.
+
+ * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+ a widget is resized or moved is "shallow" as described above -
+ only the windows that need to be invalidated are invalidated.
+
+ * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt:
+ Make these widget's init functions call
+ gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+ * gtk/gtkwindow.c (gtk_window_configure_event): Call
+ _gtk_container_queue_resize(), since we don't want
+ redrawing. (Probably could be done for other
+ calls to gtk_widget_queue_resize() in gtkwindow.c,
+ but this is the most important one.)
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+ gtk_widget_queue_draw() - size_allocate() handles
+ that as appropriate.
+
+ * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+ of queue_clear() to avoid invalidating children.
+
2001-11-04 jacob berkman <jacob@ximian.com>
* gtk/gtkmain.c (find_module): don't free the module name until
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index ec47b7bbb..620483d82 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,47 @@
+Sun Nov 4 16:02:08 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse()
+ for use in "shallow invalidation" of a widget. (Windows belonging
+ to the widget, but not to the widget's children)
+
+ * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+ flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED. These flags are set
+ up on ancestors up to the resize container on queue_resize. Size
+ requests only actually take place if GTK_REQUEST_NEEDED, size
+ allocations only take place if GTK_ALLOC_NEEDED or the size
+ changed.
+
+ * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+ container->resize_widgets and the RESIZE_NEEDED flag since the
+ above flags are sufficient to figure out what needs to be
+ resized/reallocated. Remove code manipulating
+ container->resize_widget.
+
+ * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+ allows widgets to turn off being automatically invalidated is when
+ they are resized.
+
+ * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+ a widget is resized or moved is "shallow" as described above -
+ only the windows that need to be invalidated are invalidated.
+
+ * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt:
+ Make these widget's init functions call
+ gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+ * gtk/gtkwindow.c (gtk_window_configure_event): Call
+ _gtk_container_queue_resize(), since we don't want
+ redrawing. (Probably could be done for other
+ calls to gtk_widget_queue_resize() in gtkwindow.c,
+ but this is the most important one.)
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+ gtk_widget_queue_draw() - size_allocate() handles
+ that as appropriate.
+
+ * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+ of queue_clear() to avoid invalidating children.
+
2001-11-04 jacob berkman <jacob@ximian.com>
* gtk/gtkmain.c (find_module): don't free the module name until
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index ec47b7bbb..620483d82 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,47 @@
+Sun Nov 4 16:02:08 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse()
+ for use in "shallow invalidation" of a widget. (Windows belonging
+ to the widget, but not to the widget's children)
+
+ * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+ flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED. These flags are set
+ up on ancestors up to the resize container on queue_resize. Size
+ requests only actually take place if GTK_REQUEST_NEEDED, size
+ allocations only take place if GTK_ALLOC_NEEDED or the size
+ changed.
+
+ * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+ container->resize_widgets and the RESIZE_NEEDED flag since the
+ above flags are sufficient to figure out what needs to be
+ resized/reallocated. Remove code manipulating
+ container->resize_widget.
+
+ * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+ allows widgets to turn off being automatically invalidated is when
+ they are resized.
+
+ * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+ a widget is resized or moved is "shallow" as described above -
+ only the windows that need to be invalidated are invalidated.
+
+ * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt:
+ Make these widget's init functions call
+ gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+ * gtk/gtkwindow.c (gtk_window_configure_event): Call
+ _gtk_container_queue_resize(), since we don't want
+ redrawing. (Probably could be done for other
+ calls to gtk_widget_queue_resize() in gtkwindow.c,
+ but this is the most important one.)
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+ gtk_widget_queue_draw() - size_allocate() handles
+ that as appropriate.
+
+ * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+ of queue_clear() to avoid invalidating children.
+
2001-11-04 jacob berkman <jacob@ximian.com>
* gtk/gtkmain.c (find_module): don't free the module name until
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index ec47b7bbb..620483d82 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,47 @@
+Sun Nov 4 16:02:08 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse()
+ for use in "shallow invalidation" of a widget. (Windows belonging
+ to the widget, but not to the widget's children)
+
+ * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+ flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED. These flags are set
+ up on ancestors up to the resize container on queue_resize. Size
+ requests only actually take place if GTK_REQUEST_NEEDED, size
+ allocations only take place if GTK_ALLOC_NEEDED or the size
+ changed.
+
+ * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+ container->resize_widgets and the RESIZE_NEEDED flag since the
+ above flags are sufficient to figure out what needs to be
+ resized/reallocated. Remove code manipulating
+ container->resize_widget.
+
+ * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+ allows widgets to turn off being automatically invalidated is when
+ they are resized.
+
+ * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+ a widget is resized or moved is "shallow" as described above -
+ only the windows that need to be invalidated are invalidated.
+
+ * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt:
+ Make these widget's init functions call
+ gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+ * gtk/gtkwindow.c (gtk_window_configure_event): Call
+ _gtk_container_queue_resize(), since we don't want
+ redrawing. (Probably could be done for other
+ calls to gtk_widget_queue_resize() in gtkwindow.c,
+ but this is the most important one.)
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+ gtk_widget_queue_draw() - size_allocate() handles
+ that as appropriate.
+
+ * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+ of queue_clear() to avoid invalidating children.
+
2001-11-04 jacob berkman <jacob@ximian.com>
* gtk/gtkmain.c (find_module): don't free the module name until
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index ec47b7bbb..620483d82 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,47 @@
+Sun Nov 4 16:02:08 2001 Owen Taylor <otaylor@redhat.com>
+
+ * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse()
+ for use in "shallow invalidation" of a widget. (Windows belonging
+ to the widget, but not to the widget's children)
+
+ * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+ flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED. These flags are set
+ up on ancestors up to the resize container on queue_resize. Size
+ requests only actually take place if GTK_REQUEST_NEEDED, size
+ allocations only take place if GTK_ALLOC_NEEDED or the size
+ changed.
+
+ * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+ container->resize_widgets and the RESIZE_NEEDED flag since the
+ above flags are sufficient to figure out what needs to be
+ resized/reallocated. Remove code manipulating
+ container->resize_widget.
+
+ * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+ allows widgets to turn off being automatically invalidated is when
+ they are resized.
+
+ * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+ a widget is resized or moved is "shallow" as described above -
+ only the windows that need to be invalidated are invalidated.
+
+ * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt:
+ Make these widget's init functions call
+ gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+ * gtk/gtkwindow.c (gtk_window_configure_event): Call
+ _gtk_container_queue_resize(), since we don't want
+ redrawing. (Probably could be done for other
+ calls to gtk_widget_queue_resize() in gtkwindow.c,
+ but this is the most important one.)
+
+ * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+ gtk_widget_queue_draw() - size_allocate() handles
+ that as appropriate.
+
+ * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+ of queue_clear() to avoid invalidating children.
+
2001-11-04 jacob berkman <jacob@ximian.com>
* gtk/gtkmain.c (find_module): don't free the module name until
diff --git a/docs/Changes-2.0.txt b/docs/Changes-2.0.txt
index efe9dc5e8..a5953d523 100644
--- a/docs/Changes-2.0.txt
+++ b/docs/Changes-2.0.txt
@@ -508,3 +508,9 @@ Incompatible Changes from GTK+-1.2 to GTK+-2.0:
are deprecated, as GdkRgb works on any colormap and visual. You no
longer need to gtk_widget_push_cmap (gtk_preview_get_cmap ()) in
your code.
+
+* The GtkBox, GtkTable, and GtkAlignment widgets now call
+ gtk_widget_set_redraw_on_allocate (widget, FALSE); on themselves.
+ If you want to actually draw contents in a widget derived from
+ one of these widgets, you'll probably want to change this
+ in your init() function.
diff --git a/docs/reference/gtk/tmpl/gtkimcontext.sgml b/docs/reference/gtk/tmpl/gtkimcontext.sgml
index 74f19bb38..36a2a2807 100644
--- a/docs/reference/gtk/tmpl/gtkimcontext.sgml
+++ b/docs/reference/gtk/tmpl/gtkimcontext.sgml
@@ -100,6 +100,16 @@ GtkIMContext
@imcontext: the object which received the signal.
@arg1:
+<!-- ##### SIGNAL GtkIMContext::delete-surrounding ##### -->
+<para>
+
+</para>
+
+@imcontext: the object which received the signal.
+@arg1:
+@arg2:
+@Returns:
+
<!-- ##### SIGNAL GtkIMContext::preedit-changed ##### -->
<para>
@@ -121,3 +131,11 @@ GtkIMContext
@imcontext: the object which received the signal.
+<!-- ##### SIGNAL GtkIMContext::retrieve-surrounding ##### -->
+<para>
+
+</para>
+
+@imcontext: the object which received the signal.
+@Returns:
+
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index b8729093d..e171edc2f 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -2152,10 +2152,12 @@ gdk_window_invalidate_rect (GdkWindow *window,
}
/**
- * gdk_window_invalidate_region:
+ * gdk_window_invalidate_maybe_recurse:
* @window: a #GdkWindow
* @region: a #GdkRegion
- * @invalidate_children: %TRUE to also invalidate child windows
+ * @child_func: function to use to decide if to recurse to a child,
+ * %NULL means never recurse.
+ * @child_func_data: data passed to @child_func
*
* Adds @region to the update area for @window. The update area is the
* region that needs to be redrawn, or "dirty region." The call
@@ -2169,16 +2171,16 @@ gdk_window_invalidate_rect (GdkWindow *window,
* normally there's no need to do that manually, you just need to
* invalidate regions that you know should be redrawn.
*
- * The @invalidate_children parameter controls whether the region of
+ * The @child_func parameter controls whether the region of
* each child window that intersects @region will also be invalidated.
- * If %FALSE, then the update area for child windows will remain
- * unaffected.
- *
+ * Only children for whic @child_func returns TRUE will have the area
+ * invalidated.
**/
void
-gdk_window_invalidate_region (GdkWindow *window,
- GdkRegion *region,
- gboolean invalidate_children)
+gdk_window_invalidate_maybe_recurse (GdkWindow *window,
+ GdkRegion *region,
+ gboolean (*child_func) (GdkWindow *, gpointer),
+ gpointer user_data)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkRegion *visible_region;
@@ -2233,7 +2235,7 @@ gdk_window_invalidate_region (GdkWindow *window,
gdk_window_update_idle, NULL, NULL);
}
- if (invalidate_children)
+ if (child_func)
{
GList *tmp_list;
@@ -2242,8 +2244,8 @@ gdk_window_invalidate_region (GdkWindow *window,
{
GdkWindowObject *child = tmp_list->data;
tmp_list = tmp_list->next;
-
- if (!child->input_only)
+
+ if (!child->input_only && (*child_func) ((GdkWindow *)child, user_data))
{
GdkRegion *child_region;
gint x, y;
@@ -2265,6 +2267,48 @@ gdk_window_invalidate_region (GdkWindow *window,
gdk_region_destroy (visible_region);
}
+static gboolean
+true_predicate (GdkWindow *window,
+ gpointer user_data)
+{
+ return TRUE;
+}
+
+/**
+ * gdk_window_invalidate_region:
+ * @window: a #GdkWindow
+ * @region: a #GdkRegion
+ * @invalidate_children: %TRUE to also invalidate child windows
+ *
+ * Adds @region to the update area for @window. The update area is the
+ * region that needs to be redrawn, or "dirty region." The call
+ * gdk_window_process_updates() sends one or more expose events to the
+ * window, which together cover the entire update area. An
+ * application would normally redraw the contents of @window in
+ * response to those expose events.
+ *
+ * GDK will call gdk_window_process_all_updates() on your behalf
+ * whenever your program returns to the main loop and becomes idle, so
+ * normally there's no need to do that manually, you just need to
+ * invalidate regions that you know should be redrawn.
+ *
+ * The @invalidate_children parameter controls whether the region of
+ * each child window that intersects @region will also be invalidated.
+ * If %FALSE, then the update area for child windows will remain
+ * unaffected. See gdk_window_invalidate_maybe_recurse if you need
+ * fine grained control over which children are invalidated.
+ **/
+void
+gdk_window_invalidate_region (GdkWindow *window,
+ GdkRegion *region,
+ gboolean invalidate_children)
+{
+ gdk_window_invalidate_maybe_recurse (window, region,
+ invalidate_children ?
+ true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
+ NULL);
+}
+
/**
* gdk_window_get_update_area:
* @window: a #GdkWindow
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index e4d0138fd..bca2b065d 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -491,12 +491,16 @@ void gdk_window_begin_move_drag (GdkWindow *window,
guint32 timestamp);
/* Interface for dirty-region queueing */
-void gdk_window_invalidate_rect (GdkWindow *window,
- GdkRectangle *rect,
- gboolean invalidate_children);
-void gdk_window_invalidate_region (GdkWindow *window,
- GdkRegion *region,
- gboolean invalidate_children);
+void gdk_window_invalidate_rect (GdkWindow *window,
+ GdkRectangle *rect,
+ gboolean invalidate_children);
+void gdk_window_invalidate_region (GdkWindow *window,
+ GdkRegion *region,
+ gboolean invalidate_children);
+void gdk_window_invalidate_maybe_recurse (GdkWindow *window,
+ GdkRegion *region,
+ gboolean (*child_func) (GdkWindow *, gpointer),
+ gpointer user_data);
GdkRegion *gdk_window_get_update_area (GdkWindow *window);
void gdk_window_freeze_updates (GdkWindow *window);
diff --git a/gtk/gtkalignment.c b/gtk/gtkalignment.c
index 5db7589c7..9c33fd307 100644
--- a/gtk/gtkalignment.c
+++ b/gtk/gtkalignment.c
@@ -139,6 +139,7 @@ static void
gtk_alignment_init (GtkAlignment *alignment)
{
GTK_WIDGET_SET_FLAGS (alignment, GTK_NO_WINDOW);
+ gtk_widget_set_redraw_on_allocate (GTK_WIDGET (alignment), FALSE);
alignment->xalign = 0.5;
alignment->yalign = 0.5;
diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c
index add75ec91..4c50b1137 100644
--- a/gtk/gtkbox.c
+++ b/gtk/gtkbox.c
@@ -168,7 +168,8 @@ static void
gtk_box_init (GtkBox *box)
{
GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW);
-
+ gtk_widget_set_redraw_on_allocate (GTK_WIDGET (box), FALSE);
+
box->children = NULL;
box->spacing = 0;
box->homogeneous = FALSE;
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index c25802253..a6b553da2 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -698,7 +698,6 @@ gtk_container_init (GtkContainer *container)
container->need_resize = FALSE;
container->resize_mode = GTK_RESIZE_PARENT;
container->reallocate_redraws = FALSE;
- container->resize_widgets = NULL;
}
static void
@@ -713,8 +712,6 @@ gtk_container_destroy (GtkObject *object)
if (GTK_CONTAINER_RESIZE_PENDING (container))
_gtk_container_dequeue_resize_handler (container);
- if (container->resize_widgets)
- _gtk_container_clear_resize_widgets (container);
/* do this before walking child widgets, to avoid
* removing children from focus chain one by one.
@@ -900,28 +897,6 @@ _gtk_container_dequeue_resize_handler (GtkContainer *container)
}
void
-_gtk_container_clear_resize_widgets (GtkContainer *container)
-{
- GSList *node;
-
- g_return_if_fail (container != NULL);
- g_return_if_fail (GTK_IS_CONTAINER (container));
-
- node = container->resize_widgets;
-
- while (node)
- {
- GtkWidget *widget = node->data;
-
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
- node = node->next;
- }
-
- g_slist_free (container->resize_widgets);
- container->resize_widgets = NULL;
-}
-
-void
gtk_container_set_resize_mode (GtkContainer *container,
GtkResizeMode resize_mode)
{
@@ -940,14 +915,8 @@ gtk_container_set_resize_mode (GtkContainer *container,
{
container->resize_mode = resize_mode;
- if (resize_mode == GTK_RESIZE_IMMEDIATE)
- gtk_container_check_resize (container);
- else
- {
- _gtk_container_clear_resize_widgets (container);
- gtk_widget_queue_resize (GTK_WIDGET (container));
- }
- g_object_notify (G_OBJECT (container), "resize_mode");
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ g_object_notify (G_OBJECT (container), "resize_mode");
}
}
@@ -987,7 +956,7 @@ gtk_container_get_resize_container (GtkContainer *container)
while (widget->parent)
{
widget = widget->parent;
- if (GTK_IS_RESIZE_CONTAINER (widget) && !GTK_WIDGET_RESIZE_NEEDED (widget))
+ if (GTK_IS_RESIZE_CONTAINER (widget))
break;
}
@@ -997,32 +966,52 @@ gtk_container_get_resize_container (GtkContainer *container)
static gboolean
gtk_container_idle_sizer (gpointer data)
{
+ static gboolean initialized = 0;
+ static GTimeVal last_time;
+ GTimeVal current_time;
+
GDK_THREADS_ENTER ();
- /* we may be invoked with a container_resize_queue of NULL, because
- * queue_resize could have been adding an extra idle function while
- * the queue still got processed. we better just ignore such case
- * than trying to explicitely work around them with some extra flags,
- * since it doesn't cause any actual harm.
- */
- while (container_resize_queue)
+ if (container_resize_queue)
{
- GSList *slist;
- GtkWidget *widget;
-
- slist = container_resize_queue;
- container_resize_queue = slist->next;
- widget = slist->data;
- g_slist_free_1 (slist);
-
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_PENDING);
- gtk_container_check_resize (GTK_CONTAINER (widget));
+ /* we may be invoked with a container_resize_queue of NULL, because
+ * queue_resize could have been adding an extra idle function while
+ * the queue still got processed. we better just ignore such case
+ * than trying to explicitely work around them with some extra flags,
+ * since it doesn't cause any actual harm.
+ */
+ while (container_resize_queue)
+ {
+ GSList *slist;
+ GtkWidget *widget;
+
+ slist = container_resize_queue;
+ container_resize_queue = slist->next;
+ widget = slist->data;
+ g_slist_free_1 (slist);
+
+ GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_PENDING);
+ gtk_container_check_resize (GTK_CONTAINER (widget));
+ }
+
+ gdk_window_process_all_updates ();
+
+ g_get_current_time (&current_time);
+
+ if (initialized)
+ {
+ gdouble diff = ((current_time.tv_usec - last_time.tv_usec) / 1000. +
+ (current_time.tv_sec - last_time.tv_sec) * 1000.);
+ /* g_print ("Frame time: %g msec\n", diff); */
+ }
+ else
+ initialized = TRUE;
+
+ last_time = current_time;
+
+ GDK_THREADS_LEAVE ();
}
- gdk_window_process_all_updates ();
-
- GDK_THREADS_LEAVE ();
-
return FALSE;
}
@@ -1034,21 +1023,22 @@ _gtk_container_queue_resize (GtkContainer *container)
g_return_if_fail (container != NULL);
g_return_if_fail (GTK_IS_CONTAINER (container));
- /* clear resize widgets for resize containers
- * before aborting prematurely. this is especially
- * important for toplevels which may need imemdiate
- * processing or their resize handler to be queued.
- */
- if (GTK_IS_RESIZE_CONTAINER (container))
- _gtk_container_clear_resize_widgets (container);
- if (GTK_OBJECT_DESTROYED (container) ||
- GTK_WIDGET_RESIZE_NEEDED (container))
- return;
-
resize_container = gtk_container_get_resize_container (container);
if (resize_container)
{
+ GtkWidget *widget = GTK_WIDGET (container);
+
+ while (!GTK_WIDGET_ALLOC_NEEDED (widget) || !GTK_WIDGET_REQUEST_NEEDED (widget))
+ {
+ GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
+ GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
+ if (widget == GTK_WIDGET (resize_container))
+ break;
+
+ widget = widget->parent;
+ }
+
if (GTK_WIDGET_VISIBLE (resize_container) &&
(GTK_WIDGET_TOPLEVEL (resize_container) || GTK_WIDGET_DRAWABLE (resize_container)))
{
@@ -1064,16 +1054,9 @@ _gtk_container_queue_resize (GtkContainer *container)
NULL);
container_resize_queue = g_slist_prepend (container_resize_queue, resize_container);
}
-
- GTK_PRIVATE_SET_FLAG (container, GTK_RESIZE_NEEDED);
- resize_container->resize_widgets =
- g_slist_prepend (resize_container->resize_widgets, container);
break;
case GTK_RESIZE_IMMEDIATE:
- GTK_PRIVATE_SET_FLAG (container, GTK_RESIZE_NEEDED);
- resize_container->resize_widgets =
- g_slist_prepend (resize_container->resize_widgets, container);
gtk_container_check_resize (resize_container);
break;
@@ -1134,135 +1117,24 @@ gtk_container_real_check_resize (GtkContainer *container)
* queued a resize request. Which means that the allocation
* is not sufficient for the requisition of some child.
* We've already performed a size request at this point,
- * so we simply need to run through the list of resize
- * widgets and reallocate their sizes appropriately. We
- * make the optimization of not performing reallocation
- * for a widget who also has a parent in the resize widgets
- * list. GTK_RESIZE_NEEDED is used for flagging those
- * parents inside this function.
+ * so we simply need to reallocate and let the allocation
+ * trickle down via GTK_WIDGET_ALLOC_NEEDED flags.
*/
void
gtk_container_resize_children (GtkContainer *container)
{
GtkWidget *widget;
- GtkWidget *resize_container;
- GSList *resize_widgets;
- GSList *resize_containers;
- GSList *node;
/* resizing invariants:
* toplevels have *always* resize_mode != GTK_RESIZE_PARENT set.
- * containers with resize_mode==GTK_RESIZE_PARENT have to have resize_widgets
- * set to NULL.
- * containers that are flagged RESIZE_NEEDED must have resize_widgets set to
- * NULL, or are toplevels (thus have ->parent set to NULL).
- * widgets that are in some container->resize_widgets list must be flagged with
- * RESIZE_NEEDED.
- * widgets that have RESIZE_NEEDED set must be referenced in some
- * GTK_IS_RESIZE_CONTAINER (container)->resize_widgets list.
* containers that have an idle sizer pending must be flagged with
* RESIZE_PENDING.
*/
-
g_return_if_fail (container != NULL);
g_return_if_fail (GTK_IS_CONTAINER (container));
- /* we first check out if we actually need to perform a resize,
- * which is not the case if we got another container queued for
- * a resize in our ancestry. also we can skip the whole
- * resize_widgets checks if we are a toplevel and NEED_RESIZE.
- * this code assumes that our allocation is sufficient for our
- * requisition, since otherwise we would NEED_RESIZE.
- */
- resize_container = GTK_WIDGET (container);
- while (resize_container)
- {
- if (GTK_WIDGET_RESIZE_NEEDED (resize_container))
- break;
- resize_container = resize_container->parent;
- }
- if (resize_container)
- {
- /* queue_resize and size_allocate both clear our
- * resize_widgets list.
- */
- if (resize_container->parent)
- _gtk_container_queue_resize (container);
- else
- gtk_widget_size_allocate (GTK_WIDGET (container),
- &GTK_WIDGET (container)->allocation);
- return;
- }
-
- resize_container = GTK_WIDGET (container);
-
- /* we now walk the ancestry for all resize widgets as long
- * as they are our children and as long as their allocation
- * is insufficient, since we don't need to reallocate below that.
- */
- resize_widgets = container->resize_widgets;
- container->resize_widgets = NULL;
- for (node = resize_widgets; node; node = node->next)
- {
- widget = node->data;
-
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
-
- while (widget->parent != resize_container &&
- ((widget->allocation.width < widget->requisition.width) ||
- (widget->allocation.height < widget->requisition.height)))
- widget = widget->parent;
-
- GTK_PRIVATE_SET_FLAG (widget, GTK_RESIZE_NEEDED);
- node->data = widget;
- }
-
- /* for the newly setup resize_widgets list, we now walk each widget's
- * ancestry to sort those widgets out that have RESIZE_NEEDED parents.
- * we can safely stop the walk if we are the parent, since we checked
- * our own ancestry already.
- */
- resize_containers = NULL;
- for (node = resize_widgets; node; node = node->next)
- {
- GtkWidget *parent;
-
- widget = node->data;
-
- if (!GTK_WIDGET_RESIZE_NEEDED (widget))
- continue;
-
- parent = widget->parent;
-
- while (parent != resize_container)
- {
- if (GTK_WIDGET_RESIZE_NEEDED (parent))
- {
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
- widget = parent;
- }
- parent = parent->parent;
- }
-
- if (!g_slist_find (resize_containers, widget))
- {
- resize_containers = g_slist_prepend (resize_containers, widget);
- gtk_widget_ref (widget);
- }
- }
- g_slist_free (resize_widgets);
-
- for (node = resize_containers; node; node = node->next)
- {
- widget = node->data;
-
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
-
- gtk_widget_size_allocate (widget, &widget->allocation);
-
- gtk_widget_unref (widget);
- }
- g_slist_free (resize_containers);
+ widget = GTK_WIDGET (container);
+ gtk_widget_size_allocate (widget, &widget->allocation);
}
/**
@@ -1630,8 +1502,6 @@ get_allocation_coords (GtkContainer *container,
GtkWidget *widget,
GdkRectangle *allocation)
{
- GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
-
*allocation = widget->allocation;
return gtk_widget_translate_coordinates (widget, GTK_WIDGET (container),
diff --git a/gtk/gtkcontainer.h b/gtk/gtkcontainer.h
index 98f7be851..ae8095aee 100644
--- a/gtk/gtkcontainer.h
+++ b/gtk/gtkcontainer.h
@@ -63,10 +63,6 @@ struct _GtkContainer
guint resize_mode : 2;
guint reallocate_redraws : 1;
guint has_focus_chain : 1;
-
- /* The list of children that requested a resize
- */
- GSList *resize_widgets;
};
struct _GtkContainerClass
diff --git a/gtk/gtkframe.c b/gtk/gtkframe.c
index 7efc069a5..95287ae2d 100644
--- a/gtk/gtkframe.c
+++ b/gtk/gtkframe.c
@@ -613,7 +613,7 @@ gtk_frame_size_allocate (GtkWidget *widget,
new_allocation.y != frame->child_allocation.y ||
new_allocation.width != frame->child_allocation.width ||
new_allocation.height != frame->child_allocation.height))
- gtk_widget_queue_clear (widget);
+ gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
gtk_widget_size_allocate (bin->child, &new_allocation);
diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h
index 0de6707cf..86935ee1b 100644
--- a/gtk/gtkprivate.h
+++ b/gtk/gtkprivate.h
@@ -43,14 +43,16 @@ typedef enum
{
PRIVATE_GTK_USER_STYLE = 1 << 0,
PRIVATE_GTK_RESIZE_PENDING = 1 << 2,
- PRIVATE_GTK_RESIZE_NEEDED = 1 << 3,
PRIVATE_GTK_LEAVE_PENDING = 1 << 4,
PRIVATE_GTK_HAS_SHAPE_MASK = 1 << 5,
PRIVATE_GTK_IN_REPARENT = 1 << 6,
PRIVATE_GTK_DIRECTION_SET = 1 << 7, /* If the reading direction is not DIR_NONE */
PRIVATE_GTK_DIRECTION_LTR = 1 << 8, /* If the reading direction is DIR_LTR */
PRIVATE_GTK_ANCHORED = 1 << 9, /* If widget has a GtkWindow ancestor */
- PRIVATE_GTK_CHILD_VISIBLE = 1 << 10 /* If widget should be mapped when parent is mapped */
+ PRIVATE_GTK_CHILD_VISIBLE = 1 << 10, /* If widget should be mapped when parent is mapped */
+ PRIVATE_GTK_REDRAW_ON_ALLOC = 1 << 11, /* If we should queue a draw on the entire widget when it is reallocated */
+ PRIVATE_GTK_ALLOC_NEEDED = 1 << 12, /* If we we should allocate even if the allocation is the same */
+ PRIVATE_GTK_REQUEST_NEEDED = 1 << 13 /* Whether we need to call gtk_widget_size_request */
} GtkPrivateFlags;
/* Macros for extracting a widgets private_flags from GtkWidget.
@@ -58,7 +60,6 @@ typedef enum
#define GTK_PRIVATE_FLAGS(wid) (GTK_WIDGET (wid)->private_flags)
#define GTK_WIDGET_USER_STYLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_USER_STYLE) != 0)
#define GTK_CONTAINER_RESIZE_PENDING(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_RESIZE_PENDING) != 0)
-#define GTK_WIDGET_RESIZE_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_RESIZE_NEEDED) != 0)
#define GTK_WIDGET_LEAVE_PENDING(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_LEAVE_PENDING) != 0)
#define GTK_WIDGET_HAS_SHAPE_MASK(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_SHAPE_MASK) != 0)
#define GTK_WIDGET_IN_REPARENT(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_IN_REPARENT) != 0)
@@ -66,6 +67,9 @@ typedef enum
#define GTK_WIDGET_DIRECTION_LTR(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_LTR) != 0)
#define GTK_WIDGET_ANCHORED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ANCHORED) != 0)
#define GTK_WIDGET_CHILD_VISIBLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_CHILD_VISIBLE) != 0)
+#define GTK_WIDGET_REDRAW_ON_ALLOC(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REDRAW_ON_ALLOC) != 0)
+#define GTK_WIDGET_ALLOC_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ALLOC_NEEDED) != 0)
+#define GTK_WIDGET_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REQUEST_NEEDED) != 0)
/* Macros for setting and clearing private widget flags.
* we use a preprocessor string concatenation here for a clear
diff --git a/gtk/gtksizegroup.c b/gtk/gtksizegroup.c
index 3116183ae..2ceca3c4d 100644
--- a/gtk/gtksizegroup.c
+++ b/gtk/gtksizegroup.c
@@ -20,6 +20,7 @@
#include "gtkcontainer.h"
#include "gtkintl.h"
+#include "gtkprivate.h"
#include "gtksignal.h"
#include "gtksizegroup.h"
@@ -116,8 +117,8 @@ add_widget_to_closure (GtkWidget *widget,
static void
real_queue_resize (GtkWidget *widget)
{
- if (GTK_IS_RESIZE_CONTAINER (widget))
- _gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
+ GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
+ GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
if (widget->parent)
_gtk_container_queue_resize (GTK_CONTAINER (widget->parent));
@@ -476,12 +477,23 @@ get_base_dimension (GtkWidget *widget,
}
}
+static void
+do_size_request (GtkWidget *widget)
+{
+ if (GTK_WIDGET_REQUEST_NEEDED (widget))
+ {
+ gtk_widget_ensure_style (widget);
+ gtk_signal_emit_by_name (GTK_OBJECT (widget), "size_request", &widget->requisition);
+
+ GTK_PRIVATE_UNSET_FLAG (widget, GTK_REQUEST_NEEDED);
+ }
+}
+
static gint
compute_base_dimension (GtkWidget *widget,
GtkSizeGroupMode mode)
{
- gtk_widget_ensure_style (widget);
- gtk_signal_emit_by_name (GTK_OBJECT (widget), "size_request", &widget->requisition);
+ do_size_request (widget);
return get_base_dimension (widget, mode);
}
@@ -658,9 +670,8 @@ _gtk_size_group_compute_requisition (GtkWidget *widget,
}
else
{
- gtk_widget_ensure_style (widget);
- gtk_signal_emit_by_name (GTK_OBJECT (widget), "size_request", &widget->requisition);
-
+ do_size_request (widget);
+
if (requisition)
get_fast_child_requisition (widget, requisition);
}
diff --git a/gtk/gtktable.c b/gtk/gtktable.c
index 86b8edb90..18c697f55 100644
--- a/gtk/gtktable.c
+++ b/gtk/gtktable.c
@@ -452,6 +452,7 @@ static void
gtk_table_init (GtkTable *table)
{
GTK_WIDGET_SET_FLAGS (table, GTK_NO_WINDOW);
+ gtk_widget_set_redraw_on_allocate (GTK_WIDGET (table), FALSE);
table->children = NULL;
table->rows = NULL;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 20da6016c..6ee796b39 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -213,6 +213,9 @@ static void gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
static AtkObject* gtk_widget_real_get_accessible (GtkWidget *widget);
static void gtk_widget_accessible_interface_init (AtkImplementorIface *iface);
static AtkObject* gtk_widget_ref_accessible (AtkImplementor *implementor);
+static void gtk_widget_invalidate_widget_windows (GtkWidget *widget,
+ GdkRegion *region);
+
/* --- variables --- */
static gpointer parent_class = NULL;
@@ -1248,6 +1251,8 @@ gtk_widget_init (GtkWidget *widget)
(composite_child_stack ? GTK_COMPOSITE_CHILD : 0) |
GTK_DOUBLE_BUFFERED);
+ GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
+
widget->style = gtk_widget_get_default_style ();
g_object_ref (widget->style);
}
@@ -1412,7 +1417,6 @@ gtk_widget_unparent (GtkWidget *widget)
{
GObjectNotifyQueue *nqueue;
GtkWidget *toplevel;
- GtkWidget *ancestor;
GtkWidget *old_parent;
g_return_if_fail (GTK_IS_WIDGET (widget));
@@ -1469,64 +1473,6 @@ gtk_widget_unparent (GtkWidget *widget)
else
toplevel = NULL;
- if (GTK_IS_RESIZE_CONTAINER (widget))
- _gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
-
- /* Remove the widget and all its children from any ->resize_widgets list
- * of all the parents in our branch. This code should move into gtkcontainer.c
- * somwhen, since we mess around with ->resize_widgets, which is
- * actually not of our business.
- *
- * Two ways to make this prettier:
- * Write a g_slist_conditional_remove (GSList, gboolean (*)(gpointer))
- * Change resize_widgets to a GList
- */
- ancestor = widget->parent;
- while (ancestor)
- {
- GSList *slist;
- GSList *prev;
-
- if (!GTK_CONTAINER (ancestor)->resize_widgets)
- {
- ancestor = ancestor->parent;
- continue;
- }
-
- prev = NULL;
- slist = GTK_CONTAINER (ancestor)->resize_widgets;
- while (slist)
- {
- GtkWidget *child;
- GtkWidget *parent;
- GSList *last;
-
- last = slist;
- slist = last->next;
- child = last->data;
-
- parent = child;
- while (parent && (parent != widget))
- parent = parent->parent;
-
- if (parent == widget)
- {
- GTK_PRIVATE_UNSET_FLAG (child, GTK_RESIZE_NEEDED);
-
- if (prev)
- prev->next = slist;
- else
- GTK_CONTAINER (ancestor)->resize_widgets = slist;
-
- g_slist_free_1 (last);
- }
- else
- prev = last;
- }
-
- ancestor = ancestor->parent;
- }
-
gtk_widget_queue_clear_child (widget);
/* Reset the width and height here, to force reallocation if we
@@ -1831,7 +1777,7 @@ gtk_widget_map (GtkWidget *widget)
gtk_signal_emit (GTK_OBJECT (widget), widget_signals[MAP]);
if (GTK_WIDGET_NO_WINDOW (widget))
- gtk_widget_queue_draw (widget);
+ gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
}
}
@@ -1851,7 +1797,7 @@ gtk_widget_unmap (GtkWidget *widget)
if (GTK_WIDGET_MAPPED (widget))
{
if (GTK_WIDGET_NO_WINDOW (widget))
- gtk_widget_queue_clear_child (widget);
+ gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNMAP]);
}
}
@@ -2135,10 +2081,17 @@ gtk_widget_queue_clear (GtkWidget *widget)
void
gtk_widget_queue_resize (GtkWidget *widget)
{
+ GdkRegion *region;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
- gtk_widget_queue_clear (widget);
-
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ region = gdk_region_rectangle (&widget->allocation);
+ gtk_widget_invalidate_widget_windows (widget, region);
+ gdk_region_destroy (region);
+ }
+
_gtk_size_group_queue_resize (widget);
}
@@ -2208,13 +2161,6 @@ gtk_widget_size_request (GtkWidget *widget,
#endif /* G_ENABLE_DEBUG */
_gtk_size_group_compute_requisition (widget, requisition);
-
-#if 0
- if (requisition)
- gtk_widget_get_child_requisition (widget, requisition);
-
- gtk_widget_unref (widget);
-#endif
}
/**
@@ -2247,6 +2193,38 @@ gtk_widget_get_child_requisition (GtkWidget *widget,
_gtk_size_group_get_child_requisition (widget, requisition);
}
+static gboolean
+invalidate_predicate (GdkWindow *window,
+ gpointer data)
+{
+ gpointer user_data;
+
+ gdk_window_get_user_data (window, &user_data);
+
+ return (user_data == data);
+}
+
+/* Invalidate @region in widget->window and all children
+ * of widget->window owned by widget. @region is in the
+ * same coordinates as widget->allocation and will be
+ * modified by this call.
+ */
+static void
+gtk_widget_invalidate_widget_windows (GtkWidget *widget,
+ GdkRegion *region)
+{
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ {
+ int x, y;
+
+ gdk_window_get_position (widget->window, &x, &y);
+ gdk_region_offset (region, -x, -y);
+ }
+
+ gdk_window_invalidate_maybe_recurse (widget->window, region,
+ invalidate_predicate, widget);
+}
+
/**
* gtk_widget_size_allocate:
* @widget: a #GtkWidget
@@ -2261,11 +2239,18 @@ gtk_widget_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkWidgetAuxInfo *aux_info;
- GtkAllocation real_allocation;
- gboolean needs_draw = FALSE;
+ GdkRectangle real_allocation;
+ GdkRectangle old_allocation;
+ gboolean alloc_needed;
+ gboolean size_changed;
+ gboolean position_changed;
g_return_if_fail (GTK_IS_WIDGET (widget));
-
+
+ alloc_needed = GTK_WIDGET_ALLOC_NEEDED (widget);
+ GTK_PRIVATE_UNSET_FLAG (widget, GTK_ALLOC_NEEDED);
+
+ old_allocation = widget->allocation;
real_allocation = *allocation;
aux_info =_gtk_widget_get_aux_info (widget, FALSE);
@@ -2287,33 +2272,50 @@ gtk_widget_size_allocate (GtkWidget *widget,
real_allocation.width = MAX (real_allocation.width, 1);
real_allocation.height = MAX (real_allocation.height, 1);
- if (GTK_WIDGET_NO_WINDOW (widget))
+ size_changed = (old_allocation.width != real_allocation.width ||
+ old_allocation.height != real_allocation.height);
+ position_changed = (old_allocation.x != real_allocation.x ||
+ old_allocation.y != real_allocation.y);
+
+ if (!alloc_needed && !size_changed && !position_changed)
+ return;
+
+ gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
+
+ if (GTK_WIDGET_MAPPED (widget))
{
- if (widget->allocation.x != real_allocation.x ||
- widget->allocation.y != real_allocation.y ||
- widget->allocation.width != real_allocation.width ||
- widget->allocation.height != real_allocation.height)
+ if (GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_REDRAW_ON_ALLOC (widget) && position_changed)
{
- gtk_widget_queue_clear_child (widget);
- needs_draw = TRUE;
- }
- }
- else if (widget->allocation.width != real_allocation.width ||
- widget->allocation.height != real_allocation.height)
- {
- needs_draw = TRUE;
- }
+ /* Invalidate union(old_allaction,widget->allocation) in widget->window
+ */
+ GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
+ gdk_region_union_with_rect (invalidate, &old_allocation);
- if (GTK_IS_RESIZE_CONTAINER (widget))
- _gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
+ gdk_window_invalidate_region (widget->window, invalidate, FALSE);
+ gdk_region_destroy (invalidate);
+ }
+
+ if (size_changed)
+ {
+ if (GTK_WIDGET_REDRAW_ON_ALLOC (widget))
+ {
+ /* Invalidate union(old_allaction,widget->allocation) in widget->window and descendents owned by widget
+ */
+ GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
+ gdk_region_union_with_rect (invalidate, &old_allocation);
- gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
+ gtk_widget_invalidate_widget_windows (widget, invalidate);
+ gdk_region_destroy (invalidate);
+ }
+ }
+ }
- if (needs_draw)
+ if ((size_changed || position_changed) && widget->parent &&
+ GTK_WIDGET_REALIZED (widget->parent) && GTK_CONTAINER (widget->parent)->reallocate_redraws)
{
- gtk_widget_queue_draw (widget);
- if (widget->parent && GTK_CONTAINER (widget->parent)->reallocate_redraws)
- gtk_widget_queue_draw (widget->parent);
+ GdkRegion *invalidate = gdk_region_rectangle (&widget->parent->allocation);
+ gtk_widget_invalidate_widget_windows (widget->parent, invalidate);
+ gdk_region_destroy (invalidate);
}
}
@@ -3456,6 +3458,40 @@ gtk_widget_set_double_buffered (GtkWidget *widget,
}
/**
+ * gtk_widget_set_redraw_on_allocate:
+ * @widget: a #GtkWidget
+ * @redraw_on_allocate: if %TRUE, the entire widget will be redrawn
+ * when it is allocated to a new size. Otherwise, only the
+ * new portion of the widget will be redrawn.
+ *
+ * Sets whether a when a widgets size allocation changes, the entire
+ * widget is queued for drawing. By default, this setting is %TRUE and
+ * the entire widget is redrawn on every size change. If your widget
+ * leaves the upper left are unchanged when made bigger, turning this
+ * setting on will improve performance.
+
+ * Note that for NO_WINDOW widgets setting this flag to %FALSE turns
+ * off all allocation on resizing: the widget will not even redraw if
+ * its position changes; this is to allow containers that don't draw
+ * anything to avoid excess invalidations. If you set this flag on a
+ * NO_WINDOW widget that _does_ draw on widget->window, you are
+ * responsible for invalidating both the old and new allocation of the
+ * widget when the widget is moved and responsible for invalidating
+ * regions newly when the widget increases size.
+ **/
+void
+gtk_widget_set_redraw_on_allocate (GtkWidget *widget,
+ gboolean redraw_on_allocate)
+{
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ if (redraw_on_allocate)
+ GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
+ else
+ GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
+}
+
+/**
* gtk_widget_set_sensitive:
* @widget: a @widget
* @sensitive: %TRUE to make the widget sensitive
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 111c77926..3d9969a24 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -539,25 +539,27 @@ gboolean gtk_widget_is_focus (GtkWidget *widget);
void gtk_widget_grab_focus (GtkWidget *widget);
void gtk_widget_grab_default (GtkWidget *widget);
-void gtk_widget_set_name (GtkWidget *widget,
- const gchar *name);
-G_CONST_RETURN gchar* gtk_widget_get_name (GtkWidget *widget);
-void gtk_widget_set_state (GtkWidget *widget,
- GtkStateType state);
-void gtk_widget_set_sensitive (GtkWidget *widget,
- gboolean sensitive);
-void gtk_widget_set_app_paintable (GtkWidget *widget,
- gboolean app_paintable);
-void gtk_widget_set_double_buffered (GtkWidget *widget,
- gboolean double_buffered);
-void gtk_widget_set_parent (GtkWidget *widget,
- GtkWidget *parent);
-void gtk_widget_set_parent_window (GtkWidget *widget,
- GdkWindow *parent_window);
-void gtk_widget_set_child_visible (GtkWidget *widget,
- gboolean is_visible);
-gboolean gtk_widget_get_child_visible (GtkWidget *widget);
-
+void gtk_widget_set_name (GtkWidget *widget,
+ const gchar *name);
+G_CONST_RETURN gchar* gtk_widget_get_name (GtkWidget *widget);
+void gtk_widget_set_state (GtkWidget *widget,
+ GtkStateType state);
+void gtk_widget_set_sensitive (GtkWidget *widget,
+ gboolean sensitive);
+void gtk_widget_set_app_paintable (GtkWidget *widget,
+ gboolean app_paintable);
+void gtk_widget_set_double_buffered (GtkWidget *widget,
+ gboolean double_buffered);
+void gtk_widget_set_redraw_on_allocate (GtkWidget *widget,
+ gboolean redraw_on_allocate);
+void gtk_widget_set_parent (GtkWidget *widget,
+ GtkWidget *parent);
+void gtk_widget_set_parent_window (GtkWidget *widget,
+ GdkWindow *parent_window);
+void gtk_widget_set_child_visible (GtkWidget *widget,
+ gboolean is_visible);
+gboolean gtk_widget_get_child_visible (GtkWidget *widget);
+
GtkWidget *gtk_widget_get_parent (GtkWidget *widget);
GdkWindow *gtk_widget_get_parent_window (GtkWidget *widget);
gboolean gtk_widget_child_focus (GtkWidget *widget,
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 6bedb3aab..412a57f89 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -3366,7 +3366,7 @@ gtk_window_configure_event (GtkWidget *widget,
widget->allocation.width = event->width;
widget->allocation.height = event->height;
- gtk_widget_queue_resize (widget);
+ _gtk_container_queue_resize (GTK_CONTAINER (widget));
return TRUE;
}
@@ -4144,7 +4144,6 @@ gtk_window_move_resize (GtkWindow *window)
/* gtk_window_configure_event() filled in widget->allocation */
allocation = widget->allocation;
gtk_widget_size_allocate (widget, &allocation);
- gtk_widget_queue_draw (widget);
/* If the configure request changed, it means that
* we either:
@@ -4284,8 +4283,7 @@ gtk_window_move_resize (GtkWindow *window)
/* And run the resize queue.
*/
- if (container->resize_widgets)
- gtk_container_resize_children (container);
+ gtk_container_resize_children (container);
}
}