aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/items/qquicklistview.cpp32
-rw-r--r--tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp20
2 files changed, 43 insertions, 9 deletions
diff --git a/src/declarative/items/qquicklistview.cpp b/src/declarative/items/qquicklistview.cpp
index 9dc91309f1..4fd4e97da5 100644
--- a/src/declarative/items/qquicklistview.cpp
+++ b/src/declarative/items/qquicklistview.cpp
@@ -634,18 +634,34 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
FxViewItem *item = 0;
bool changed = false;
- while (visibleItems.count() > 1 && (item = visibleItems.first()) && item->endPosition() <= bufferFrom) {
+ // Remove items from the start of the view.
+ // Zero-sized items shouldn't be removed unless a non-zero-sized item is also being
+ // removed, otherwise a zero-sized item is infinitely added and removed over and
+ // over by refill().
+ int index = 0;
+ while (visibleItems.count() > 1 && index < visibleItems.count()
+ && (item = visibleItems.at(index)) && item->endPosition() <= bufferFrom) {
if (item->attached->delayRemove())
break;
- if (item->size() == 0)
- break;
+ if (item->size() > 0) {
// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition();
- if (item->index != -1)
- visibleIndex++;
- visibleItems.removeFirst();
- releaseItem(item);
- changed = true;
+
+ // remove this item and all zero-sized items before it
+ while (item) {
+ if (item->index != -1)
+ visibleIndex++;
+ visibleItems.removeAt(index);
+ releaseItem(item);
+ if (index == 0)
+ break;
+ item = visibleItems.at(--index);
+ }
+ changed = true;
+ } else {
+ index++;
+ }
}
+
while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) {
if (item->attached->delayRemove())
break;
diff --git a/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp b/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp
index ae37724492..36824f8e0f 100644
--- a/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp
@@ -3468,7 +3468,7 @@ void tst_QQuickListView::resizeFirstDelegate()
// check the content y has not jumped up and down
QCOMPARE(listview->contentY(), 0.0);
QSignalSpy spy(listview, SIGNAL(contentYChanged()));
- QTest::qWait(300);
+ QTest::qWait(100);
QCOMPARE(spy.count(), 0);
for (int i = 1; i < model.count(); ++i) {
@@ -3477,6 +3477,24 @@ void tst_QQuickListView::resizeFirstDelegate()
QTRY_COMPARE(item->y(), (i-1)*20.0);
}
+
+ // QTBUG-22014: refill doesn't clear items scrolling off the top of the
+ // list if they follow a zero-sized delegate
+
+ for (int i = 0; i < 10; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ item = findItem<QQuickItem>(contentItem, "wrapper", 1);
+ QVERIFY(item);
+ item->setHeight(0);
+
+ listview->setCurrentIndex(19);
+ qApp->processEvents();
+
+ // items 0-3 should have been deleted
+ for (int i=0; i<4; i++)
+ QTRY_VERIFY(!findItem<QQuickItem>(contentItem, "wrapper", i));
+
delete testObject;
delete canvas;
}