[gtk] widget: Fix gtk_widget_size_allocate()



commit d247e5707dc8df5e32aee923ed317845cf4fec93
Author: Benjamin Otte <otte redhat com>
Date:   Tue Feb 19 05:50:49 2019 +0100

    widget: Fix gtk_widget_size_allocate()
    
    Compute the matrix for adjusted sizes etc properly.

 gtk/gtksizerequest.c   |   3 +-
 gtk/gtkwidget.c        | 165 ++++++++++++++++++-------------------------------
 gtk/gtkwidgetprivate.h |   2 +-
 3 files changed, 63 insertions(+), 107 deletions(-)
---
diff --git a/gtk/gtksizerequest.c b/gtk/gtksizerequest.c
index d14b55471a..197d2413ea 100644
--- a/gtk/gtksizerequest.c
+++ b/gtk/gtksizerequest.c
@@ -208,6 +208,7 @@ gtk_widget_query_size_for_orientation (GtkWidget        *widget,
           int adjusted_for_size;
           int minimum_for_size = 0;
           int natural_for_size = 0;
+          int dummy = 0;
 
           /* Pull the minimum for_size from the cache as it's needed to adjust
            * the proposed 'for_size' */
@@ -221,7 +222,7 @@ gtk_widget_query_size_for_orientation (GtkWidget        *widget,
           adjusted_for_size = for_size;
           gtk_widget_adjust_size_allocation (widget, OPPOSITE_ORIENTATION (orientation),
                                              &for_size, &natural_for_size,
-                                             NULL, &adjusted_for_size);
+                                             &dummy, &adjusted_for_size);
 
           adjusted_for_size -= css_extra_for_size;
 
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 4e6ea25321..6255aba57d 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4188,11 +4188,7 @@ gtk_widget_allocate (GtkWidget               *widget,
                      const graphene_matrix_t *transform)
 {
   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-  int real_width;
-  int real_height;
-  int adjusted_width;
-  int adjusted_height;
-  graphene_matrix_t adjusted_transform;
+  GdkRectangle adjusted;
   gboolean alloc_needed;
   gboolean size_changed;
   gboolean baseline_changed;
@@ -4249,9 +4245,7 @@ gtk_widget_allocate (GtkWidget               *widget,
   priv->allocated_height = height;
   priv->allocated_size_baseline = baseline;
 
-  adjusted_width = width;
-  adjusted_height = height;
-  graphene_matrix_init_from_matrix (&adjusted_transform, transform);
+  adjusted = (GdkRectangle) { 0, 0, width, height };
   if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
     {
       /* Go ahead and request the height for allocated width, note that the internals
@@ -4291,47 +4285,52 @@ gtk_widget_allocate (GtkWidget               *widget,
                                      GTK_ORIENTATION_HORIZONTAL,
                                      &dummy,
                                      &natural_width,
-                                     &adjusted_transform,
-                                     &adjusted_width);
+                                     &adjusted.x,
+                                     &adjusted.width);
   gtk_widget_adjust_size_allocation (widget,
                                      GTK_ORIENTATION_VERTICAL,
                                      &dummy,
                                      &natural_height,
-                                     &adjusted_transform,
-                                     &adjusted_height);
+                                     &adjusted.y,
+                                     &adjusted.height);
   if (baseline >= 0)
     baseline -= priv->margin.top;
 
-  real_width = adjusted_width;
-  real_height = adjusted_height;
-
-  if (real_width < 0 || real_height < 0)
+  if (adjusted.width < 0 || adjusted.height < 0)
     {
       g_warning ("gtk_widget_size_allocate(): attempt to allocate %s %s %p with width %d and height %d",
                  G_OBJECT_TYPE_NAME (widget), gtk_css_node_get_name (priv->cssnode), widget,
-                 real_width,
-                 real_height);
+                 adjusted.width,
+                 adjusted.height);
 
-      real_width = 0;
-      real_height = 0;
+      adjusted.width = 0;
+      adjusted.height = 0;
     }
 
   if (G_UNLIKELY (_gtk_widget_get_has_surface (widget)))
     {
-      real_width = MAX (1, real_width);
-      real_height = MAX (1, real_height);
+      adjusted.width = MAX (1, adjusted.width);
+      adjusted.height = MAX (1, adjusted.height);
     }
 
   style = gtk_css_node_get_style (priv->cssnode);
   get_box_margin (style, &margin);
   get_box_border (style, &border);
   get_box_padding (style, &padding);
-  graphene_matrix_translate (&adjusted_transform,
-                             &GRAPHENE_POINT3D_INIT (
-                               margin.left + border.left + padding.left,
-                               margin.top + border.top + padding.top,
-                               0
-                             ));
+  adjusted.x += margin.left + border.left + padding.left;
+  adjusted.y += margin.top + border.top + padding.top;
+
+  /* Since gtk_widget_measure does it for us, we can be sure here that
+   * the given alloaction is large enough for the css margin/bordder/padding */
+  adjusted.width -= margin.left + border.left + padding.left +
+                    margin.right + border.right + padding.right;
+  adjusted.height -= margin.top + border.top + padding.top +
+                     margin.bottom + border.bottom + padding.bottom;
+  if (baseline >= 0)
+    baseline -= margin.top + border.top + padding.top;
+
+  graphene_matrix_init_translate (&priv->transform, &GRAPHENE_POINT3D_INIT (adjusted.x, adjusted.y, 0));
+  graphene_matrix_multiply (&priv->transform, transform, &priv->transform);
 
   if (!alloc_needed && !size_changed && !baseline_changed)
     {
@@ -4347,20 +4346,11 @@ gtk_widget_allocate (GtkWidget               *widget,
                                    window_alloc.width, window_alloc.height);
          }
 
-      goto only_transform_changed;
+      goto skip_allocate;
     }
 
-  /* Since gtk_widget_measure does it for us, we can be sure here that
-   * the given alloaction is large enough for the css margin/bordder/padding */
-  real_width -= margin.left + border.left + padding.left +
-                margin.right + border.right + padding.right;
-  real_height -= margin.top + border.top + padding.top +
-                 margin.bottom + border.bottom + padding.bottom;
-  if (baseline >= 0)
-    baseline -= margin.top + border.top + padding.top;
-
-  priv->width = real_width;
-  priv->height = real_height;
+  priv->width = adjusted.width;
+  priv->height = adjusted.height;
   priv->baseline = baseline;
 
   if (g_signal_has_handler_pending (widget, widget_signals[SIZE_ALLOCATE], 0, FALSE))
@@ -4389,9 +4379,7 @@ gtk_widget_allocate (GtkWidget               *widget,
 
   gtk_widget_update_paintables (widget);
 
-only_transform_changed:
-  graphene_matrix_init_from_matrix (&priv->transform, &adjusted_transform);
-
+skip_allocate:
   if (size_changed || baseline_changed)
     gtk_widget_queue_draw (widget);
   else if (transform_changed && priv->parent)
@@ -4616,11 +4604,10 @@ effective_align (GtkAlign         align,
 }
 
 static void
-adjust_for_align (GtkOrientation     orientation,
-                  GtkAlign           align,
-                  int               *natural_size,
-                  graphene_matrix_t *transform,
-                  int               *allocated_size)
+adjust_for_align (GtkAlign  align,
+                  gint     *natural_size,
+                  gint     *allocated_pos,
+                  gint     *allocated_size)
 {
   switch (align)
     {
@@ -4630,66 +4617,38 @@ adjust_for_align (GtkOrientation     orientation,
       /* change nothing */
       break;
     case GTK_ALIGN_START:
-      /* keep position where it is */
+      /* keep *allocated_pos where it is */
       *allocated_size = MIN (*allocated_size, *natural_size);
       break;
     case GTK_ALIGN_END:
       if (*allocated_size > *natural_size)
-        {
-          if (transform)
-            {
-              if (orientation == GTK_ORIENTATION_HORIZONTAL)
-                graphene_matrix_translate (transform,
-                                           &GRAPHENE_POINT3D_INIT (*allocated_size - *natural_size, 0, 0));
-              else
-                graphene_matrix_translate (transform,
-                                           &GRAPHENE_POINT3D_INIT (0, *allocated_size - *natural_size, 0));
-            }
-
-          *allocated_size = *natural_size;
-        }
+       {
+         *allocated_pos += (*allocated_size - *natural_size);
+         *allocated_size = *natural_size;
+       }
       break;
     case GTK_ALIGN_CENTER:
       if (*allocated_size > *natural_size)
-        {
-          if (transform)
-            {
-              if (orientation == GTK_ORIENTATION_HORIZONTAL)
-                graphene_matrix_translate (transform,
-                                           &GRAPHENE_POINT3D_INIT ((*allocated_size - *natural_size) / 2, 0, 
0));
-              else
-                graphene_matrix_translate (transform,
-                                           &GRAPHENE_POINT3D_INIT (0, (*allocated_size - *natural_size) / 2, 
0));
-            }
-
-          *allocated_size = MIN (*allocated_size, *natural_size);
-        }
+       {
+         *allocated_pos += (*allocated_size - *natural_size) / 2;
+         *allocated_size = MIN (*allocated_size, *natural_size);
+       }
       break;
     }
 }
 
 static void
-adjust_for_margin (GtkOrientation     orientation,
-                   int                start_margin,
-                   int                end_margin,
-                   int               *minimum_size,
-                   int               *natural_size,
-                   graphene_matrix_t *transform,
-                   int               *allocated_size)
+adjust_for_margin(gint               start_margin,
+                  gint               end_margin,
+                  gint              *minimum_size,
+                  gint              *natural_size,
+                  gint              *allocated_pos,
+                  gint              *allocated_size)
 {
   *minimum_size -= (start_margin + end_margin);
   *natural_size -= (start_margin + end_margin);
+  *allocated_pos += start_margin;
   *allocated_size -= (start_margin + end_margin);
-
-  if (transform)
-    {
-      if (orientation == GTK_ORIENTATION_HORIZONTAL)
-        graphene_matrix_translate (transform,
-                                   &GRAPHENE_POINT3D_INIT (start_margin, 0, 0));
-      else
-        graphene_matrix_translate (transform,
-                                   &GRAPHENE_POINT3D_INIT (0, start_margin, 0));
-    }
 }
 
 void
@@ -4697,32 +4656,28 @@ gtk_widget_adjust_size_allocation (GtkWidget         *widget,
                                    GtkOrientation     orientation,
                                    gint              *minimum_size,
                                    gint              *natural_size,
-                                   graphene_matrix_t *transform,
+                                   gint              *allocated_pos,
                                    gint              *allocated_size)
 {
   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
 
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
     {
-      adjust_for_margin (orientation,
-                         priv->margin.left,
+      adjust_for_margin (priv->margin.left,
                          priv->margin.right,
                          minimum_size, natural_size,
-                         transform, allocated_size);
-      adjust_for_align (orientation,
-                        effective_align (priv->halign, _gtk_widget_get_direction (widget)),
-                        natural_size, transform, allocated_size);
+                         allocated_pos, allocated_size);
+      adjust_for_align (effective_align (priv->halign, _gtk_widget_get_direction (widget)),
+                        natural_size, allocated_pos, allocated_size);
     }
   else
     {
-      adjust_for_margin (orientation,
-                         priv->margin.top,
+      adjust_for_margin (priv->margin.top,
                          priv->margin.bottom,
                          minimum_size, natural_size,
-                         transform, allocated_size);
-      adjust_for_align (orientation,
-                        effective_align (priv->valign, GTK_TEXT_DIR_NONE),
-                        natural_size, transform, allocated_size);
+                         allocated_pos, allocated_size);
+      adjust_for_align (effective_align (priv->valign, GTK_TEXT_DIR_NONE),
+                        natural_size, allocated_pos, allocated_size);
     }
 }
 
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 9d4d04fcd7..31356ae5a5 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -304,7 +304,7 @@ void              gtk_widget_adjust_size_allocation        (GtkWidget         *w
                                                             GtkOrientation     orientation,
                                                             gint              *minimum_size,
                                                             gint              *natural_size,
-                                                            graphene_matrix_t *transform,
+                                                            gint              *allocated_pos,
                                                             gint              *allocated_size);
 void              gtk_widget_adjust_baseline_request       (GtkWidget *widget,
                                                             gint      *minimum_baseline,


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