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.
This commit is contained in:
Owen Taylor 2001-11-04 22:57:03 +00:00 committed by Owen Taylor
parent bc5849a5e0
commit 21457ced17
22 changed files with 643 additions and 343 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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;
@ -2243,7 +2245,7 @@ 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

View File

@ -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);

View File

@ -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;

View File

@ -168,6 +168,7 @@ 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;

View File

@ -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.
@ -899,28 +896,6 @@ _gtk_container_dequeue_resize_handler (GtkContainer *container)
GTK_PRIVATE_UNSET_FLAG (container, GTK_RESIZE_PENDING);
}
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;
/* 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);
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));
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),

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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,8 +670,7 @@ _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);

View File

@ -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;

View File

@ -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,9 +2081,16 @@ 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))
{
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)
{
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;
}
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 (GTK_IS_RESIZE_CONTAINER (widget))
_gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
if (!alloc_needed && !size_changed && !position_changed)
return;
gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
if (needs_draw)
if (GTK_WIDGET_MAPPED (widget))
{
gtk_widget_queue_draw (widget);
if (widget->parent && GTK_CONTAINER (widget->parent)->reallocate_redraws)
gtk_widget_queue_draw (widget->parent);
if (GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_REDRAW_ON_ALLOC (widget) && position_changed)
{
/* Invalidate union(old_allaction,widget->allocation) in widget->window
*/
GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
gdk_region_union_with_rect (invalidate, &old_allocation);
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_widget_invalidate_widget_windows (widget, invalidate);
gdk_region_destroy (invalidate);
}
}
}
if ((size_changed || position_changed) && widget->parent &&
GTK_WIDGET_REALIZED (widget->parent) && GTK_CONTAINER (widget->parent)->reallocate_redraws)
{
GdkRegion *invalidate = gdk_region_rectangle (&widget->parent->allocation);
gtk_widget_invalidate_widget_windows (widget->parent, invalidate);
gdk_region_destroy (invalidate);
}
}
@ -3455,6 +3457,40 @@ gtk_widget_set_double_buffered (GtkWidget *widget,
GTK_WIDGET_UNSET_FLAGS (widget, GTK_DOUBLE_BUFFERED);
}
/**
* 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

View File

@ -539,24 +539,26 @@ 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);

View File

@ -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);
}
}