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 Change-Id: I1e318335ce8b5268d878b48a02a089d703bb90ad Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io> (cherry picked from commit9ad9d05f26
) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commita1d5514289
) (cherry picked from commit1570bd5f8e
)
This commit is contained in:
parent
2e3e3adf0f
commit
e3022f58fd
|
@ -921,7 +921,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();
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************
|
||||
|
|
|
@ -1177,6 +1177,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