SizeRequest: Round px values up for min CSS sizes
authorDaniel Boles <dboles.src@gmail.com>
Mon, 21 May 2018 20:45:27 +0000 (21:45 +0100)
committerDaniel Boles <dboles.src@gmail.com>
Tue, 5 Jun 2018 17:49:52 +0000 (18:49 +0100)
Otherwise, requesting a min size in em where the equivalent in px had a
fractional part would lead to the widget getting allocated 1 too few px.
You could see this in the CSS property vs. allocation in the Inspector.

Note that margin/border/padding are left alone: the rationale is that we
do as browsers do, and Benjamin said we already do that for those,
whereas his tests on min-(width|height) showed otherwise. My subsequent
analysis indicated it to be far less clear-cut than that, but he remains
unconvinced that we should ceil() all the things! So just do these ones.

https://gitlab.gnome.org/GNOME/gtk/issues/1088

gtk/gtksizerequest.c

index b53acffb3e9d428a9103c7af6aed756797db2262..f85f9893379c9c5ba27a9712480179bb759dc807 100644 (file)
@@ -82,6 +82,14 @@ get_number (GtkCssStyle *style,
     return floor (d);
 }
 
+/* Special-case min-width|height to round upwards, to avoid underalloc by 1px */
+static int
+get_number_ceil (GtkCssStyle *style,
+                 guint        property)
+{
+  return ceil (_gtk_css_number_value_get (gtk_css_style_get_value (style, property), 100));
+}
+
 static void
 get_box_margin (GtkCssStyle *style,
                 GtkBorder   *margin)
@@ -166,15 +174,15 @@ gtk_widget_query_size_for_orientation (GtkWidget        *widget,
         {
           css_extra_size = margin.left + margin.right + border.left + border.right + padding.left + padding.right;
           css_extra_for_size = margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom;
-          css_min_size = get_number (style, GTK_CSS_PROPERTY_MIN_WIDTH);
-          css_min_for_size = get_number (style, GTK_CSS_PROPERTY_MIN_HEIGHT);
+          css_min_size = get_number_ceil (style, GTK_CSS_PROPERTY_MIN_WIDTH);
+          css_min_for_size = get_number_ceil (style, GTK_CSS_PROPERTY_MIN_HEIGHT);
         }
       else
         {
           css_extra_size = margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom;
           css_extra_for_size = margin.left + margin.right + border.left + border.right + padding.left + padding.right;
-          css_min_size = get_number (style, GTK_CSS_PROPERTY_MIN_HEIGHT);
-          css_min_for_size = get_number (style, GTK_CSS_PROPERTY_MIN_WIDTH);
+          css_min_size = get_number_ceil (style, GTK_CSS_PROPERTY_MIN_HEIGHT);
+          css_min_for_size = get_number_ceil (style, GTK_CSS_PROPERTY_MIN_WIDTH);
         }
 
       if (for_size < 0)