mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
Added logic to GtkScrolledWindow when allocating height-for-width children.
This patch makes the scrolled window reconsider allocating the child the full width or height (depending on the child's request mode) without a scrollbar. For instance when the child is height-for-width; the child will first be tested if the content's height for full allocated width (without a vscrollbar) will allow the contents height for that width to fit the allocated height. Patch is a simplified version of code inspected in st-scroll-view.c. Note that this patch assumes children will begin to scroll only after reaching their minimum size; adding a property to the future GtkScrollableIface to decide whether to scroll-to-minimum or scroll-to-natural will effect this code (it should then reconsider whether the child will scroll below the natural size instead of the minimum). Patch addresses bug 629778.
This commit is contained in:
parent
0e0d938cc3
commit
e85dad38e2
@ -1453,10 +1453,132 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
child = gtk_bin_get_child (bin);
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gboolean previous_vvis;
|
||||
gint child_min_width;
|
||||
gint child_min_height;
|
||||
gboolean previous_hvis;
|
||||
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)
|
||||
{
|
||||
gtk_widget_get_preferred_width (child, &child_min_width, NULL);
|
||||
|
||||
if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
{
|
||||
/* First try without a vertical scrollbar if the content will fit the height
|
||||
* given the extra width of the scrollbar */
|
||||
gtk_widget_get_preferred_height_for_width (child, allocation->width,
|
||||
&child_min_height, NULL);
|
||||
|
||||
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
{
|
||||
/* Does the content height fit the allocation height ? */
|
||||
priv->vscrollbar_visible = child_min_height > allocation->height;
|
||||
|
||||
/* Does the content width fit the allocation with minus a possible scrollbar ? */
|
||||
priv->hscrollbar_visible =
|
||||
child_min_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
|
||||
|
||||
/* Now that we've guessed the hscrollbar, does the content height fit
|
||||
* the possible new allocation height ? */
|
||||
priv->vscrollbar_visible =
|
||||
child_min_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
|
||||
|
||||
/* Now that we've guessed the vscrollbar, does the content width fit
|
||||
* the possible new allocation width ? */
|
||||
priv->hscrollbar_visible =
|
||||
child_min_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
|
||||
}
|
||||
else /* priv->hscrollbar_policy != GTK_POLICY_AUTOMATIC */
|
||||
{
|
||||
priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
|
||||
priv->vscrollbar_visible = child_min_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
|
||||
}
|
||||
}
|
||||
else /* priv->vscrollbar_policy != GTK_POLICY_AUTOMATIC */
|
||||
{
|
||||
priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
|
||||
|
||||
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
priv->hscrollbar_visible =
|
||||
child_min_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? 0 : sb_width + sb_spacing);
|
||||
else
|
||||
priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
|
||||
}
|
||||
}
|
||||
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT */
|
||||
{
|
||||
gtk_widget_get_preferred_height (child, &child_min_height, NULL);
|
||||
|
||||
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
{
|
||||
/* First try without a horizontal scrollbar if the content will fit the width
|
||||
* given the extra height of the scrollbar */
|
||||
gtk_widget_get_preferred_width_for_height (child, allocation->height,
|
||||
&child_min_width, NULL);
|
||||
|
||||
if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
{
|
||||
/* Does the content width fit the allocation width ? */
|
||||
priv->hscrollbar_visible = child_min_width > allocation->width;
|
||||
|
||||
/* Does the content height fit the allocation with minus a possible scrollbar ? */
|
||||
priv->vscrollbar_visible =
|
||||
child_min_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
|
||||
|
||||
/* Now that we've guessed the vscrollbar, does the content width fit
|
||||
* the possible new allocation width ? */
|
||||
priv->hscrollbar_visible =
|
||||
child_min_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
|
||||
|
||||
/* Now that we've guessed the hscrollbar, does the content height fit
|
||||
* the possible new allocation height ? */
|
||||
priv->vscrollbar_visible =
|
||||
child_min_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
|
||||
}
|
||||
else /* priv->vscrollbar_policy != GTK_POLICY_AUTOMATIC */
|
||||
{
|
||||
priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
|
||||
priv->hscrollbar_visible = child_min_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
|
||||
}
|
||||
}
|
||||
else /* priv->hscrollbar_policy != GTK_POLICY_AUTOMATIC */
|
||||
{
|
||||
priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
|
||||
|
||||
if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
priv->vscrollbar_visible =
|
||||
child_min_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? 0 : sb_height + sb_spacing);
|
||||
else
|
||||
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
|
||||
* infinite recursion
|
||||
*/
|
||||
do
|
||||
{
|
||||
gtk_scrolled_window_relative_allocation (widget, &relative_allocation);
|
||||
|
Loading…
Reference in New Issue
Block a user