Merge branch 'more-size-allocation-fixes' into 'main'

widget: Skip popovers in allocation

See merge request GNOME/gtk!5615
This commit is contained in:
Matthias Clasen 2023-03-08 22:26:51 +00:00
commit 12858114a2

View File

@ -3871,6 +3871,29 @@ gtk_widget_adjust_size_allocation (GtkWidget *widget,
} }
} }
static void
gtk_widget_ensure_allocate_on_children (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GtkWidget *child;
g_assert (!priv->resize_needed);
g_assert (!priv->alloc_needed);
if (!priv->alloc_needed_on_child)
return;
priv->alloc_needed_on_child = FALSE;
for (child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (gtk_widget_should_layout (child))
gtk_widget_ensure_allocate (child);
}
}
/** /**
* gtk_widget_allocate: * gtk_widget_allocate:
* @widget: A `GtkWidget` * @widget: A `GtkWidget`
@ -4037,57 +4060,58 @@ gtk_widget_allocate (GtkWidget *widget,
size_changed = (priv->width != adjusted.width) || (priv->height != adjusted.height); size_changed = (priv->width != adjusted.width) || (priv->height != adjusted.height);
if (!alloc_needed && !size_changed && !baseline_changed) if (!alloc_needed && !size_changed && !baseline_changed)
goto skip_allocate;
priv->width = adjusted.width;
priv->height = adjusted.height;
priv->baseline = baseline;
priv->alloc_needed_on_child = FALSE;
if (priv->layout_manager != NULL)
{ {
gtk_layout_manager_allocate (priv->layout_manager, widget, gtk_widget_ensure_allocate_on_children (widget);
priv->width,
priv->height,
baseline);
} }
else else
{ {
GTK_WIDGET_GET_CLASS (widget)->size_allocate (widget, priv->width = adjusted.width;
priv->width, priv->height = adjusted.height;
priv->height, priv->baseline = baseline;
baseline);
}
/* Size allocation is god... after consulting god, no further requests or allocations are needed */ priv->alloc_needed_on_child = FALSE;
if (priv->layout_manager != NULL)
{
gtk_layout_manager_allocate (priv->layout_manager, widget,
priv->width,
priv->height,
baseline);
}
else
{
GTK_WIDGET_GET_CLASS (widget)->size_allocate (widget,
priv->width,
priv->height,
baseline);
}
/* Size allocation is god... after consulting god, no further requests or allocations are needed */
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
if (GTK_DISPLAY_DEBUG_CHECK (_gtk_widget_get_display (widget), GEOMETRY) && if (GTK_DISPLAY_DEBUG_CHECK (_gtk_widget_get_display (widget), GEOMETRY) &&
gtk_widget_get_resize_needed (widget)) gtk_widget_get_resize_needed (widget))
{ {
g_warning ("%s %p or a child called gtk_widget_queue_resize() during size_allocate().", g_warning ("%s %p or a child called gtk_widget_queue_resize() during size_allocate().",
gtk_widget_get_name (widget), widget); gtk_widget_get_name (widget), widget);
} }
#endif #endif
gtk_widget_ensure_resize (widget); gtk_widget_ensure_resize (widget);
priv->alloc_needed = FALSE; priv->alloc_needed = FALSE;
gtk_widget_update_paintables (widget); gtk_widget_update_paintables (widget);
if (size_changed) if (size_changed)
gtk_accessible_bounds_changed (GTK_ACCESSIBLE (widget)); gtk_accessible_bounds_changed (GTK_ACCESSIBLE (widget));
skip_allocate: if (size_changed || baseline_changed)
if (size_changed || baseline_changed) gtk_widget_queue_draw (widget);
gtk_widget_queue_draw (widget); }
else if (transform_changed && priv->parent)
if (transform_changed && priv->parent)
gtk_widget_queue_draw (priv->parent); gtk_widget_queue_draw (priv->parent);
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);
} }
@ -10637,7 +10661,10 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
break; break;
if (GTK_IS_NATIVE (widget)) if (GTK_IS_NATIVE (widget))
gtk_native_queue_relayout (GTK_NATIVE (widget)); {
gtk_native_queue_relayout (GTK_NATIVE (widget));
return;
}
widget = priv->parent; widget = priv->parent;
if (widget == NULL) if (widget == NULL)
@ -10685,18 +10712,9 @@ gtk_widget_ensure_allocate (GtkWidget *widget)
priv->allocated_size_baseline, priv->allocated_size_baseline,
gsk_transform_ref (priv->allocated_transform)); gsk_transform_ref (priv->allocated_transform));
} }
else if (priv->alloc_needed_on_child) else
{ {
GtkWidget *child; gtk_widget_ensure_allocate_on_children (widget);
priv->alloc_needed_on_child = FALSE;
for (child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
gtk_widget_ensure_allocate (child);
}
} }
} }