[gtk/wip/otte/for-master: 2/2] boxlayout: Compute opposite size properly




commit 5c9ae289373b967ba395fbe562c6db4c83e6415c
Author: Benjamin Otte <otte redhat com>
Date:   Fri Nov 5 20:30:49 2021 +0100

    boxlayout: Compute opposite size properly
    
    For size -1 in the opposite orientation, GtkBoxLayout used to measure
    the children based on their min size in the box's orientation instead of
    -1. That wasn't really intended, but was a side effect of how the sizing
    code did (not) distribute extra size above the minimum size.
    
    This is clearly not what we want.
    What we want is measuring the orientation as is for size -1. Then we
    want to just take the maximum of all children and use that.
    
    A reftest is incldued that ensures a vbox wraps a label just like an
    hbox does.

 gtk/gtkboxlayout.c                                 | 52 ++++++++++++++++++++--
 testsuite/reftests/meson.build                     |  2 +
 .../vbox-with-max-width-chars-label.ref.ui         | 18 ++++++++
 .../reftests/vbox-with-max-width-chars-label.ui    | 18 ++++++++
 4 files changed, 86 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkboxlayout.c b/gtk/gtkboxlayout.c
index f080748830..99feca37e5 100644
--- a/gtk/gtkboxlayout.c
+++ b/gtk/gtkboxlayout.c
@@ -256,11 +256,46 @@ gtk_box_layout_compute_size (GtkBoxLayout *self,
 static void
 gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
                                       GtkWidget    *widget,
-                                      int           for_size,
                                       int          *minimum,
                                       int          *natural,
                                       int          *min_baseline,
                                       int          *nat_baseline)
+{
+  GtkWidget *child;
+  int largest_min = 0, largest_nat = 0;
+
+  for (child = gtk_widget_get_first_child (widget);
+       child != NULL;
+       child = gtk_widget_get_next_sibling (child))
+    {
+      int child_min = 0;
+      int child_nat = 0;
+
+      if (!gtk_widget_should_layout (child))
+        continue;
+
+      gtk_widget_measure (child,
+                          OPPOSITE_ORIENTATION (self->orientation),
+                          -1,
+                          &child_min, &child_nat,
+                          NULL, NULL);
+
+      largest_min = MAX (largest_min, child_min);
+      largest_nat = MAX (largest_nat, child_nat);
+    }
+
+  *minimum = largest_min;
+  *natural = largest_nat;
+}
+
+static void
+gtk_box_layout_compute_opposite_size_for_size (GtkBoxLayout *self,
+                                               GtkWidget    *widget,
+                                               int           for_size,
+                                               int          *minimum,
+                                               int          *natural,
+                                               int          *min_baseline,
+                                               int          *nat_baseline)
 {
   GtkWidget *child;
   int nvis_children;
@@ -437,9 +472,18 @@ gtk_box_layout_measure (GtkLayoutManager *layout_manager,
 
   if (self->orientation != orientation)
     {
-      gtk_box_layout_compute_opposite_size (self, widget, for_size,
-                                            minimum, natural,
-                                            min_baseline, nat_baseline);
+      if (for_size < 0)
+        {
+          gtk_box_layout_compute_opposite_size (self, widget,
+                                                minimum, natural,
+                                                min_baseline, nat_baseline);
+        }
+      else
+        {
+          gtk_box_layout_compute_opposite_size_for_size (self, widget, for_size,
+                                                         minimum, natural,
+                                                         min_baseline, nat_baseline);
+        }
     }
   else
     {
diff --git a/testsuite/reftests/meson.build b/testsuite/reftests/meson.build
index b033760ed7..692a427438 100644
--- a/testsuite/reftests/meson.build
+++ b/testsuite/reftests/meson.build
@@ -498,6 +498,8 @@ testdata = [
   'unresolvable.css',
   'unresolvable.ref.ui',
   'unresolvable.ui',
+  'vbox-with-max-width-chars-label.ref.ui',
+  'vbox-with-max-width-chars-label.ui',
   'window-border-width.ref.ui',
   'window-border-width.ui',
   'window-default-size.ref.ui',
diff --git a/testsuite/reftests/vbox-with-max-width-chars-label.ref.ui 
b/testsuite/reftests/vbox-with-max-width-chars-label.ref.ui
new file mode 100644
index 0000000000..aa732c608d
--- /dev/null
+++ b/testsuite/reftests/vbox-with-max-width-chars-label.ref.ui
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="GtkWindow">
+    <property name="decorated">0</property>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">horizontal</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="label">Hello World</property>
+            <property name="wrap">1</property>
+            <property name="max-width-chars">1</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/testsuite/reftests/vbox-with-max-width-chars-label.ui 
b/testsuite/reftests/vbox-with-max-width-chars-label.ui
new file mode 100644
index 0000000000..3a7d52e4a4
--- /dev/null
+++ b/testsuite/reftests/vbox-with-max-width-chars-label.ui
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="GtkWindow">
+    <property name="decorated">0</property>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="label">Hello World</property>
+            <property name="wrap">1</property>
+            <property name="max-width-chars">1</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]