aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2012-01-18 16:21:50 +1000
committerQt by Nokia <qt-info@nokia.com>2012-01-20 00:30:09 +0100
commitd9fd9ff55d4d8717cb35b7af39f9f5f39f9a3448 (patch)
treeff2f7725482a36506c1b5a34a7a69ff79ec10c67 /src
parentb1da5cb07922e786bd3223317651284b73159e82 (diff)
Fix lockup in views due to endless polish loop.
It was possible to cause an endless polish loop in some rare cases. Eliminate all calls to polish() within existing polish() code paths. Cleanup delegate creation and cancelling in the cacheBuffer area. Adjust first item position correctly when inserting/removing before visibleItems list. Change-Id: I508a2e6de8cb09d904466cbf5fb6b5dfd1e89c49 Reviewed-by: Bea Lam <bea.lam@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickgridview.cpp53
-rw-r--r--src/quick/items/qquickitemview.cpp81
-rw-r--r--src/quick/items/qquickitemview_p_p.h18
-rw-r--r--src/quick/items/qquicklistview.cpp48
-rw-r--r--src/quick/items/qquickvisualdatamodel.cpp4
5 files changed, 120 insertions, 84 deletions
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index ef79a4de42..8cc9b4248d 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE
#define QML_FLICK_SNAPONETHRESHOLD 30
#endif
+//#define DEBUG_DELEGATE_LIFECYCLE
+
//----------------------------------------------------------------------------
class FxGridItemSG : public FxViewItem
@@ -172,7 +174,7 @@ public:
virtual FxViewItem *newViewItem(int index, QQuickItem *item);
virtual void repositionPackageItemAt(QQuickItem *item, int index);
virtual void resetFirstItemPosition(qreal pos = 0.0);
- virtual void adjustFirstItem(qreal forwards, qreal backwards);
+ virtual void adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible);
virtual void createHighlight();
virtual void updateHighlight();
@@ -442,7 +444,9 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
bool changed = false;
while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) {
-// qDebug() << "refill: append item" << modelIndex << colPos << rowPos;
+#ifdef DEBUG_DELEGATE_LIFECYCLE
+ qDebug() << "refill: append item" << modelIndex << colPos << rowPos;
+#endif
if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, doBuffer))))
break;
item->setPosition(colPos, rowPos);
@@ -457,6 +461,9 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
changed = true;
}
+ if (doBuffer && requestedIndex != -1) // already waiting for an item
+ return changed;
+
// Find first column
if (visibleItems.count()) {
FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
@@ -473,7 +480,9 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
// Prepend
colPos = colNum * colSize();
while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){
-// qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos;
+#ifdef DEBUG_DELEGATE_LIFECYCLE
+ qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos;
+#endif
if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, doBuffer))))
break;
--visibleIndex;
@@ -501,7 +510,9 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
&& item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) {
if (item->attached->delayRemove())
break;
-// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos();
+#ifdef DEBUG_DELEGATE_LIFECYCLE
+ qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos();
+#endif
if (item->index != -1)
visibleIndex++;
visibleItems.removeFirst();
@@ -513,7 +524,9 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
&& item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) {
if (item->attached->delayRemove())
break;
-// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1;
+#ifdef DEBUG_DELEGATE_LIFECYCLE
+ qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1;
+#endif
visibleItems.removeLast();
releaseItem(item);
changed = true;
@@ -590,12 +603,15 @@ void QQuickGridViewPrivate::resetFirstItemPosition(qreal pos)
item->setPosition(0, pos);
}
-void QQuickGridViewPrivate::adjustFirstItem(qreal forwards, qreal backwards)
+void QQuickGridViewPrivate::adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible)
{
if (!visibleItems.count())
return;
- int moveCount = (forwards / rowSize()) - (backwards / rowSize());
+ int moveCount = (forwards - backwards) / rowSize();
+
+ if (changeBeforeVisible)
+ moveCount += (changeBeforeVisible%columns) - (columns - 1);
FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(visibleItems.first());
gridItem->setPosition(gridItem->colPos(), gridItem->rowPos() + ((moveCount / columns) * rowSize()));
@@ -1419,7 +1435,7 @@ void QQuickGridView::setCellWidth(qreal cellWidth)
d->updateViewport();
emit cellWidthChanged();
d->forceLayout = true;
- d->layout();
+ polish();
}
}
@@ -1437,7 +1453,7 @@ void QQuickGridView::setCellHeight(qreal cellHeight)
d->updateViewport();
emit cellHeightChanged();
d->forceLayout = true;
- d->layout();
+ polish();
}
}
/*!
@@ -1521,14 +1537,6 @@ void QQuickGridView::viewportMoved()
return;
d->inViewportMoved = true;
- // Set visibility of items to eliminate cost of items outside the visible area.
- qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
- qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
- for (int i = 0; i < d->visibleItems.count(); ++i) {
- FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i));
- item->item->setVisible(item->rowPos() + d->rowSize() >= from && item->rowPos() <= to);
- }
-
if (yflick())
d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
else if (d->isRightToLeftTopToBottom())
@@ -1537,6 +1545,15 @@ void QQuickGridView::viewportMoved()
d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
d->refill();
+
+ // Set visibility of items to eliminate cost of items outside the visible area.
+ qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
+ qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
+ for (int i = 0; i < d->visibleItems.count(); ++i) {
+ FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i));
+ item->item->setVisible(item->rowPos() + d->rowSize() >= from && item->rowPos() <= to);
+ }
+
if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QQuickGridViewPrivate::Mouse;
if (d->moveReason != QQuickGridViewPrivate::SetIndex) {
@@ -1817,7 +1834,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::In
while (i >= 0) {
if (rowPos > from && insertionIdx < visibleIndex) {
// item won't be visible, just note the size for repositioning
- insertResult->sizeChangesBeforeVisiblePos += rowSize();
+ insertResult->changeBeforeVisible++;
} else {
// item is before first visible e.g. in cache buffer
FxViewItem *item = 0;
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 8ff8b8860c..3341402acd 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -775,7 +775,7 @@ void QQuickItemView::destroyRemoved()
// Correct the positioning of the items
d->updateSections();
d->forceLayout = true;
- d->layout();
+ polish();
}
void QQuickItemView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
@@ -1114,7 +1114,7 @@ QQuickItemViewPrivate::QQuickItemViewPrivate()
, highlightMoveDuration(150)
, headerComponent(0), header(0), footerComponent(0), footer(0)
, minExtent(0), maxExtent(0)
- , ownModel(false), wrap(false), deferredRelease(false)
+ , ownModel(false), wrap(false)
, inApplyModelChanges(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false)
, haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false)
, fillCacheBuffer(false), inRequest(false), requestedAsync(false)
@@ -1301,7 +1301,7 @@ void QQuickItemViewPrivate::refill()
refill(position(), position()+s);
}
-void QQuickItemViewPrivate::refill(qreal from, qreal to, bool doBuffer)
+void QQuickItemViewPrivate::refill(qreal from, qreal to)
{
Q_Q(QQuickItemView);
if (!isValid() || !q->isComponentComplete())
@@ -1315,35 +1315,22 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to, bool doBuffer)
qreal bufferTo = to + buffer;
qreal fillFrom = from;
qreal fillTo = to;
- if (doBuffer && (bufferMode & BufferAfter))
- fillTo = bufferTo;
- if (doBuffer && (bufferMode & BufferBefore))
- fillFrom = bufferFrom;
-
- // Item creation and release is staggered in order to avoid
- // creating/releasing multiple items in one frame
- // while flicking (as much as possible).
- bool changed = addVisibleItems(fillFrom, fillTo, doBuffer);
+ bool added = addVisibleItems(fillFrom, fillTo, false);
+ bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
- if (!changed || deferredRelease) { // avoid destroying items in the same frame that we create
- if (removeNonVisibleItems(bufferFrom, bufferTo))
- changed = true;
- deferredRelease = false;
- } else {
- deferredRelease = true;
+ if (buffer && bufferMode != NoBuffer) {
+ if (bufferMode & BufferAfter)
+ fillTo = bufferTo;
+ if (bufferMode & BufferBefore)
+ fillFrom = bufferFrom;
+ added |= addVisibleItems(fillFrom, fillTo, true);
}
- if (changed) {
+ if (added || removed) {
markExtentsDirty();
+ updateBeginningEnd();
visibleItemsChanged();
- } else if (!doBuffer && buffer && bufferMode != NoBuffer) {
- refill(from, to, true);
- }
-
- if (!q->isMoving() && changed) {
- fillCacheBuffer = true;
- q->polish();
}
if (prevCount != itemCount)
@@ -1393,8 +1380,10 @@ void QQuickItemViewPrivate::layout()
}
if (!applyModelChanges() && !forceLayout) {
- if (fillCacheBuffer)
+ if (fillCacheBuffer) {
+ fillCacheBuffer = false;
refill();
+ }
return;
}
forceLayout = false;
@@ -1459,7 +1448,7 @@ bool QQuickItemViewPrivate::applyModelChanges()
// set positions correctly for the next insertion
if (!insertions.isEmpty()) {
- repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, insertionResult, removalResult);
+ repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, &insertionResult, &removalResult);
layoutVisibleItems(removals.first().index);
}
}
@@ -1476,7 +1465,7 @@ bool QQuickItemViewPrivate::applyModelChanges()
// set positions correctly for the next insertion
if (i < insertions.count() - 1) {
- repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, insertionResult, removalResult);
+ repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, &insertionResult, &removalResult);
layoutVisibleItems(insertions[i].index);
}
@@ -1487,7 +1476,7 @@ bool QQuickItemViewPrivate::applyModelChanges()
// reposition visibleItems.first() correctly so that the content y doesn't jump
if (removedCount != prevVisibleItemsCount)
- repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, insertionResult, removalResult);
+ repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstVisible, &insertionResult, &removalResult);
// Whatever removed/moved items remain are no longer visible items.
for (QHash<QDeclarativeChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin();
@@ -1567,27 +1556,31 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QDeclarativeChangeSet::Remo
}
}
}
+
+ if (removal.index + removal.count < visibleIndex)
+ removeResult->changeBeforeVisible -= removal.count;
+
return visibleAffected;
}
void QQuickItemViewPrivate::repositionFirstItem(FxViewItem *prevVisibleItemsFirst,
qreal prevVisibleItemsFirstPos,
FxViewItem *prevFirstVisible,
- const ChangeResult &insertionResult,
- const ChangeResult &removalResult)
+ ChangeResult *insertionResult,
+ ChangeResult *removalResult)
{
- const QDeclarativeNullableValue<qreal> prevViewPos = insertionResult.visiblePos;
+ const QDeclarativeNullableValue<qreal> prevViewPos = insertionResult->visiblePos;
// reposition visibleItems.first() correctly so that the content y doesn't jump
if (visibleItems.count()) {
- if (prevVisibleItemsFirst && insertionResult.changedFirstItem)
+ if (prevVisibleItemsFirst && insertionResult->changedFirstItem)
resetFirstItemPosition(prevVisibleItemsFirstPos);
if (prevFirstVisible && prevVisibleItemsFirst == prevFirstVisible
&& prevFirstVisible != *visibleItems.constBegin()) {
// the previous visibleItems.first() was also the first visible item, and it has been
// moved/removed, so move the new visibleItems.first() to the pos of the previous one
- if (!insertionResult.changedFirstItem)
+ if (!insertionResult->changedFirstItem)
resetFirstItemPosition(prevVisibleItemsFirstPos);
} else if (prevViewPos.isValid()) {
@@ -1596,14 +1589,16 @@ void QQuickItemViewPrivate::repositionFirstItem(FxViewItem *prevVisibleItemsFirs
// shift visibleItems.first() relative to the number of added/removed items
if (visibleItems.first()->position() > prevViewPos) {
- moveForwardsBy = insertionResult.sizeChangesAfterVisiblePos;
- moveBackwardsBy = removalResult.sizeChangesAfterVisiblePos;
+ moveForwardsBy = insertionResult->sizeChangesAfterVisiblePos;
+ moveBackwardsBy = removalResult->sizeChangesAfterVisiblePos;
} else if (visibleItems.first()->position() < prevViewPos) {
- moveForwardsBy = removalResult.sizeChangesBeforeVisiblePos;
- moveBackwardsBy = insertionResult.sizeChangesBeforeVisiblePos;
+ moveForwardsBy = removalResult->sizeChangesBeforeVisiblePos;
+ moveBackwardsBy = insertionResult->sizeChangesBeforeVisiblePos;
}
- adjustFirstItem(moveForwardsBy, moveBackwardsBy);
+ adjustFirstItem(moveForwardsBy, moveBackwardsBy, insertionResult->changeBeforeVisible + removalResult->changeBeforeVisible);
}
+ insertionResult->reset();
+ removalResult->reset();
}
}
@@ -1619,6 +1614,8 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous)
return 0;
if (requestedIndex != -1 && requestedIndex != modelIndex) {
+ if (requestedItem && requestedItem->item)
+ requestedItem->item->setParentItem(0);
delete requestedItem;
requestedItem = 0;
}
@@ -1631,7 +1628,6 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous)
item->setParentItem(q->contentItem());
QDeclarative_setParent_noEvent(item, q->contentItem());
requestedIndex = -1;
- fillCacheBuffer = false;
FxViewItem *viewItem = requestedItem;
if (!viewItem)
viewItem = newViewItem(modelIndex, item); // already in cache, so viewItem not initialized in initItem()
@@ -1665,9 +1661,6 @@ void QQuickItemView::createdItem(int index, QQuickItem *item)
if (index == d->currentIndex)
d->updateCurrent(index);
d->refill();
- } else {
- d->fillCacheBuffer = true;
- polish();
}
}
}
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index a2dd963dd2..52463afaaa 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -104,9 +104,18 @@ public:
qreal sizeChangesBeforeVisiblePos;
qreal sizeChangesAfterVisiblePos;
bool changedFirstItem;
+ int changeBeforeVisible;
ChangeResult(const QDeclarativeNullableValue<qreal> &p)
- : visiblePos(p), sizeChangesBeforeVisiblePos(0), sizeChangesAfterVisiblePos(0), changedFirstItem(false) {}
+ : visiblePos(p), sizeChangesBeforeVisiblePos(0), sizeChangesAfterVisiblePos(0),
+ changedFirstItem(false), changeBeforeVisible(0) {}
+
+ void reset() {
+ sizeChangesBeforeVisiblePos = 0.0;
+ sizeChangesAfterVisiblePos = 0.0;
+ changedFirstItem = false;
+ changeBeforeVisible = 0;
+ }
};
enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 };
@@ -130,7 +139,7 @@ public:
void regenerate();
void layout();
void refill();
- void refill(qreal from, qreal to, bool doBuffer = false);
+ void refill(qreal from, qreal to);
void mirrorChange();
FxViewItem *createItem(int modelIndex, bool asynchronous = false);
@@ -149,7 +158,7 @@ public:
bool applyModelChanges();
bool applyRemovalChange(const QDeclarativeChangeSet::Remove &removal, ChangeResult *changeResult, int *removedCount);
void repositionFirstItem(FxViewItem *prevVisibleItemsFirst, qreal prevVisibleItemsFirstPos,
- FxViewItem *prevFirstVisible, const ChangeResult &insertionResult, const ChangeResult &removalResult);
+ FxViewItem *prevFirstVisible, ChangeResult *insertionResult, ChangeResult *removalResult);
void checkVisible() const;
@@ -197,7 +206,6 @@ public:
bool ownModel : 1;
bool wrap : 1;
- bool deferredRelease : 1;
bool inApplyModelChanges : 1;
bool inViewportMoved : 1;
bool forceLayout : 1;
@@ -240,7 +248,7 @@ protected:
virtual FxViewItem *newViewItem(int index, QQuickItem *item) = 0;
virtual void repositionPackageItemAt(QQuickItem *item, int index) = 0;
virtual void resetFirstItemPosition(qreal pos = 0.0) = 0;
- virtual void adjustFirstItem(qreal forwards, qreal backwards) = 0;
+ virtual void adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible) = 0;
virtual void layoutVisibleItems(int fromModelIndex = 0) = 0;
virtual void changedVisibleIndex(int newIndex) = 0;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index f0ced5fc71..62155272c4 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
#define QML_FLICK_SNAPONETHRESHOLD 30
#endif
+//#define DEBUG_DELEGATE_LIFECYCLE
+
class FxListItemSG;
class QQuickListViewPrivate : public QQuickItemViewPrivate
@@ -94,7 +96,7 @@ public:
virtual void releaseItem(FxViewItem *item);
virtual void repositionPackageItemAt(QQuickItem *item, int index);
virtual void resetFirstItemPosition(qreal pos = 0.0);
- virtual void adjustFirstItem(qreal forwards, qreal backwards);
+ virtual void adjustFirstItem(qreal forwards, qreal backwards, int);
virtual void createHighlight();
virtual void updateHighlight();
@@ -601,7 +603,9 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
FxListItemSG *item = 0;
qreal pos = itemEnd;
while (modelIndex < model->count() && pos <= fillTo) {
-// qDebug() << "refill: append item" << modelIndex << "pos" << pos;
+#ifdef DEBUG_DELEGATE_LIFECYCLE
+ qDebug() << "refill: append item" << modelIndex << "pos" << pos;
+#endif
if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer))))
break;
item->setPosition(pos);
@@ -611,8 +615,14 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
++modelIndex;
changed = true;
}
+
+ if (doBuffer && requestedIndex != -1) // already waiting for an item
+ return changed;
+
while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos > fillFrom) {
-// qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos;
+#ifdef DEBUG_DELEGATE_LIFECYCLE
+ qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos;
+#endif
if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, doBuffer))))
break;
--visibleIndex;
@@ -641,8 +651,9 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
if (item->attached->delayRemove())
break;
if (item->size() > 0) {
-// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition();
-
+#ifdef DEBUG_DELEGATE_LIFECYCLE
+ qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition();
+#endif
// remove this item and all zero-sized items before it
while (item) {
if (item->index != -1)
@@ -662,7 +673,9 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) {
if (item->attached->delayRemove())
break;
-// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position();
+#ifdef DEBUG_DELEGATE_LIFECYCLE
+ qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position();
+#endif
visibleItems.removeLast();
releaseItem(item);
changed = true;
@@ -741,7 +754,7 @@ void QQuickListViewPrivate::resetFirstItemPosition(qreal pos)
item->setPosition(pos);
}
-void QQuickListViewPrivate::adjustFirstItem(qreal forwards, qreal backwards)
+void QQuickListViewPrivate::adjustFirstItem(qreal forwards, qreal backwards, int)
{
if (!visibleItems.count())
return;
@@ -1822,7 +1835,7 @@ void QQuickListView::setSpacing(qreal spacing)
if (spacing != d->spacing) {
d->spacing = spacing;
d->forceLayout = true;
- d->layout();
+ polish();
emit spacingChanged();
}
}
@@ -2188,14 +2201,6 @@ void QQuickListView::viewportMoved()
return;
d->inViewportMoved = true;
- // Set visibility of items to eliminate cost of items outside the visible area.
- qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
- qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
- for (int i = 0; i < d->visibleItems.count(); ++i) {
- FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i));
- item->item->setVisible(item->endPosition() >= from && item->position() <= to);
- }
-
if (yflick())
d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter;
else if (d->isRightToLeft())
@@ -2204,6 +2209,15 @@ void QQuickListView::viewportMoved()
d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter;
d->refill();
+
+ // Set visibility of items to eliminate cost of items outside the visible area.
+ qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
+ qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
+ for (int i = 0; i < d->visibleItems.count(); ++i) {
+ FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i));
+ item->item->setVisible(item->endPosition() >= from && item->position() <= to);
+ }
+
if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QQuickListViewPrivate::Mouse;
if (d->moveReason != QQuickListViewPrivate::SetIndex) {
@@ -2365,7 +2379,7 @@ void QQuickListView::updateSections()
d->updateSections();
if (d->itemCount) {
d->forceLayout = true;
- d->layout();
+ polish();
}
}
}
diff --git a/src/quick/items/qquickvisualdatamodel.cpp b/src/quick/items/qquickvisualdatamodel.cpp
index 3de1e91f7f..d52aec0433 100644
--- a/src/quick/items/qquickvisualdatamodel.cpp
+++ b/src/quick/items/qquickvisualdatamodel.cpp
@@ -425,6 +425,10 @@ QQuickVisualDataModel::ReleaseFlags QQuickVisualDataModelPrivate::release(QObjec
if (QQuickItem *item = qobject_cast<QQuickItem *>(object))
emitDestroyingItem(item);
cacheItem->object = 0;
+ if (cacheItem->incubationTask) {
+ releaseIncubator(cacheItem->incubationTask);
+ cacheItem->incubationTask = 0;
+ }
stat |= QQuickVisualModel::Destroyed;
} else {
stat |= QQuickVisualDataModel::Referenced;