aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYulong Bai <yulong.bai@qt.io>2019-06-19 15:05:28 +0200
committerFrederik Gladhorn <frederik.gladhorn@qt.io>2019-06-26 12:37:29 +0000
commitb8a85408d943bffba403d783b9082bd279460bed (patch)
tree943887cbe495b8182930ac24325ce043f47b5374 /src
parent5eceb1801ec881947f80f70f32ea46e00926194f (diff)
QQuickItemView: fix crash while doing fast flicking in transitions
The cause was that fast flicking kicked items in and out of viewport, while in transition, they would abruptly having tracking data structure , i.e. releasePendingTransition of QQuickItemViewPrivate, got iterator invalidated. This also helps to resolve QTBUG-44308. Fixes: QTBUG-76433 Fixes: QTBUG-44308 Change-Id: If14533d3f6b1acd7b6ca0c5c723347c0cb3f54dc Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickitemview.cpp20
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
2 files changed, 14 insertions, 8 deletions
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 2e1962bc7b..eead84d51e 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1874,15 +1874,21 @@ void QQuickItemViewPrivate::layout()
prepareVisibleItemTransitions();
- for (QList<FxViewItem*>::Iterator it = releasePendingTransition.begin();
- it != releasePendingTransition.end(); ) {
- FxViewItem *item = *it;
- if (prepareNonVisibleItemTransition(item, viewBounds)) {
- ++it;
- } else {
- releaseItem(item);
+ for (auto it = releasePendingTransition.begin(); it != releasePendingTransition.end(); ) {
+ auto old_count = releasePendingTransition.count();
+ auto success = prepareNonVisibleItemTransition(*it, viewBounds);
+ // prepareNonVisibleItemTransition() may invalidate iterators while in fast flicking
+ // invisible animating items are kicked in or out the viewPort
+ // use old_count to test if the abrupt erasure occurs
+ if (old_count > releasePendingTransition.count()) {
+ continue;
+ }
+ if (!success) {
+ releaseItem(*it);
it = releasePendingTransition.erase(it);
+ continue;
}
+ ++it;
}
for (int i=0; i<visibleItems.count(); i++)
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index ea5b5df9c6..aca334d931 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -287,7 +287,7 @@ public:
: item(i), moveKey(k) {}
};
QQuickItemViewTransitioner *transitioner;
- QList<FxViewItem *> releasePendingTransition;
+ QVector<FxViewItem *> releasePendingTransition;
mutable qreal minExtent;
mutable qreal maxExtent;