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.
This commit is contained in:
Benjamin Otte 2015-09-29 23:19:07 +02:00
parent 299600a7d4
commit 6866d1c06e
4 changed files with 69 additions and 13 deletions

View File

@ -2144,6 +2144,8 @@ gtk_container_real_check_resize (GtkContainer *container)
GtkRequisition requisition; GtkRequisition requisition;
int baseline; int baseline;
if (_gtk_widget_get_alloc_needed (widget))
{
gtk_widget_get_preferred_size (widget, &requisition, NULL); gtk_widget_get_preferred_size (widget, &requisition, NULL);
gtk_widget_get_allocated_size (widget, &allocation, &baseline); gtk_widget_get_allocated_size (widget, &allocation, &baseline);
@ -2164,6 +2166,11 @@ gtk_container_real_check_resize (GtkContainer *container)
gtk_widget_size_allocate_with_baseline (widget, &allocation, baseline); gtk_widget_size_allocate_with_baseline (widget, &allocation, baseline);
} }
} }
else
{
gtk_widget_ensure_allocate (widget);
}
}
/* The container hasn't changed size but one of its children /* The container hasn't changed size but one of its children
* queued a resize request. Which means that the allocation * queued a resize request. Which means that the allocation

View File

@ -5577,6 +5577,8 @@ gtk_widget_queue_draw (GtkWidget *widget)
0, 0, rect.width, rect.height); 0, 0, rect.width, rect.height);
} }
static void
gtk_widget_set_alloc_needed (GtkWidget *widget);
/** /**
* gtk_widget_queue_allocate: * gtk_widget_queue_allocate:
* @widget: a #GtkWidget * @widget: a #GtkWidget
@ -5595,8 +5597,7 @@ gtk_widget_queue_allocate (GtkWidget *widget)
{ {
g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (GTK_IS_WIDGET (widget));
/* for now... */ gtk_widget_set_alloc_needed (widget);
gtk_widget_queue_resize (widget);
} }
/** /**
@ -6085,6 +6086,9 @@ gtk_widget_size_allocate_with_baseline (GtkWidget *widget,
} }
out: out:
if (priv->alloc_needed_on_child)
gtk_widget_ensure_allocate (widget);
gtk_widget_pop_verify_invariants (widget); gtk_widget_pop_verify_invariants (widget);
} }
@ -16234,6 +16238,14 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
if (!priv->visible) if (!priv->visible)
break; 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; widget = priv->parent;
if (widget == NULL) if (widget == NULL)
break; break;
@ -16243,6 +16255,40 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
while (TRUE); 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 void
gtk_widget_queue_resize_on_widget (GtkWidget *widget) gtk_widget_queue_resize_on_widget (GtkWidget *widget)
{ {

View File

@ -169,6 +169,7 @@ void _gtk_widget_set_shadowed (GtkWidget *widget,
gboolean _gtk_widget_get_alloc_needed (GtkWidget *widget); gboolean _gtk_widget_get_alloc_needed (GtkWidget *widget);
void gtk_widget_queue_resize_on_widget (GtkWidget *widget); void gtk_widget_queue_resize_on_widget (GtkWidget *widget);
void gtk_widget_ensure_resize (GtkWidget *widget); void gtk_widget_ensure_resize (GtkWidget *widget);
void gtk_widget_ensure_allocate (GtkWidget *widget);
void _gtk_widget_draw (GtkWidget *widget, void _gtk_widget_draw (GtkWidget *widget,
cairo_t *cr); cairo_t *cr);
void _gtk_widget_scale_changed (GtkWidget *widget); void _gtk_widget_scale_changed (GtkWidget *widget);

View File

@ -8247,6 +8247,8 @@ gtk_window_check_resize (GtkContainer *container)
* so handle it like a normal window */ * so handle it like a normal window */
if (!_gtk_widget_is_toplevel (GTK_WIDGET (container))) if (!_gtk_widget_is_toplevel (GTK_WIDGET (container)))
GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (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))) else if (gtk_widget_get_visible (GTK_WIDGET (container)))
gtk_window_move_resize (GTK_WINDOW (container)); gtk_window_move_resize (GTK_WINDOW (container));
} }