diff options
Diffstat (limited to 'gtk/gtkcontainer.c')
-rw-r--r-- | gtk/gtkcontainer.c | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index e8220845db..2e9367bb58 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -44,7 +44,8 @@ enum { ARG_0, ARG_BORDER_WIDTH, ARG_RESIZE_MODE, - ARG_CHILD + ARG_CHILD, + ARG_REALLOCATE_REDRAWS }; typedef struct _GtkChildArgInfo GtkChildArgInfo; @@ -167,6 +168,7 @@ gtk_container_class_init (GtkContainerClass *class) gtk_object_add_arg_type ("GtkContainer::border_width", GTK_TYPE_ULONG, GTK_ARG_READWRITE, ARG_BORDER_WIDTH); gtk_object_add_arg_type ("GtkContainer::resize_mode", GTK_TYPE_RESIZE_MODE, GTK_ARG_READWRITE, ARG_RESIZE_MODE); gtk_object_add_arg_type ("GtkContainer::child", GTK_TYPE_WIDGET, GTK_ARG_WRITABLE, ARG_CHILD); + gtk_object_add_arg_type ("GtkContainer::reallocate_redraws", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_REALLOCATE_REDRAWS); container_signals[ADD] = gtk_signal_new ("add", @@ -607,6 +609,7 @@ gtk_container_init (GtkContainer *container) container->border_width = 0; container->need_resize = FALSE; container->resize_mode = GTK_RESIZE_PARENT; + container->reallocate_redraws = FALSE; container->resize_widgets = NULL; } @@ -621,11 +624,9 @@ gtk_container_destroy (GtkObject *object) container = GTK_CONTAINER (object); if (GTK_CONTAINER_RESIZE_PENDING (container)) - { - container_resize_queue = g_slist_remove (container_resize_queue, container); - GTK_PRIVATE_UNSET_FLAG (container, GTK_RESIZE_PENDING); - } - gtk_container_clear_resize_widgets (container); + gtk_container_dequeue_resize_handler (container); + if (container->resize_widgets) + gtk_container_clear_resize_widgets (container); gtk_container_foreach (container, (GtkCallback) gtk_widget_destroy, NULL); @@ -650,6 +651,9 @@ gtk_container_set_arg (GtkObject *object, case ARG_RESIZE_MODE: gtk_container_set_resize_mode (container, GTK_VALUE_ENUM (*arg)); break; + case ARG_REALLOCATE_REDRAWS: + gtk_container_set_reallocate_redraws (container, GTK_VALUE_BOOL (*arg)); + break; case ARG_CHILD: gtk_container_add (container, GTK_WIDGET (GTK_VALUE_OBJECT (*arg))); break; @@ -675,6 +679,9 @@ gtk_container_get_arg (GtkObject *object, case ARG_RESIZE_MODE: GTK_VALUE_ENUM (*arg) = container->resize_mode; break; + case ARG_REALLOCATE_REDRAWS: + GTK_VALUE_BOOL (*arg) = container->reallocate_redraws; + break; default: arg->type = GTK_TYPE_INVALID; break; @@ -726,6 +733,16 @@ gtk_container_remove (GtkContainer *container, } void +gtk_container_dequeue_resize_handler (GtkContainer *container) +{ + g_return_if_fail (GTK_IS_CONTAINER (container)); + g_return_if_fail (GTK_CONTAINER_RESIZE_PENDING (container)); + + container_resize_queue = g_slist_remove (container_resize_queue, container); + GTK_PRIVATE_UNSET_FLAG (container, GTK_RESIZE_PENDING); +} + +void gtk_container_clear_resize_widgets (GtkContainer *container) { GSList *node; @@ -735,11 +752,6 @@ gtk_container_clear_resize_widgets (GtkContainer *container) node = container->resize_widgets; - if (node) - gtk_signal_disconnect_by_func (GTK_OBJECT (container), - GTK_SIGNAL_FUNC (gtk_container_clear_resize_widgets), - NULL); - while (node) { GtkWidget *widget = node->data; @@ -778,6 +790,21 @@ gtk_container_set_resize_mode (GtkContainer *container, } } +void +gtk_container_set_reallocate_redraws (GtkContainer *container, + gboolean needs_redraws) +{ + g_return_if_fail (GTK_IS_CONTAINER (container)); + + needs_redraws = needs_redraws ? TRUE : FALSE; + if (needs_redraws != container->reallocate_redraws) + { + container->reallocate_redraws = needs_redraws; + if (container->reallocate_redraws) + gtk_widget_queue_draw (GTK_WIDGET (container)); + } +} + static GtkContainer* gtk_container_get_resize_container (GtkContainer *container) { @@ -833,18 +860,23 @@ 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; - - if (GTK_IS_RESIZE_CONTAINER (container)) - gtk_container_clear_resize_widgets (container); - + resize_container = gtk_container_get_resize_container (container); - + if (resize_container) { - if (GTK_WIDGET_VISIBLE (resize_container)) + if (GTK_WIDGET_VISIBLE (resize_container) && + (GTK_WIDGET_TOPLEVEL (resize_container) || GTK_WIDGET_DRAWABLE (resize_container))) { switch (resize_container->resize_mode) { @@ -860,40 +892,29 @@ gtk_container_queue_resize (GtkContainer *container) } GTK_PRIVATE_SET_FLAG (container, GTK_RESIZE_NEEDED); - if (!resize_container->resize_widgets) - gtk_signal_connect (GTK_OBJECT (resize_container), - "size_allocate", - GTK_SIGNAL_FUNC (gtk_container_clear_resize_widgets), - NULL); 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); - if (!resize_container->resize_widgets) - gtk_signal_connect (GTK_OBJECT (resize_container), - "size_allocate", - GTK_SIGNAL_FUNC (gtk_container_clear_resize_widgets), - NULL); resize_container->resize_widgets = g_slist_prepend (resize_container->resize_widgets, container); gtk_container_check_resize (resize_container); break; case GTK_RESIZE_PARENT: - /* Ignore */ + /* Ignore, should not be reached */ break; } } else { - /* We need to let hidden toplevels know that something - * changed while they where hidden. For other resize containers, - * they will get resized when they are shown. + /* we need to let hidden resize containers know that something + * changed while they where hidden (currently only evaluated by + * toplevels). */ - if (GTK_WIDGET_TOPLEVEL (resize_container)) - gtk_container_check_resize (resize_container); + resize_container->need_resize = TRUE; } } } @@ -903,7 +924,7 @@ gtk_container_check_resize (GtkContainer *container) { g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); - + gtk_signal_emit (GTK_OBJECT (container), container_signals[CHECK_RESIZE]); } @@ -976,7 +997,7 @@ gtk_container_resize_children (GtkContainer *container) * which is not the case if we got another container queued for * a resize in our anchestry. also we can skip the whole * resize_widgets checks if we are a toplevel and NEED_RESIZE. - * this code implies that our allocation is sufficient for our + * this code assumes that our allocation is sufficient for our * requisition, since otherwise we would NEED_RESIZE. */ resize_container = GTK_WIDGET (container); @@ -1006,10 +1027,6 @@ gtk_container_resize_children (GtkContainer *container) * is insufficient, since we don't need to reallocate below that. */ resize_widgets = container->resize_widgets; - if (resize_widgets) - gtk_signal_disconnect_by_func (GTK_OBJECT (container), - GTK_SIGNAL_FUNC (gtk_container_clear_resize_widgets), - NULL); container->resize_widgets = NULL; for (node = resize_widgets; node; node = node->next) { |