diff options
-rw-r--r-- | src/quicklayouts/qquicklayout.cpp | 24 | ||||
-rw-r--r-- | src/quicklayouts/qquicklinearlayout.cpp | 24 | ||||
-rw-r--r-- | tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml | 72 |
3 files changed, 93 insertions, 27 deletions
diff --git a/src/quicklayouts/qquicklayout.cpp b/src/quicklayouts/qquicklayout.cpp index eb4a8f0c51..f38bdfd396 100644 --- a/src/quicklayouts/qquicklayout.cpp +++ b/src/quicklayouts/qquicklayout.cpp @@ -835,20 +835,16 @@ void QQuickLayout::invalidate(QQuickItem * /*childItem*/) d->m_dirtyArrangement = true; if (!qobject_cast<QQuickLayout *>(parentItem())) { - - if (m_inUpdatePolish) - ++m_polishInsideUpdatePolish; - else - m_polishInsideUpdatePolish = 0; - - if (m_polishInsideUpdatePolish <= 2) { - // allow at most two consecutive loops in order to respond to height-for-width - // (e.g QQuickText changes implicitHeight when its width gets changed) - qCDebug(lcQuickLayouts) << "QQuickLayout::invalidate(), polish()"; - polish(); + polish(); + + if (m_inUpdatePolish) { + if (++m_polishInsideUpdatePolish > 2) + // allow at most two consecutive loops in order to respond to height-for-width + // (e.g QQuickText changes implicitHeight when its width gets changed) + qCDebug(lcQuickLayouts) << "Layout polish loop detected for " << this + << ". The polish request will still be scheduled."; } else { - qmlWarning(this).nospace() << "Layout polish loop detected for " << this - << ". Aborting after two iterations."; + m_polishInsideUpdatePolish = 0; } } } @@ -927,7 +923,7 @@ void QQuickLayout::geometryChange(const QRectF &newGeometry, const QRectF &oldGe { Q_D(QQuickLayout); QQuickItem::geometryChange(newGeometry, oldGeometry); - if (d->m_disableRearrange || !isReady()) + if (invalidated() || d->m_disableRearrange || !isReady()) return; qCDebug(lcQuickLayouts) << "QQuickLayout::geometryChange" << newGeometry << oldGeometry; diff --git a/src/quicklayouts/qquicklinearlayout.cpp b/src/quicklayouts/qquicklinearlayout.cpp index 31c1857d9f..e10725da1c 100644 --- a/src/quicklayouts/qquicklinearlayout.cpp +++ b/src/quicklayouts/qquicklinearlayout.cpp @@ -361,26 +361,24 @@ void QQuickGridLayoutBase::invalidate(QQuickItem *childItem) if (!isReady()) return; qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::invalidate()" << this << ", invalidated:" << invalidated(); - if (invalidated()) { - return; - } - qCDebug(lcQuickLayouts) << "d->m_rearranging:" << d->m_rearranging; - if (d->m_rearranging) { - d->m_invalidateAfterRearrange << childItem; - return; - } - if (childItem) { - if (QQuickGridLayoutItem *layoutItem = d->engine.findLayoutItem(childItem)) + if (d->m_rearranging) { + if (!d->m_invalidateAfterRearrange.contains(childItem)) + d->m_invalidateAfterRearrange << childItem; + return; + } + if (QQuickGridLayoutItem *layoutItem = d->engine.findLayoutItem(childItem)) { layoutItem->invalidate(); + } } + // invalidate engine d->engine.invalidate(); qCDebug(lcQuickLayouts) << "calling QQuickLayout::invalidate();"; QQuickLayout::invalidate(); - if (QQuickLayout *parentLayout = qobject_cast<QQuickLayout *>(parentItem())) + if (auto *parentLayout = qobject_cast<QQuickLayout *>(parentItem())) parentLayout->invalidate(this); qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::invalidate() LEAVING" << this; } @@ -479,8 +477,8 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size) d->engine.setGeometries(QRectF(QPointF(0,0), size), d->styleInfo); d->m_rearranging = false; - for (QQuickItem *invalid : std::as_const(d->m_invalidateAfterRearrange)) - invalidate(invalid); + for (auto childItem : std::as_const(d->m_invalidateAfterRearrange)) + invalidate(childItem); d->m_invalidateAfterRearrange.clear(); } diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml index 99da499e08..63734d9d14 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml @@ -1329,6 +1329,78 @@ Item { } Component { + id: sizeHintBindingLoopComp + Item { + id: root + anchors.fill: parent + property var customWidth: 100 + RowLayout { + id: col + Item { + id: item + implicitHeight: 80 + implicitWidth: Math.max(col2.implicitWidth, root.customWidth + 20) + ColumnLayout { + id: col2 + width: parent.width + Item { + id: rect + implicitWidth: root.customWidth + implicitHeight: 80 + } + } + } + } + } + } + + function test_sizeHintBindingLoopIssue() { + var item = createTemporaryObject(sizeHintBindingLoopComp, container) + waitForRendering(item) + item.customWidth += 10 + waitForRendering(item) + verify(!LayoutSetup.bindingLoopDetected, "Detected binding loop") + LayoutSetup.resetBindingLoopDetectedFlag() + } + + Component { + id: polishLayoutItemComp + Item { + anchors.fill: parent + implicitHeight: contentLayout.implicitHeight + implicitWidth: contentLayout.implicitWidth + property alias textLayout: contentLayout + RowLayout { + width: parent.width + height: parent.height + ColumnLayout { + id: contentLayout + Layout.alignment: Qt.AlignHCenter | Qt.AlignTop + Layout.maximumWidth: 200 + Repeater { + model: 2 + Text { + Layout.fillWidth: true + text: "This is a long text causing line breaks to show the bug." + wrapMode: Text.Wrap + } + } + Item { + Layout.fillHeight: true + } + } + } + } + } + + function test_polishLayoutItemIssue() { + var rootItem = createTemporaryObject(polishLayoutItemComp, container) + waitForRendering(rootItem) + var textItem = rootItem.textLayout.children[1] + verify(textItem.y >= rootItem.textLayout.children[0].height) + } + + Component { id: rearrangeNestedLayouts_Component RowLayout { id: layout |