diff options
author | Daiwei Li <daiweili@suitabletech.com> | 2015-01-27 18:47:20 -0800 |
---|---|---|
committer | Daiwei Li <daiweili@suitabletech.com> | 2015-02-05 10:09:47 +0000 |
commit | 13f53d45037629ad27b93e7a817dc0567dea5e66 (patch) | |
tree | 860eebe4735b259faad48b2fcf69c3602d0fd8fa /src/layouts | |
parent | 5f7f27759e23fb1e5f3779a580adcf5bb6d5ecd6 (diff) | |
download | qtquickcontrols-13f53d45037629ad27b93e7a817dc0567dea5e66.tar.gz |
Fix crash when invalidating a layout while rearranging
Queue the invalidations and upates while rearranging and
apply them after. If we do them during, we can delete the
items being arranged, leading to a crash.
Change-Id: Ic3fe25c52afd1c8d36644f3cf7e3377ba3bec9c1
Task-number: QTBUG-44139
Reviewed-by: Jan Arve Sæther <jan-arve.saether@theqtcompany.com>
Diffstat (limited to 'src/layouts')
-rw-r--r-- | src/layouts/qquicklinearlayout.cpp | 21 | ||||
-rw-r--r-- | src/layouts/qquicklinearlayout_p.h | 5 |
2 files changed, 26 insertions, 0 deletions
diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp index d2fb1933..6c9c59f4 100644 --- a/src/layouts/qquicklinearlayout.cpp +++ b/src/layouts/qquicklinearlayout.cpp @@ -390,6 +390,11 @@ void QQuickGridLayoutBase::invalidate(QQuickItem *childItem) Q_D(QQuickGridLayoutBase); if (!isReady()) return; + if (d->m_rearranging) { + d->m_invalidateAfterRearrange << childItem; + return; + } + quickLayoutDebug() << "QQuickGridLayoutBase::invalidate()"; if (childItem) { @@ -429,6 +434,11 @@ void QQuickGridLayoutBase::updateLayoutItems() Q_D(QQuickGridLayoutBase); if (!isReady()) return; + if (d->m_rearranging) { + d->m_updateAfterRearrange = true; + return; + } + quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems"; d->engine.deleteItems(); insertLayoutItems(); @@ -548,6 +558,7 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size) if (!isReady()) return; + d->m_rearranging = true; quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::rearrange()" << size; Qt::LayoutDirection visualDir = effectiveLayoutDirection(); d->engine.setVisualDirection(visualDir); @@ -563,6 +574,16 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size) // This could happen if there is a binding like implicitWidth: height QQuickLayout::rearrange(size); d->engine.setGeometries(QRectF(QPointF(0,0), size), d->styleInfo); + d->m_rearranging = false; + + foreach (QQuickItem *invalid, d->m_invalidateAfterRearrange) + invalidate(invalid); + d->m_invalidateAfterRearrange.clear(); + + if (d->m_updateAfterRearrange) { + updateLayoutItems(); + d->m_updateAfterRearrange = false; + } } bool QQuickGridLayoutBase::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints) diff --git a/src/layouts/qquicklinearlayout_p.h b/src/layouts/qquicklinearlayout_p.h index 931ef2cb..aaab2248 100644 --- a/src/layouts/qquicklinearlayout_p.h +++ b/src/layouts/qquicklinearlayout_p.h @@ -107,6 +107,8 @@ class QQuickGridLayoutBasePrivate : public QQuickLayoutPrivate public: QQuickGridLayoutBasePrivate() : m_disableRearrange(true) , m_isReady(false) + , m_rearranging(false) + , m_updateAfterRearrange(false) , m_layoutDirection(Qt::LeftToRight) {} @@ -120,6 +122,9 @@ public: Qt::Orientation orientation; unsigned m_disableRearrange : 1; unsigned m_isReady : 1; + unsigned m_rearranging : 1; + unsigned m_updateAfterRearrange : 1; + QVector<QQuickItem *> m_invalidateAfterRearrange; Qt::LayoutDirection m_layoutDirection : 2; QSet<QQuickItem *> m_ignoredItems; |