summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte.benjamin@googlemail.com>2020-09-09 16:44:29 +0000
committerBenjamin Otte <otte.benjamin@googlemail.com>2020-09-09 16:44:29 +0000
commit9a927176dfb87b9be4de7ef4e2002324638fc0ae (patch)
treea575063dc6320587b9ed89ed67eaec619c1ff3ca
parentdf7cbdfff4fe24fb92a162b119095e3afe8404a4 (diff)
parentcb5b375f43bbfbd55e2d143cf55d396e5e319dc7 (diff)
downloadgtk+-9a927176dfb87b9be4de7ef4e2002324638fc0ae.tar.gz
Merge branch 'wip/otte/for-master' into 'master'
Wip/otte/for master Closes #3137 See merge request GNOME/gtk!2550
-rw-r--r--gtk/gtkrevealer.c54
-rw-r--r--gtk/gtkwidget.c22
2 files changed, 60 insertions, 16 deletions
diff --git a/gtk/gtkrevealer.c b/gtk/gtkrevealer.c
index ccaaef4143..34d538d03f 100644
--- a/gtk/gtkrevealer.c
+++ b/gtk/gtkrevealer.c
@@ -457,8 +457,6 @@ gtk_revealer_size_allocate (GtkWidget *widget,
return;
}
- child_width = width;
- child_height = height;
hscale = get_child_size_scale (revealer, GTK_ORIENTATION_HORIZONTAL);
vscale = get_child_size_scale (revealer, GTK_ORIENTATION_VERTICAL);
if (hscale <= 0 || vscale <= 0)
@@ -475,29 +473,53 @@ gtk_revealer_size_allocate (GtkWidget *widget,
* some other form of clipping. We do this by reverse-applying
* the scale when size allocating the child.
*
- * Unfortunately this causes precision issues, because the scaled
- * size request is always rounded up to an integer. For instance if
- * natural with is 100, and scale is 0.001. we will request a
- * natural size of ceil(0.1) == 1, but reversing this results in 1 /
- * 0.001 == 1000 (rather than 100). In the swing case we can get the
- * scale arbitrarily near 0 causing arbitrary large problems here.
+ * Unfortunately this causes precision issues.
*
- * In order to avoid such issue we pick an arbitrary maximum upscale
- * scale factor of 100. This means that in the case where the allocated
- * size is 1 we never allocate the child at > 100 px. This means
- * that in large downscaling cases we may run into the clipping issue
- * described above. However, at these downscaling levels (100 times!)
- * we're unlikely to notice much detail anyway.
+ * So we assume that the fully expanded revealer will likely get
+ * an allocation that matches the child's minimum or natural allocation,
+ * so we special-case these two values.
+ * So when - due to the precision loss - multiple sizes would match
+ * the current allocation, we don't pick one at random, we prefer the
+ * min and nat size.
+ *
+ * On top, the scaled size request is always rounded up to an integer.
+ * For instance if natural with is 100, and scale is 0.001, we would
+ * request a natural size of ceil(0.1) == 1, but reversing this would
+ * result in 1 / 0.001 == 1000 (rather than 100).
+ * In the swing case we can get the scale arbitrarily near 0 causing
+ * arbitrary large problems.
+ * These also get avoided by the preference.
*/
if (hscale < 1.0)
{
+ int min, nat;
g_assert (vscale == 1.0);
- child_width = MIN (100*width, ceil (width / hscale));
+ gtk_widget_measure (priv->child, GTK_ORIENTATION_HORIZONTAL, height, &min, &nat, NULL, NULL);
+ if (ceil (nat * hscale) == width)
+ child_width = nat;
+ else if (ceil (min * hscale) == width)
+ child_width = min;
+ else
+ child_width = floor (width / hscale);
+ child_height = height;
}
else if (vscale < 1.0)
{
- child_height = MIN (100*height, ceil (height / vscale));
+ int min, nat;
+ child_width = width;
+ gtk_widget_measure (priv->child, GTK_ORIENTATION_VERTICAL, width, &min, &nat, NULL, NULL);
+ if (ceil (nat * vscale) == height)
+ child_height = nat;
+ else if (ceil (min * vscale) == height)
+ child_height = min;
+ else
+ child_height = floor (height / vscale);
+ }
+ else
+ {
+ child_width = width;
+ child_height = height;
}
transform = NULL;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 18038fd1a4..01ea24da59 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -3785,6 +3785,28 @@ gtk_widget_allocate (GtkWidget *widget,
"How does the code know the size to allocate?",
gtk_widget_get_name (widget), widget);
}
+ if (!GTK_IS_SCROLLABLE (widget))
+ {
+ int min;
+ gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, width, &min, NULL, NULL, NULL);
+ if (min > height)
+ {
+ g_critical ("Allocation height too small. Tried to allocate %dx%d, but %s %p needs "
+ "at least %dx%d.",
+ width, height,
+ gtk_widget_get_name (widget), widget,
+ width, min);
+ }
+ gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, height, &min, NULL, NULL, NULL);
+ if (min > width)
+ {
+ g_critical ("Allocation width too small. Tried to allocate %dx%d, but %s %p needs "
+ "at least %dx%d.",
+ width, height,
+ gtk_widget_get_name (widget), widget,
+ min, height);
+ }
+ }
#endif /* G_ENABLE_DEBUG */
alloc_needed = priv->alloc_needed;