diff options
author | Benjamin Otte <otte.benjamin@googlemail.com> | 2020-09-09 16:44:29 +0000 |
---|---|---|
committer | Benjamin Otte <otte.benjamin@googlemail.com> | 2020-09-09 16:44:29 +0000 |
commit | 9a927176dfb87b9be4de7ef4e2002324638fc0ae (patch) | |
tree | a575063dc6320587b9ed89ed67eaec619c1ff3ca | |
parent | df7cbdfff4fe24fb92a162b119095e3afe8404a4 (diff) | |
parent | cb5b375f43bbfbd55e2d143cf55d396e5e319dc7 (diff) | |
download | gtk+-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.c | 54 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 22 |
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; |