diff options
author | Kari Oikarinen <kari.oikarinen@qt.io> | 2020-01-15 19:08:34 +0200 |
---|---|---|
committer | Kari Oikarinen <kari.oikarinen@qt.io> | 2020-01-15 19:08:34 +0200 |
commit | 51a158929b55dffbdfb757da8bd6a2cd181906c6 (patch) | |
tree | d887ef986f357614624d65277f94d740c410be21 /src/quick/items/qquickitemview.cpp | |
parent | 3a06d02197179240b8ea589534dc3416c75fc0f2 (diff) | |
parent | 3f8bcced6790059c279430ff34903c16bea25a98 (diff) |
Merge 5.14 into 5.14.1v5.14.1
Change-Id: Iefb900b42cc0476e62342724a5f3a480c09ce354
Diffstat (limited to 'src/quick/items/qquickitemview.cpp')
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 66be3c79f8..a931abca58 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1505,7 +1505,7 @@ QQuickItemViewPrivate::QQuickItemViewPrivate() , inLayout(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false) , haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false) , fillCacheBuffer(false), inRequest(false) - , runDelayedRemoveTransition(false), delegateValidated(false) + , runDelayedRemoveTransition(false), delegateValidated(false), isClearing(false) { bufferPause.addAnimationChangeListener(this, QAbstractAnimationJob::Completion); bufferPause.setLoopCount(1); @@ -1681,6 +1681,10 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) void QQuickItemViewPrivate::clear(bool onDestruction) { Q_Q(QQuickItemView); + + isClearing = true; + auto cleanup = qScopeGuard([this] { isClearing = false; }); + currentChanges.reset(); bufferedChanges.reset(); timeline.clear(); @@ -1908,21 +1912,25 @@ void QQuickItemViewPrivate::layout() prepareVisibleItemTransitions(); - 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()) { + // We cannot use iterators here as erasing from a container invalidates them. + for (int i = 0, count = releasePendingTransition.count(); i < count;) { + auto success = prepareNonVisibleItemTransition(releasePendingTransition[i], viewBounds); + // prepareNonVisibleItemTransition() may remove items while in fast flicking. + // Invisible animating items are kicked in or out the viewPort. + // Recheck count to test if the item got removed. In that case the same index points + // to a different item now. + const int old_count = count; + count = releasePendingTransition.count(); + if (old_count > count) continue; - } + if (!success) { - releaseItem(*it); - it = releasePendingTransition.erase(it); - continue; + releaseItem(releasePendingTransition[i]); + releasePendingTransition.remove(i); + --count; + } else { + ++i; } - ++it; } for (int i=0; i<visibleItems.count(); i++) @@ -2399,7 +2407,7 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item) QQmlInstanceModel::ReleaseFlags flags = {}; if (model && item->item) { flags = model->release(item->item); - if (!flags) { + if (!flags && !isClearing) { // item was not destroyed, and we no longer reference it. if (item->item->parentItem() == contentItem) { // Only cull the item if its parent item is still our contentItem. |