summaryrefslogtreecommitdiffstats
path: root/src/layouts
diff options
context:
space:
mode:
authorDaiwei Li <daiweili@suitabletech.com>2015-01-27 18:47:20 -0800
committerDaiwei Li <daiweili@suitabletech.com>2015-02-05 10:09:47 +0000
commit13f53d45037629ad27b93e7a817dc0567dea5e66 (patch)
tree860eebe4735b259faad48b2fcf69c3602d0fd8fa /src/layouts
parent5f7f27759e23fb1e5f3779a580adcf5bb6d5ecd6 (diff)
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.cpp21
-rw-r--r--src/layouts/qquicklinearlayout_p.h5
2 files changed, 26 insertions, 0 deletions
diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp
index d2fb19335..6c9c59f48 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 931ef2cb7..aaab2248a 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;