aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@qt.io>2016-09-29 16:34:48 +0200
committerMitch Curtis <mitch.curtis@qt.io>2016-09-30 08:09:20 +0000
commit7433cc2f91d1aba045ab4920d6732c85d2ee33b9 (patch)
treedb2cec7ab252addc0645ac964a77edb7359bce85 /src
parent5d2c242d2d3fd6af724514ee00a6440864be0ade (diff)
Fix crash when flicking a ListView-based Tumbler
This only happens in 5.7, and seemingly only when the delegate uses attached properties (like displacement). Other fixes required and/or relevant to the patch: - Fixed some instances of displacementChanged possibly not being emitted. - Use QPointer for the attached object's Tumbler pointer, as it was being accessed while null after this patch. Change-Id: I7d881d815faf57f1a8bc0ea8e73a7331523d2f9b Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quicktemplates2/qquicktumbler.cpp35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp
index 580859ef..8c9c1d10 100644
--- a/src/quicktemplates2/qquicktumbler.cpp
+++ b/src/quicktemplates2/qquicktumbler.cpp
@@ -436,9 +436,10 @@ public:
void itemChildRemoved(QQuickItem *, QQuickItem *) override;
void _q_calculateDisplacement();
+ void emitIfDisplacementChanged(qreal oldDisplacement, qreal newDisplacement);
// The Tumbler that contains the delegate. Required to calculated the displacement.
- QQuickTumbler *tumbler;
+ QPointer<QQuickTumbler> tumbler;
// The index of the delegate. Used to calculate the displacement.
int index;
// The displacement for our delegate.
@@ -476,14 +477,23 @@ void QQuickTumblerAttachedPrivate::_q_calculateDisplacement()
const int previousDisplacement = displacement;
displacement = 0;
+ if (!tumbler) {
+ emitIfDisplacementChanged(previousDisplacement, displacement);
+ return;
+ }
+
const int count = tumbler->count();
// This can happen in tests, so it may happen in normal usage too.
- if (count == 0)
+ if (count == 0) {
+ emitIfDisplacementChanged(previousDisplacement, displacement);
return;
+ }
ContentItemType contentType = contentItemType(tumbler->contentItem());
- if (contentType == UnsupportedContentItemType)
+ if (contentType == UnsupportedContentItemType) {
+ emitIfDisplacementChanged(previousDisplacement, displacement);
return;
+ }
qreal offset = 0;
@@ -507,8 +517,13 @@ void QQuickTumblerAttachedPrivate::_q_calculateDisplacement()
displacement = reverseDisplacement - index;
}
+ emitIfDisplacementChanged(previousDisplacement, displacement);
+}
+
+void QQuickTumblerAttachedPrivate::emitIfDisplacementChanged(qreal oldDisplacement, qreal newDisplacement)
+{
Q_Q(QQuickTumblerAttached);
- if (displacement != previousDisplacement)
+ if (newDisplacement != oldDisplacement)
emit q->displacementChanged();
}
@@ -532,6 +547,18 @@ QQuickTumblerAttached::QQuickTumblerAttached(QQuickItem *delegateItem) :
QQuickTumblerAttached::~QQuickTumblerAttached()
{
+ Q_D(QQuickTumblerAttached);
+ if (!d->tumbler || !d->tumbler->contentItem())
+ return;
+
+ QQuickItem *rootContentItem = d->tumbler->contentItem();
+ const ContentItemType contentType = contentItemType(rootContentItem);
+ QQuickItem *actualItem = actualContentItem(rootContentItem, contentType);
+ if (!actualItem)
+ return;
+
+ QQuickItemPrivate *p = QQuickItemPrivate::get(actualItem);
+ p->removeItemChangeListener(d, QQuickItemPrivate::Geometry | QQuickItemPrivate::Children);
}
/*!