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

View File

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

View File

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

View File

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