aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Zerkin <alexey.zerkin@qt.io>2026-03-20 10:58:23 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2026-04-29 16:39:38 +0000
commit768e286ed15e8d7323122a25fc330d04ca048009 (patch)
treedb5713fd8aa9c706fd7fe729126b1709a18db41a
parent7416a4ca2d1fad2edb3fb8c1d1077505e2f7b729 (diff)
Remove margins added by the helper to size hints of FlexBoxLayoutItem
QQuickLayout::effectiveSizeHints_helper() adds margins to the size hints, which are not needed in FlexBoxLayoutItem case as the item is managed by the Yoga layout library. Fixes: QTBUG-142153 Pick-to: 6.10 Change-Id: Ibd243a375c0f459770688250606462485666a282 Reviewed-by: SanthoshKumar Selvaraj <santhosh.kumar.selvaraj@qt.io> (cherry picked from commit 8ea218874eb058f1294c56ed64f705a422aa6562) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/quicklayouts/qquickflexboxlayoutengine.cpp33
-rw-r--r--src/quicklayouts/qquickflexboxlayoutitem_p.h1
-rw-r--r--tests/auto/quick/qquicklayouts/data/tst_flexboxlayout.qml52
3 files changed, 77 insertions, 9 deletions
diff --git a/src/quicklayouts/qquickflexboxlayoutengine.cpp b/src/quicklayouts/qquickflexboxlayoutengine.cpp
index d6d2451459..3fc29b5eb6 100644
--- a/src/quicklayouts/qquickflexboxlayoutengine.cpp
+++ b/src/quicklayouts/qquickflexboxlayoutengine.cpp
@@ -73,6 +73,15 @@ void QQuickFlexboxLayoutEngine::collectItemSizeHints(QQuickFlexboxLayoutItem *fl
if (!info)
return;
+ // remove margins from the size added by the helper
+ auto m = info->qMargins();
+ const QSizeF margins{m.left() + m.right(), m.top() + m.bottom()};
+ flexItem->cachedItemSizeHints().margins = margins; // save margins for later use
+
+ QSizeF noMarginsHints[Qt::NSizeHints];
+ for (int i = 0; i < Qt::NSizeHints; ++i)
+ noMarginsHints[i] = sizeHints[i] - margins;
+
// Set layout margins to the flex item (Layout.margins)
if (info->isMarginsSet())
flexItem->setFlexMargin(QQuickFlexboxLayout::EdgeAll, info->margins());
@@ -103,8 +112,8 @@ void QQuickFlexboxLayoutEngine::collectItemSizeHints(QQuickFlexboxLayoutItem *fl
// If the Layout.fillHeight not been set, the preferred height
// will be set as height
if (!info->fillHeight())
- flexItem->setHeight(sizeHints[Qt::PreferredSize].height());
- flexItem->setFlexBasis(sizeHints[Qt::PreferredSize].width(), !info->fillWidth());
+ flexItem->setHeight(noMarginsHints[Qt::PreferredSize].height());
+ flexItem->setFlexBasis(noMarginsHints[Qt::PreferredSize].width(), !info->fillWidth());
// Set child item to grow on main-axis (i.e. the flex
// direction)
flexItem->setItemGrowAlongMainAxis(info->fillWidth() ? 1.0f : 0.0f);
@@ -116,8 +125,8 @@ void QQuickFlexboxLayoutEngine::collectItemSizeHints(QQuickFlexboxLayoutItem *fl
// If the Layout.fillWidth not been set, the preferred width
// will be set as width
if (!info->fillWidth())
- flexItem->setWidth(sizeHints[Qt::PreferredSize].width());
- flexItem->setFlexBasis(sizeHints[Qt::PreferredSize].height(), !info->fillHeight());
+ flexItem->setWidth(noMarginsHints[Qt::PreferredSize].width());
+ flexItem->setFlexBasis(noMarginsHints[Qt::PreferredSize].height(), !info->fillHeight());
// Set child item to grow on main-axis (i.e. the flex
// direction)
flexItem->setItemGrowAlongMainAxis(info->fillHeight() ? 1.0f : 0.0f);
@@ -175,8 +184,13 @@ QSizeF QQuickFlexboxLayoutEngine::sizeHint(Qt::SizeHint whichSizeHint) const
const int count = itemCount();
for (int i = 0; i < count; ++i) {
SizeHints &hints = cachedItemSizeHints(i);
+
+ QSizeF noMarginsHints[Qt::NSizeHints];
+ for (int i = 0; i < Qt::NSizeHints; ++i)
+ noMarginsHints[i] = hints.array[i] - hints.margins;
+
auto &flexLayoutItem = m_flexLayoutItems.at(i);
- flexLayoutItem->setMinSize(hints.min());
+ flexLayoutItem->setMinSize(noMarginsHints[Qt::MinimumSize]);
if (flexLayoutItem->isFlexBasisUndefined()) {
// If flex basis is undefined and item is still stretched, it
// meant the flex child item has a const width or height but
@@ -191,16 +205,16 @@ QSizeF QQuickFlexboxLayoutEngine::sizeHint(Qt::SizeHint whichSizeHint) const
flexLayoutItem->resetSize();
if (qFlexLayout->direction() == QQuickFlexboxLayout::Row ||
qFlexLayout->direction() == QQuickFlexboxLayout::RowReverse) {
- flexLayoutItem->setWidth(hints.pref().width());
+ flexLayoutItem->setWidth(noMarginsHints[Qt::PreferredSize].width());
} else {
- flexLayoutItem->setHeight(hints.pref().height());
+ flexLayoutItem->setHeight(noMarginsHints[Qt::PreferredSize].height());
}
}
} else {
- flexLayoutItem->setSize(hints.pref());
+ flexLayoutItem->setSize(noMarginsHints[Qt::PreferredSize]);
}
}
- flexLayoutItem->setMaxSize(hints.max());
+ flexLayoutItem->setMaxSize(noMarginsHints[Qt::MaximumSize]);
// The preferred size, minimum and maximum size of the parent item
// will be calculated as follows
// If no wrap enabled in the flex layout:
@@ -312,6 +326,7 @@ void QQuickFlexboxLayoutEngine::invalidateItemSizeHint(QQuickItem *item)
hints.min() = QSizeF();
hints.pref() = QSizeF();
hints.max() = QSizeF();
+ hints.margins = {0,0};
}
}
diff --git a/src/quicklayouts/qquickflexboxlayoutitem_p.h b/src/quicklayouts/qquickflexboxlayoutitem_p.h
index d0b1b7deb9..f1c8530e49 100644
--- a/src/quicklayouts/qquickflexboxlayoutitem_p.h
+++ b/src/quicklayouts/qquickflexboxlayoutitem_p.h
@@ -27,6 +27,7 @@ struct SizeHints {
inline QSizeF &pref() { return array[Qt::PreferredSize]; }
inline QSizeF &max() { return array[Qt::MaximumSize]; }
QSizeF array[Qt::NSizeHints];
+ QSizeF margins{0,0};
};
class QQuickFlexboxLayoutItem
diff --git a/tests/auto/quick/qquicklayouts/data/tst_flexboxlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_flexboxlayout.qml
index 5334f7a977..e5fdbbfc99 100644
--- a/tests/auto/quick/qquicklayouts/data/tst_flexboxlayout.qml
+++ b/tests/auto/quick/qquicklayouts/data/tst_flexboxlayout.qml
@@ -911,5 +911,57 @@ Item {
compare(flexboxLayout.Layout.maximumWidth, 300 + 5)
compare(flexboxLayout.Layout.maximumHeight, 300 + 5)
}
+
+ function test_margins() {
+ let flexboxLayout = createTemporaryObject(dynamicFlexboxLayoutComponent, container)
+ waitForItemPolished(flexboxLayout)
+
+ compare(flexboxLayout.implicitWidth, 0)
+ compare(flexboxLayout.implicitHeight, 0)
+ compare(flexboxLayout.Layout.minimumWidth, 0)
+ compare(flexboxLayout.Layout.minimumHeight, 0)
+
+ let item1 = flexItem.createObject(flexboxLayout)
+ waitForItemPolished(flexboxLayout)
+ compare(item1.width, 20)
+ compare(item1.height, 20)
+ // item2 has no margins
+ compare(flexboxLayout.implicitWidth, 20)
+ compare(flexboxLayout.implicitHeight, 20)
+ compare(flexboxLayout.Layout.minimumWidth, 0)
+ compare(flexboxLayout.Layout.minimumHeight, 0)
+ // add margins
+ item1.Layout.margins = 7
+ waitForItemPolished(flexboxLayout)
+ compare(item1.width, 20)
+ compare(item1.height, 20)
+ // margins affect the implicit size of the layout itself
+ // item1 (20 + 2 * item1.Layout.margins)
+ compare(flexboxLayout.implicitWidth, 34)
+ compare(flexboxLayout.implicitHeight, 34)
+ compare(flexboxLayout.Layout.minimumWidth, 14)
+ compare(flexboxLayout.Layout.minimumHeight, 14)
+
+
+ let item2 = flexItem.createObject(flexboxLayout)
+ waitForItemPolished(flexboxLayout)
+ compare(item2.width, 20)
+ compare(item2.height, 20)
+ // item2 has no margins
+ compare(flexboxLayout.implicitWidth, 54)
+ compare(flexboxLayout.implicitHeight, 34)
+ compare(flexboxLayout.Layout.minimumWidth, 14)
+ compare(flexboxLayout.Layout.minimumHeight, 14)
+ // add margins
+ item2.Layout.leftMargin = 17
+ waitForItemPolished(flexboxLayout)
+ compare(item2.width, 20)
+ compare(item2.height, 20)
+ // item1 (34) + item2 (17 + 20 = 37)
+ compare(flexboxLayout.implicitWidth, 71)
+ compare(flexboxLayout.implicitHeight, 34)
+ compare(flexboxLayout.Layout.minimumWidth, 31)
+ compare(flexboxLayout.Layout.minimumHeight, 14)
+ }
}
}