From 6866d1c06e338002bf584b0b9529154e33b5e86a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 29 Sep 2015 23:19:07 +0200 Subject: [PATCH] widget: Make gtk_widget_queue_allocate() not resize This commit toggles the big switch. We now don't run size_allocate() from the toplevel up anymore in cases where we don't need to. Things might be broken in subtle ways as a result of this commit. We'll have to find them and fix them. --- gtk/gtkcontainer.c | 29 ++++++++++++++---------- gtk/gtkwidget.c | 50 ++++++++++++++++++++++++++++++++++++++++-- gtk/gtkwidgetprivate.h | 1 + gtk/gtkwindow.c | 2 ++ 4 files changed, 69 insertions(+), 13 deletions(-) diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 72d9e3a600..0af6f3c677 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -2144,24 +2144,31 @@ gtk_container_real_check_resize (GtkContainer *container) GtkRequisition requisition; int baseline; - gtk_widget_get_preferred_size (widget, &requisition, NULL); - gtk_widget_get_allocated_size (widget, &allocation, &baseline); - - if (requisition.width > allocation.width || - requisition.height > allocation.height) + if (_gtk_widget_get_alloc_needed (widget)) { - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - if (GTK_IS_RESIZE_CONTAINER (container)) + gtk_widget_get_preferred_size (widget, &requisition, NULL); + gtk_widget_get_allocated_size (widget, &allocation, &baseline); + + if (requisition.width > allocation.width || + requisition.height > allocation.height) { - gtk_widget_size_allocate (widget, &allocation); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + if (GTK_IS_RESIZE_CONTAINER (container)) + { + gtk_widget_size_allocate (widget, &allocation); + } + else + gtk_widget_queue_resize (widget); + G_GNUC_END_IGNORE_DEPRECATIONS; } else - gtk_widget_queue_resize (widget); - G_GNUC_END_IGNORE_DEPRECATIONS; + { + gtk_widget_size_allocate_with_baseline (widget, &allocation, baseline); + } } else { - gtk_widget_size_allocate_with_baseline (widget, &allocation, baseline); + gtk_widget_ensure_allocate (widget); } } diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index fee05a7675..a1d5153cfd 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -5577,6 +5577,8 @@ gtk_widget_queue_draw (GtkWidget *widget) 0, 0, rect.width, rect.height); } +static void +gtk_widget_set_alloc_needed (GtkWidget *widget); /** * gtk_widget_queue_allocate: * @widget: a #GtkWidget @@ -5595,8 +5597,7 @@ gtk_widget_queue_allocate (GtkWidget *widget) { g_return_if_fail (GTK_IS_WIDGET (widget)); - /* for now... */ - gtk_widget_queue_resize (widget); + gtk_widget_set_alloc_needed (widget); } /** @@ -6085,6 +6086,9 @@ gtk_widget_size_allocate_with_baseline (GtkWidget *widget, } out: + if (priv->alloc_needed_on_child) + gtk_widget_ensure_allocate (widget); + gtk_widget_pop_verify_invariants (widget); } @@ -16234,6 +16238,14 @@ gtk_widget_set_alloc_needed (GtkWidget *widget) if (!priv->visible) break; +G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + if (GTK_IS_RESIZE_CONTAINER (widget)) + { + gtk_container_queue_resize_handler (GTK_CONTAINER (widget)); + break; + } +G_GNUC_END_IGNORE_DEPRECATIONS; + widget = priv->parent; if (widget == NULL) break; @@ -16243,6 +16255,40 @@ gtk_widget_set_alloc_needed (GtkWidget *widget) while (TRUE); } +void +gtk_widget_ensure_allocate (GtkWidget *widget) +{ + GtkWidgetPrivate *priv = widget->priv; + + gtk_widget_ensure_resize (widget); + + if (!priv->visible || !priv->child_visible) + return; + + /* This code assumes that we only reach here if the previous + * allocation is still valid (ie no resize was queued). + * If that wasn't true, the parent would have taken care of + * things. + */ + if (priv->alloc_needed) + { + GtkAllocation allocation; + int baseline; + + gtk_widget_get_allocated_size (widget, &allocation, &baseline); + gtk_widget_size_allocate_with_baseline (widget, &allocation, baseline); + } + else if (priv->alloc_needed_on_child) + { + priv->alloc_needed_on_child = FALSE; + + if (GTK_IS_CONTAINER (widget)) + gtk_container_foreach (GTK_CONTAINER (widget), + (GtkCallback) gtk_widget_ensure_allocate, + NULL); + } +} + void gtk_widget_queue_resize_on_widget (GtkWidget *widget) { diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index 814524c7e2..856fc730fb 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -169,6 +169,7 @@ void _gtk_widget_set_shadowed (GtkWidget *widget, gboolean _gtk_widget_get_alloc_needed (GtkWidget *widget); void gtk_widget_queue_resize_on_widget (GtkWidget *widget); void gtk_widget_ensure_resize (GtkWidget *widget); +void gtk_widget_ensure_allocate (GtkWidget *widget); void _gtk_widget_draw (GtkWidget *widget, cairo_t *cr); void _gtk_widget_scale_changed (GtkWidget *widget); diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index fb8c2a202c..d7ccf274c7 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -8247,6 +8247,8 @@ gtk_window_check_resize (GtkContainer *container) * so handle it like a normal window */ if (!_gtk_widget_is_toplevel (GTK_WIDGET (container))) GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (container); + else if (!_gtk_widget_get_alloc_needed (GTK_WIDGET (container))) + GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (container); else if (gtk_widget_get_visible (GTK_WIDGET (container))) gtk_window_move_resize (GTK_WINDOW (container)); }