Fix binding loop and polish issue in quick layout
The quick layout item cause binding loop issue when layout item size were updated in-between polish. This has been fixed by not updating layout size hint during rearrange. But there is polish issue due to child item not being invalidated and this skips corresponding item box size calculation. This patch invalidate all the items in the rearrange list of the layout and finally, invalidate engine and layout. Fixes: QTBUG-117899 Fixes: QTBUG-118511 Pick-to: 6.7 6.6 6.5 Change-Id: I1e318335ce8b5268d878b48a02a089d703bb90ad Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
parent
3211100411
commit
9ad9d05f26
|
@ -925,7 +925,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;
|
||||
|
|
|
@ -457,10 +457,6 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
|
|||
return;
|
||||
}
|
||||
|
||||
// Should normally not be needed, but there might be an incoming window resize event that we
|
||||
// will process before we process updatePolish()
|
||||
ensureLayoutItemsUpdated(QQuickLayout::ApplySizeHints | QQuickLayout::Recursive);
|
||||
|
||||
d->m_rearranging = true;
|
||||
qCDebug(lcQuickLayouts) << objectName() << "QQuickGridLayoutBase::rearrange()" << size;
|
||||
Qt::LayoutDirection visualDir = effectiveLayoutDirection();
|
||||
|
@ -479,9 +475,14 @@ 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);
|
||||
d->m_invalidateAfterRearrange.clear();
|
||||
if (d->m_invalidateAfterRearrange.size() > 0) {
|
||||
for (QQuickItem *invalid : std::as_const(d->m_invalidateAfterRearrange)) {
|
||||
if (QQuickGridLayoutItem *layoutItem = d->engine.findLayoutItem(invalid))
|
||||
layoutItem->invalidate();
|
||||
}
|
||||
invalidate();
|
||||
d->m_invalidateAfterRearrange.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************
|
||||
|
|
|
@ -1289,6 +1289,78 @@ Item {
|
|||
compare(row.implicitWidth, 2);
|
||||
}
|
||||
|
||||
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(!BindingLoopDetector.bindingLoopDetected, "Detected binding loop")
|
||||
BindingLoopDetector.reset()
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue