mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-11 11:20:12 +00:00
Fixed hangs in TextView and ToolPalette
Fixed the hangs by adding a ->inside_allocation flag and avoiding to queue resizes while inside the allocation loop. The extra queue'd resizes were causing the scrolled window size_allocate() to perform the guess again and again thus causing an infinite loop.
This commit is contained in:
parent
338001ae48
commit
ae71cf7209
@ -134,6 +134,7 @@ struct _GtkScrolledWindowPrivate
|
||||
guint vscrollbar_visible : 1;
|
||||
guint window_placement : 2;
|
||||
guint focus_out : 1; /* Flag used by ::move-focus-out implementation */
|
||||
guint inside_allocate : 1;
|
||||
|
||||
gint min_content_width;
|
||||
gint min_content_height;
|
||||
@ -1444,6 +1445,30 @@ gtk_scrolled_window_relative_allocation (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrolled_window_allocate_child (GtkScrolledWindow *swindow,
|
||||
GtkAllocation *relative_allocation)
|
||||
{
|
||||
GtkScrolledWindowPrivate *priv = swindow->priv;
|
||||
GtkWidget *widget = GTK_WIDGET (swindow), *child;
|
||||
GtkAllocation allocation;
|
||||
GtkAllocation child_allocation;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
gtk_scrolled_window_relative_allocation (widget, relative_allocation);
|
||||
child_allocation.x = relative_allocation->x + allocation.x;
|
||||
child_allocation.y = relative_allocation->y + allocation.y;
|
||||
child_allocation.width = relative_allocation->width;
|
||||
child_allocation.height = relative_allocation->height;
|
||||
|
||||
priv->inside_allocate = TRUE;
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
priv->inside_allocate = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
@ -1495,15 +1520,6 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
gboolean previous_vvis;
|
||||
guint count = 0;
|
||||
|
||||
/* In the case that both scrollbars are visible in the previous round,
|
||||
* we dont do our guess-work before hand because it's possible some
|
||||
* infinite recursion was detected (leave it up to the child scrollable
|
||||
* widget in this case to drive the scrollbar visibility completely
|
||||
* with the adjustment values).
|
||||
*/
|
||||
if (!priv->vscrollbar_visible || !priv->hscrollbar_visible)
|
||||
{
|
||||
|
||||
/* Determine scrollbar visibility first via hfw apis */
|
||||
if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
{
|
||||
@ -1627,7 +1643,6 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now after guessing scrollbar visibility; fall back on the allocation loop which
|
||||
* observes the adjustments to detect scrollbar visibility and also avoids
|
||||
@ -1635,17 +1650,9 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
*/
|
||||
do
|
||||
{
|
||||
gtk_scrolled_window_relative_allocation (widget, &relative_allocation);
|
||||
|
||||
child_allocation.x = relative_allocation.x + allocation->x;
|
||||
child_allocation.y = relative_allocation.y + allocation->y;
|
||||
child_allocation.width = relative_allocation.width;
|
||||
child_allocation.height = relative_allocation.height;
|
||||
|
||||
previous_hvis = priv->hscrollbar_visible;
|
||||
previous_vvis = priv->vscrollbar_visible;
|
||||
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
gtk_scrolled_window_allocate_child (scrolled_window, &relative_allocation);
|
||||
|
||||
/* If, after the first iteration, the hscrollbar and the
|
||||
* vscrollbar flip visiblity, then we need both.
|
||||
@ -1657,10 +1664,9 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
priv->hscrollbar_visible = TRUE;
|
||||
priv->vscrollbar_visible = TRUE;
|
||||
|
||||
/* a new resize is already queued at this point,
|
||||
* so we will immediatedly get reinvoked
|
||||
*/
|
||||
return;
|
||||
gtk_scrolled_window_allocate_child (scrolled_window, &relative_allocation);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
@ -1864,7 +1870,7 @@ gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment,
|
||||
visible = priv->hscrollbar_visible;
|
||||
priv->hscrollbar_visible = (adjustment->upper - adjustment->lower >
|
||||
adjustment->page_size);
|
||||
if (priv->hscrollbar_visible != visible)
|
||||
if (!priv->inside_allocate && priv->hscrollbar_visible != visible)
|
||||
gtk_widget_queue_resize (GTK_WIDGET (scrolled_window));
|
||||
}
|
||||
}
|
||||
@ -1878,7 +1884,7 @@ gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment,
|
||||
visible = priv->vscrollbar_visible;
|
||||
priv->vscrollbar_visible = (adjustment->upper - adjustment->lower >
|
||||
adjustment->page_size);
|
||||
if (priv->vscrollbar_visible != visible)
|
||||
if (!priv->inside_allocate && priv->vscrollbar_visible != visible)
|
||||
gtk_widget_queue_resize (GTK_WIDGET (scrolled_window));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user