From cec771589dc0ef98d5d3e1b65641c8c581c4ed55 Mon Sep 17 00:00:00 2001
From: Jan Arve Saether <jan-arve.saether@digia.com>
Date: Wed, 8 May 2013 11:59:35 +0200
Subject: [PATCH] Layouts implicit sizes was not propagated up properly.

When a layout did not have an implicit size nor any of the
Layout.preferred* properties set, the size hint calculation would
fall back to retrieving the width and the height properties of the
item. It would then store that value in the Layout.preferred*
property. This was wrong.

This could be a problem when an item was later added to the layout,
and consequently the implicit size of the layout got updated.
However, since the layout now had a preferred size set, a parent
layout would ignore the implicit size it had since it would settle
with the Layout.preferred* property (that's the rules the
effectiveSizeHint_helper work with).

The fix is to set the implicit width/height instead of the
Layout.preferred{width|height} property.

The compare in the test was actually by accident wrong, which can be
easily verified.

Change-Id: Ib9110dec7988a547441748698348227d1b8a077f
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
---
 src/layouts/qquickgridlayoutengine.cpp     | 28 ++++++++++++----------
 tests/auto/controls/data/tst_rowlayout.qml |  4 +++-
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/layouts/qquickgridlayoutengine.cpp b/src/layouts/qquickgridlayoutengine.cpp
index 7935d79c4..e734e9fef 100644
--- a/src/layouts/qquickgridlayoutengine.cpp
+++ b/src/layouts/qquickgridlayoutengine.cpp
@@ -182,24 +182,26 @@ Fixed    | Layout.fillWidth               | Expanding if layout, Fixed if item |
            we only want to use the initial width.
            This is because the width will change due to layout rearrangement, and the preferred
            width should return the same value, regardless of the current width.
-           We therefore store the width in the Layout.preferredWidth attached property.
-           Since the layout listens to changes of Layout.preferredWidth, (it will
-           basically cause an invalidation of the layout, we have to disable that
-           notification while we set the preferred width.
+           We therefore store the width in the implicitWidth attached property.
+           Since the layout listens to changes of implicitWidth, (it will
+           basically cause an invalidation of the layout), we have to disable that
+           notification while we set the implicit width (and height).
 
            Only use this fallback the first time the size hint is queried. Otherwise, we might
            end up picking a width that is different than what was specified in the QML.
         */
-        const bool was = info->setChangesNotificationEnabled(false);
-        if (prefWidth < 0) {
-            prefWidth = item->width();
-            info->setPreferredWidth(prefWidth);
+        if (prefWidth < 0 || prefHeight < 0) {
+            item->blockSignals(true);
+            if (prefWidth < 0) {
+                prefWidth = item->width();
+                item->setImplicitWidth(prefWidth);
+            }
+            if (prefHeight < 0) {
+                prefHeight = item->height();
+                item->setImplicitHeight(prefHeight);
+            }
+            item->blockSignals(false);
         }
-        if (prefHeight < 0) {
-            prefHeight = item->height();
-            info->setPreferredHeight(prefHeight);
-        }
-        info->setChangesNotificationEnabled(was);
     }
     //--- GATHER MAXIMUM SIZE HINTS ---
     // They are always q_declarativeLayoutMaxSize
diff --git a/tests/auto/controls/data/tst_rowlayout.qml b/tests/auto/controls/data/tst_rowlayout.qml
index d142a5965..1b9573e0c 100644
--- a/tests/auto/controls/data/tst_rowlayout.qml
+++ b/tests/auto/controls/data/tst_rowlayout.qml
@@ -262,6 +262,7 @@ Item {
         Component {
             id: columnLayoutItem_Component
             ColumnLayout {
+                spacing: 0
             }
         }
 
@@ -295,7 +296,8 @@ Item {
             rect3.Layout.fillHeight = true
 
             compare(layout.implicitWidth, 70)
-            compare(layout.implicitHeight, 30)
+            compare(col.implicitHeight, 40)
+            compare(layout.implicitHeight, 40)
 
             rect3.destroy()
             wait(0)     // this will hopefully effectuate the destruction of the object
-- 
GitLab