diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2018-02-06 19:40:36 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2018-02-06 19:40:36 +0000 |
commit | 81b393227db1f28a3838ea9aa958d5e609fe0cdf (patch) | |
tree | 71bade271de1b7fe451f2cd505145979b9c4e34d /src/quick/items | |
parent | f252b5229dc291cbf0773d2252068b0b2a6d7c9e (diff) | |
parent | a9a9fa0c4737017aa4fc72b467eb45645d0912f0 (diff) |
Merge "Merge remote-tracking branch 'origin/5.10' into dev" into refs/staging/dev
Diffstat (limited to 'src/quick/items')
-rw-r--r-- | src/quick/items/qquickanimatedimage.cpp | 120 | ||||
-rw-r--r-- | src/quick/items/qquickanimatedimage_p_p.h | 21 | ||||
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 14 | ||||
-rw-r--r-- | src/quick/items/qquickflickable_p_p.h | 4 | ||||
-rw-r--r-- | src/quick/items/qquickframebufferobject.cpp | 1 | ||||
-rw-r--r-- | src/quick/items/qquickgridview.cpp | 14 | ||||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 35 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 3 | ||||
-rw-r--r-- | src/quick/items/qquickitemsmodule.cpp | 6 | ||||
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 76 | ||||
-rw-r--r-- | src/quick/items/qquickitemviewtransition_p.h | 18 | ||||
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/qquickloader.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickrepeater.cpp | 5 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 56 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.h | 6 | ||||
-rw-r--r-- | src/quick/items/qquickwindowmodule.cpp | 2 |
17 files changed, 235 insertions, 151 deletions
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index 4180714f86..5c9f893b63 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -54,26 +54,26 @@ QT_BEGIN_NAMESPACE QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine) { - if (!_movie) + if (!movie) return 0; - int current = _movie->currentFrameNumber(); + int current = movie->currentFrameNumber(); if (!frameMap.contains(current)) { QUrl requestedUrl; QQuickPixmap *pixmap = 0; - if (engine && !_movie->fileName().isEmpty()) { + if (engine && !movie->fileName().isEmpty()) { requestedUrl.setUrl(QString::fromUtf8("quickanimatedimage://%1#%2") - .arg(_movie->fileName()) + .arg(movie->fileName()) .arg(current)); } if (!requestedUrl.isEmpty()) { if (QQuickPixmap::isCached(requestedUrl, QSize(), QQuickImageProviderOptions())) pixmap = new QQuickPixmap(engine, requestedUrl); else - pixmap = new QQuickPixmap(requestedUrl, _movie->currentImage()); + pixmap = new QQuickPixmap(requestedUrl, movie->currentImage()); } else { pixmap = new QQuickPixmap; - pixmap->setImage(_movie->currentImage()); + pixmap->setImage(movie->currentImage()); } frameMap.insert(current, pixmap); } @@ -138,7 +138,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine QQuickAnimatedImage::QQuickAnimatedImage(QQuickItem *parent) : QQuickImage(*(new QQuickAnimatedImagePrivate), parent) { - QObject::connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged); + connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged); } QQuickAnimatedImage::~QQuickAnimatedImage() @@ -148,7 +148,7 @@ QQuickAnimatedImage::~QQuickAnimatedImage() if (d->reply) d->reply->deleteLater(); #endif - delete d->_movie; + delete d->movie; qDeleteAll(d->frameMap); d->frameMap.clear(); } @@ -164,9 +164,9 @@ QQuickAnimatedImage::~QQuickAnimatedImage() bool QQuickAnimatedImage::isPaused() const { Q_D(const QQuickAnimatedImage); - if (!d->_movie) + if (!d->movie) return d->paused; - return d->_movie->state()==QMovie::Paused; + return d->movie->state()==QMovie::Paused; } void QQuickAnimatedImage::setPaused(bool pause) @@ -174,11 +174,11 @@ void QQuickAnimatedImage::setPaused(bool pause) Q_D(QQuickAnimatedImage); if (pause == d->paused) return; - if (!d->_movie) { + if (!d->movie) { d->paused = pause; emit pausedChanged(); } else { - d->_movie->setPaused(pause); + d->movie->setPaused(pause); } } @@ -203,9 +203,9 @@ void QQuickAnimatedImage::setPaused(bool pause) bool QQuickAnimatedImage::isPlaying() const { Q_D(const QQuickAnimatedImage); - if (!d->_movie) + if (!d->movie) return d->playing; - return d->_movie->state()!=QMovie::NotRunning; + return d->movie->state()!=QMovie::NotRunning; } void QQuickAnimatedImage::setPlaying(bool play) @@ -213,15 +213,15 @@ void QQuickAnimatedImage::setPlaying(bool play) Q_D(QQuickAnimatedImage); if (play == d->playing) return; - if (!d->_movie) { + if (!d->movie) { d->playing = play; emit playingChanged(); return; } if (play) - d->_movie->start(); + d->movie->start(); else - d->_movie->stop(); + d->movie->stop(); } /*! @@ -237,27 +237,27 @@ void QQuickAnimatedImage::setPlaying(bool play) int QQuickAnimatedImage::currentFrame() const { Q_D(const QQuickAnimatedImage); - if (!d->_movie) - return d->preset_currentframe; - return d->_movie->currentFrameNumber(); + if (!d->movie) + return d->presetCurrentFrame; + return d->movie->currentFrameNumber(); } void QQuickAnimatedImage::setCurrentFrame(int frame) { Q_D(QQuickAnimatedImage); - if (!d->_movie) { - d->preset_currentframe = frame; + if (!d->movie) { + d->presetCurrentFrame = frame; return; } - d->_movie->jumpToFrame(frame); + d->movie->jumpToFrame(frame); } int QQuickAnimatedImage::frameCount() const { Q_D(const QQuickAnimatedImage); - if (!d->_movie) + if (!d->movie) return 0; - return d->_movie->frameCount(); + return d->movie->frameCount(); } /*! @@ -280,8 +280,8 @@ void QQuickAnimatedImage::setSpeed(qreal speed) Q_D(QQuickAnimatedImage); if (d->speed != speed) { d->speed = speed; - if (d->_movie) - d->_movie->setSpeed(qRound(speed * 100.0)); + if (d->movie) + d->movie->setSpeed(qRound(speed * 100.0)); emit speedChanged(); } } @@ -304,10 +304,7 @@ void QQuickAnimatedImage::setSource(const QUrl &url) d->frameMap.clear(); d->oldPlaying = isPlaying(); - if (d->_movie) { - d->setMovie(nullptr); - } - + d->setMovie(nullptr); d->url = url; emit sourceChanged(d->url); @@ -361,10 +358,8 @@ void QQuickAnimatedImage::load() req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); d->reply = qmlEngine(this)->networkAccessManager()->get(req); - QObject::connect(d->reply, SIGNAL(finished()), - this, SLOT(movieRequestFinished())); - QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), - this, SLOT(requestProgress(qint64,qint64))); + connect(d->reply, &QNetworkReply::finished, this, &QQuickAnimatedImage::movieRequestFinished); + connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(requestProgress(qint64,qint64))); #endif } } @@ -395,7 +390,7 @@ void QQuickAnimatedImage::movieRequestFinished() } #endif - if (!d->_movie || !d->_movie->isValid()) { + if (!d->movie || !d->movie->isValid()) { qmlWarning(this) << "Error Reading Animated Image File " << d->url.toString(); d->setMovie(nullptr); d->setImage(QImage()); @@ -416,13 +411,11 @@ void QQuickAnimatedImage::movieRequestFinished() return; } - connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)), - this, SLOT(playingStatusChanged())); - connect(d->_movie, SIGNAL(frameChanged(int)), - this, SLOT(movieUpdate())); + connect(d->movie, &QMovie::stateChanged, this, &QQuickAnimatedImage::playingStatusChanged); + connect(d->movie, &QMovie::frameChanged, this, &QQuickAnimatedImage::movieUpdate); if (d->cache) - d->_movie->setCacheMode(QMovie::CacheAll); - d->_movie->setSpeed(qRound(d->speed * 100.0)); + d->movie->setCacheMode(QMovie::CacheAll); + d->movie->setSpeed(qRound(d->speed * 100.0)); d->status = Ready; emit statusChanged(d->status); @@ -433,22 +426,21 @@ void QQuickAnimatedImage::movieRequestFinished() } bool pausedAtStart = d->paused; - if (d->playing) { - d->_movie->start(); - } + if (d->playing) + d->movie->start(); if (pausedAtStart) - d->_movie->setPaused(true); + d->movie->setPaused(true); if (d->paused || !d->playing) { - d->_movie->jumpToFrame(d->preset_currentframe); - d->preset_currentframe = 0; + d->movie->jumpToFrame(d->presetCurrentFrame); + d->presetCurrentFrame = 0; } d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this))); if (isPlaying() != d->oldPlaying) emit playingChanged(); - if (d->_movie) - d->currentSourceSize = d->_movie->currentPixmap().size(); + if (d->movie) + d->currentSourceSize = d->movie->currentPixmap().size(); else d->currentSourceSize = QSize(0, 0); @@ -467,7 +459,7 @@ void QQuickAnimatedImage::movieUpdate() d->frameMap.clear(); } - if (d->_movie) { + if (d->movie) { d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this))); emit frameChanged(); } @@ -477,12 +469,12 @@ void QQuickAnimatedImage::playingStatusChanged() { Q_D(QQuickAnimatedImage); - if ((d->_movie->state() != QMovie::NotRunning) != d->playing) { - d->playing = (d->_movie->state() != QMovie::NotRunning); + if ((d->movie->state() != QMovie::NotRunning) != d->playing) { + d->playing = (d->movie->state() != QMovie::NotRunning); emit playingChanged(); } - if ((d->_movie->state() == QMovie::Paused) != d->paused) { - d->paused = (d->_movie->state() == QMovie::Paused); + if ((d->movie->state() == QMovie::Paused) != d->paused) { + d->paused = (d->movie->state() == QMovie::Paused); emit pausedChanged(); } } @@ -493,13 +485,11 @@ void QQuickAnimatedImage::onCacheChanged() if (!cache()) { qDeleteAll(d->frameMap); d->frameMap.clear(); - if (d->_movie) { - d->_movie->setCacheMode(QMovie::CacheNone); - } + if (d->movie) + d->movie->setCacheMode(QMovie::CacheNone); } else { - if (d->_movie) { - d->_movie->setCacheMode(QMovie::CacheAll); - } + if (d->movie) + d->movie->setCacheMode(QMovie::CacheAll); } } @@ -515,13 +505,15 @@ void QQuickAnimatedImage::componentComplete() load(); } -void QQuickAnimatedImagePrivate::setMovie(QMovie *movie) +void QQuickAnimatedImagePrivate::setMovie(QMovie *m) { + if (movie == m) + return; Q_Q(QQuickAnimatedImage); const int oldFrameCount = q->frameCount(); - delete _movie; - _movie = movie; + delete movie; + movie = m; if (oldFrameCount != q->frameCount()) emit q->frameCountChanged(); diff --git a/src/quick/items/qquickanimatedimage_p_p.h b/src/quick/items/qquickanimatedimage_p_p.h index ef30c39fed..1a74f67424 100644 --- a/src/quick/items/qquickanimatedimage_p_p.h +++ b/src/quick/items/qquickanimatedimage_p_p.h @@ -70,29 +70,30 @@ class QQuickAnimatedImagePrivate : public QQuickImagePrivate public: QQuickAnimatedImagePrivate() - : playing(true), paused(false), speed(1.0), preset_currentframe(0), _movie(0), oldPlaying(false) + : playing(true), paused(false), oldPlaying(false), padding(0) + , presetCurrentFrame(0), speed(1.0), currentSourceSize(0, 0), movie(nullptr) #if QT_CONFIG(qml_network) - , reply(0), redirectCount(0) + , reply(nullptr), redirectCount(0) #endif - , currentSourceSize(0, 0) { } QQuickPixmap *infoForCurrentFrame(QQmlEngine *engine); + void setMovie(QMovie *movie); - bool playing; - bool paused; + bool playing : 1; + bool paused : 1; + bool oldPlaying : 1; + unsigned padding: 29; + int presetCurrentFrame; qreal speed; - int preset_currentframe; - QMovie *_movie; - bool oldPlaying; + QSize currentSourceSize; + QMovie *movie; #if QT_CONFIG(qml_network) QNetworkReply *reply; int redirectCount; #endif QMap<int, QQuickPixmap *> frameMap; - QSize currentSourceSize; - void setMovie(QMovie *movie); }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index bec5f06d72..95d1229c8d 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1435,17 +1435,23 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) case Qt::ScrollUpdate: if (d->scrollingPhase) d->pressed = true; -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS + // TODO eliminate this timer when ScrollMomentum has been added d->movementEndingTimer.start(MovementEndingTimerInterval, this); #endif break; case Qt::ScrollEnd: + // TODO most of this should be done at transition to ScrollMomentum phase, + // then do what the movementEndingTimer triggers at transition to ScrollEnd phase d->pressed = false; d->scrollingPhase = false; d->draggingEnding(); event->accept(); returnToBounds(); d->lastPosTime = -1; +#ifdef Q_OS_MACOS + d->movementEndingTimer.start(MovementEndingTimerInterval, this); +#endif return; } @@ -2670,13 +2676,15 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding) if (hMovementEnding && d->hData.moving && (!d->pressed && !d->stealMouse)) { d->hData.moving = false; - d->hMoved = false; + if (!d->scrollingPhase) + d->hMoved = false; emit movingHorizontallyChanged(); } if (vMovementEnding && d->vData.moving && (!d->pressed && !d->stealMouse)) { d->vData.moving = false; - d->vMoved = false; + if (!d->scrollingPhase) + d->vMoved = false; emit movingVerticallyChanged(); } if (wasMoving && !isMoving()) { diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 54cc67875a..c2531e6012 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -106,9 +106,10 @@ public: , continuousFlickVelocity(0), velocityTime(), vTime(0) , smoothVelocity(fp), atEnd(false), atBeginning(true) , transitionToSet(false) - , fixingUp(false), inOvershoot(false), moving(false), flicking(false) + , fixingUp(false), inOvershoot(false), inRebound(false), moving(false), flicking(false) , dragging(false), extentsChanged(false) , explicitValue(false), minExtentDirty(true), maxExtentDirty(true) + , unused(0) {} ~AxisData(); @@ -168,6 +169,7 @@ public: bool explicitValue : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; + uint unused : 19; }; bool flickX(qreal velocity); diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp index 5a40d6b705..9b133a823e 100644 --- a/src/quick/items/qquickframebufferobject.cpp +++ b/src/quick/items/qquickframebufferobject.cpp @@ -313,6 +313,7 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode desiredFboSize *= n->devicePixelRatio; if (n->fbo && ((d->followsItemSize && n->fbo->size() != desiredFboSize) || n->invalidatePending)) { + delete n->texture(); delete n->fbo; n->fbo = 0; delete n->msDisplayFbo; diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index f68dfbf581..b2adf96f0e 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -537,13 +537,12 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal if (visibleItems.count()) { FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.constFirst()); rowPos = firstItem->rowPos(); - colNum = qFloor((firstItem->colPos()+colSize()/2) / colSize()); - if (--colNum < 0) { - colNum = columns - 1; - rowPos -= rowSize(); - } - } else { - colNum = qFloor((colPos+colSize()/2) / colSize()); + colPos = firstItem->colPos(); + } + colNum = qFloor((colPos+colSize()/2) / colSize()); + if (--colNum < 0) { + colNum = columns - 1; + rowPos -= rowSize(); } // Prepend @@ -894,7 +893,6 @@ void QQuickGridViewPrivate::initializeCurrentItem() void QQuickGridViewPrivate::fixupPosition() { - moveReason = Other; if (flow == QQuickGridView::FlowLeftToRight) fixupY(); else diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index f4d11e32bd..f615e85e1b 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -87,6 +87,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(DBG_MOUSE_TARGET) Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE) +Q_DECLARE_LOGGING_CATEGORY(lcTransient) void debugFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1) { @@ -970,7 +971,7 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const Keys.onEscapePressed: { console.log("escapeItem is handling escape"); - event.accepted = true; + // event.accepted is set to true by default for the specific key handlers } } @@ -3264,11 +3265,13 @@ void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o) } if (thisWindow) { - if (itemWindow) + if (itemWindow) { + qCDebug(lcTransient) << thisWindow << "is transient for" << itemWindow; thisWindow->setTransientParent(itemWindow); - else + } else { QObject::connect(item, SIGNAL(windowChanged(QQuickWindow*)), thisWindow, SLOT(setTransientParent_helper(QQuickWindow*))); + } } o->setParent(that); } @@ -3667,8 +3670,9 @@ QQmlListProperty<QObject> QQuickItemPrivate::data() \qmlproperty real QtQuick::Item::childrenRect.y \qmlproperty real QtQuick::Item::childrenRect.width \qmlproperty real QtQuick::Item::childrenRect.height + \readonly - This property holds the collective position and size of the item's + This read-only property holds the collective position and size of the item's children. This property is useful if you need to access the collective geometry @@ -5806,19 +5810,24 @@ bool QQuickItem::isVisible() const return d->effectiveVisible; } -void QQuickItem::setVisible(bool v) +void QQuickItemPrivate::setVisible(bool visible) { - Q_D(QQuickItem); - if (v == d->explicitVisible) + if (visible == explicitVisible) return; - d->explicitVisible = v; - if (!v) - d->dirty(QQuickItemPrivate::Visible); + explicitVisible = visible; + if (!visible) + dirty(QQuickItemPrivate::Visible); - const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible()); - if (childVisibilityChanged && d->parentItem) - emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this! + const bool childVisibilityChanged = setEffectiveVisibleRecur(calcEffectiveVisible()); + if (childVisibilityChanged && parentItem) + emit parentItem->visibleChildrenChanged(); // signal the parent, not this! +} + +void QQuickItem::setVisible(bool v) +{ + Q_D(QQuickItem); + d->setVisible(v); } /*! diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 0c02c66ef2..02e7424d1e 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -311,7 +311,6 @@ public: static void transform_clear(QQmlListProperty<QQuickTransform> *list); void _q_resourceObjectDeleted(QObject *); - void _q_windowChanged(QQuickWindow *w); quint64 _q_createJSWrapper(QV4::ExecutionEngine *engine); enum ChangeType { @@ -581,6 +580,8 @@ public: virtual bool handlePointerEvent(QQuickPointerEvent *, bool avoidExclusiveGrabber = false); + virtual void setVisible(bool visible); + bool isTransparentForPositioner() const; void setTransparentForPositioner(bool trans); diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index f03942ecee..51a91e1f7a 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -113,6 +113,10 @@ #include <private/qqmlmetatype_p.h> #include <QtQuick/private/qquickaccessibleattached_p.h> +QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcTransient) +QT_END_NAMESPACE + static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject *parent) { // When setting a parent (especially during dynamic object creation) in QML, @@ -127,6 +131,7 @@ static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject QQuickWindow *win = qmlobject_cast<QQuickWindow *>(obj); if (win) { // A Window inside an Item should be transient for that item's window + qCDebug(lcTransient) << win << "is transient for" << parentItem->window(); win->setTransientParent(parentItem->window()); return QQmlPrivate::Parented; } @@ -136,6 +141,7 @@ static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject QQuickWindow *win = qmlobject_cast<QQuickWindow *>(obj); if (win) { // A Window inside a Window should be transient for it + qCDebug(lcTransient) << win << "is transient for" << parentWindow; win->setTransientParent(parentWindow); return QQmlPrivate::Parented; } else { diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 10f6c63170..856070634c 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1751,6 +1751,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) void QQuickItemViewPrivate::clear() { currentChanges.reset(); + bufferedChanges.reset(); timeline.clear(); releaseVisibleItems(); @@ -1808,51 +1809,56 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to) if (!isValid() || !q->isComponentComplete()) return; - bufferPause.stop(); - currentChanges.reset(); + do { + bufferPause.stop(); + if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) { + currentChanges.reset(); + bufferedChanges.reset(); + releaseVisibleItems(); + } - int prevCount = itemCount; - itemCount = model->count(); - qreal bufferFrom = from - buffer; - qreal bufferTo = to + buffer; - qreal fillFrom = from; - qreal fillTo = to; - - bool added = addVisibleItems(fillFrom, fillTo, bufferFrom, bufferTo, false); - bool removed = removeNonVisibleItems(bufferFrom, bufferTo); - - if (requestedIndex == -1 && buffer && bufferMode != NoBuffer) { - if (added) { - // We've already created a new delegate this frame. - // Just schedule a buffer refill. - bufferPause.start(); - } else { - if (bufferMode & BufferAfter) - fillTo = bufferTo; - if (bufferMode & BufferBefore) - fillFrom = bufferFrom; - added |= addVisibleItems(fillFrom, fillTo, bufferFrom, bufferTo, true); + int prevCount = itemCount; + itemCount = model->count(); + qreal bufferFrom = from - buffer; + qreal bufferTo = to + buffer; + qreal fillFrom = from; + qreal fillTo = to; + + bool added = addVisibleItems(fillFrom, fillTo, bufferFrom, bufferTo, false); + bool removed = removeNonVisibleItems(bufferFrom, bufferTo); + + if (requestedIndex == -1 && buffer && bufferMode != NoBuffer) { + if (added) { + // We've already created a new delegate this frame. + // Just schedule a buffer refill. + bufferPause.start(); + } else { + if (bufferMode & BufferAfter) + fillTo = bufferTo; + if (bufferMode & BufferBefore) + fillFrom = bufferFrom; + added |= addVisibleItems(fillFrom, fillTo, bufferFrom, bufferTo, true); + } } - } - if (added || removed) { - markExtentsDirty(); - updateBeginningEnd(); - visibleItemsChanged(); - updateHeader(); - updateFooter(); - updateViewport(); - } + if (added || removed) { + markExtentsDirty(); + updateBeginningEnd(); + visibleItemsChanged(); + updateHeader(); + updateFooter(); + updateViewport(); + } - if (prevCount != itemCount) - emit q->countChanged(); + if (prevCount != itemCount) + emit q->countChanged(); + } while (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()); } void QQuickItemViewPrivate::regenerate(bool orientationChanged) { Q_Q(QQuickItemView); if (q->isComponentComplete()) { - currentChanges.reset(); if (orientationChanged) { delete header; header = 0; diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index 3d2f5361b1..29a62f7f10 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -58,6 +58,8 @@ QT_REQUIRE_CONFIG(quick_viewtransitions); #include <QtCore/qobject.h> #include <QtCore/qpoint.h> #include <QtQml/qqml.h> +#include <private/qqmlguard_p.h> +#include <private/qquicktransition_p.h> QT_BEGIN_NAMESPACE @@ -115,14 +117,14 @@ public: QList<QObject *> moveTransitionTargets; QList<QObject *> removeTransitionTargets; - QQuickTransition *populateTransition; - QQuickTransition *addTransition; - QQuickTransition *addDisplacedTransition; - QQuickTransition *moveTransition; - QQuickTransition *moveDisplacedTransition; - QQuickTransition *removeTransition; - QQuickTransition *removeDisplacedTransition; - QQuickTransition *displacedTransition; + QQmlGuard<QQuickTransition> populateTransition; + QQmlGuard<QQuickTransition> addTransition; + QQmlGuard<QQuickTransition> addDisplacedTransition; + QQmlGuard<QQuickTransition> moveTransition; + QQmlGuard<QQuickTransition> moveDisplacedTransition; + QQmlGuard<QQuickTransition> removeTransition; + QQmlGuard<QQuickTransition> removeDisplacedTransition; + QQmlGuard<QQuickTransition> displacedTransition; private: friend class QQuickItemViewTransitionJob; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 11eaf393ea..54dfbafaa2 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -1468,9 +1468,6 @@ void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometry void QQuickListViewPrivate::fixupPosition() { - if ((haveHighlightRange && highlightRange == QQuickListView::StrictlyEnforceRange) - || snapMode != QQuickListView::NoSnap) - moveReason = Other; if (orient == QQuickListView::Vertical) fixupY(); else diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 42dd532d91..1f2828585c 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -48,6 +48,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcTransient) + static const QQuickItemPrivate::ChangeTypes watchedChanges = QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index 658a7de3d4..ba9460bf76 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -374,9 +374,12 @@ void QQuickRepeater::clear() if (complete) emit itemRemoved(i, item); d->model->release(item); - item->setParentItem(0); } } + for (QQuickItem *item : qAsConst(d->deletables)) { + if (item) + item->setParentItem(0); + } } d->deletables.clear(); d->itemCount = 0; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index cfeaa6f22d..2e36f07fdb 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -78,6 +78,9 @@ # include <private/qopenglvertexarrayobject_p.h> # include <private/qsgdefaultrendercontext_p.h> #endif +#ifndef QT_NO_DEBUG_STREAM +#include <private/qdebug_p.h> +#endif QT_BEGIN_NAMESPACE @@ -88,6 +91,7 @@ Q_LOGGING_CATEGORY(DBG_MOUSE_TARGET, "qt.quick.mouse.target") Q_LOGGING_CATEGORY(DBG_HOVER_TRACE, "qt.quick.hover.trace") Q_LOGGING_CATEGORY(DBG_FOCUS, "qt.quick.focus") Q_LOGGING_CATEGORY(DBG_DIRTY, "qt.quick.dirty") +Q_LOGGING_CATEGORY(lcTransient, "qt.quick.window.transient") extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); @@ -576,13 +580,21 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) QObject::connect(q, SIGNAL(focusObjectChanged(QObject*)), q, SIGNAL(activeFocusItemChanged())); QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(handleScreenChanged(QScreen*))); - + QObject::connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), + q, SLOT(handleApplicationStateChanged(Qt::ApplicationState))); QObject::connect(q, SIGNAL(frameSwapped()), q, SLOT(runJobsAfterSwap()), Qt::DirectConnection); if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>()) service->addWindow(q); } +void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state) +{ + Q_D(QQuickWindow); + if (state != Qt::ApplicationActive && d->contentItem) + d->contentItem->windowDeactivateEvent(); +} + /*! \property QQuickWindow::data \internal @@ -2280,6 +2292,7 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) con void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) { + Q_Q(QQuickWindow); // If users spin the eventloop as a result of event delivery, we disable // event compression and send events directly. This is because we consider // the usecase a bit evil, but we at least don't want to lose events. @@ -2289,8 +2302,11 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) if (event->asPointerMouseEvent()) { deliverMouseEvent(event->asPointerMouseEvent()); // failsafe: never allow any kind of grab to persist after release - if (event->isReleaseEvent() && event->buttons() == Qt::NoButton) + QQuickItem *grabber = q->mouseGrabberItem(); + if (event->isReleaseEvent() && event->buttons() == Qt::NoButton && grabber) { event->clearGrabbers(); + sendUngrabEvent(grabber, false); + } } else if (event->asPointerTouchEvent()) { deliverTouchEvent(event->asPointerTouchEvent()); } else { @@ -2961,8 +2977,10 @@ void QQuickWindowPrivate::data_append(QQmlListProperty<QObject> *property, QObje if (!o) return; QQuickWindow *that = static_cast<QQuickWindow *>(property->object); - if (QQuickWindow *window = qmlobject_cast<QQuickWindow *>(o)) + if (QQuickWindow *window = qmlobject_cast<QQuickWindow *>(o)) { + qCDebug(lcTransient) << window << "is transient for" << that; window->setTransientParent(that); + } QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(that->contentItem())->data(); itemProperty.append(&itemProperty, o); } @@ -3493,6 +3511,7 @@ void QQuickWindow::cleanupSceneGraph() void QQuickWindow::setTransientParent_helper(QQuickWindow *window) { + qCDebug(lcTransient) << this << "is transient for" << window; setTransientParent(window); disconnect(sender(), SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(setTransientParent_helper(QQuickWindow*))); @@ -4935,6 +4954,37 @@ void QQuickWindow::setTextRenderType(QQuickWindow::TextRenderType renderType) QQuickWindowPrivate::textRenderType = renderType; } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QQuickWindow *win) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + if (!win) { + debug << "QQuickWindow(0)"; + return debug; + } + + debug << win->metaObject()->className() << '(' << static_cast<const void *>(win); + if (win->isActive()) + debug << " active"; + if (win->isExposed()) + debug << " exposed"; + debug << ", visibility=" << win->visibility() << ", flags=" << win->flags(); + if (!win->title().isEmpty()) + debug << ", title=" << win->title(); + if (!win->objectName().isEmpty()) + debug << ", name=" << win->objectName(); + if (win->parent()) + debug << ", parent=" << static_cast<const void *>(win->parent()); + if (win->transientParent()) + debug << ", transientParent=" << static_cast<const void *>(win->transientParent()); + debug << ", geometry="; + QtDebugUtils::formatQRect(debug, win->geometry()); + debug << ')'; + return debug; +} +#endif + #include "moc_qquickwindow.cpp" QT_END_NAMESPACE diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 06af7bbf02..53e0581fbb 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -234,7 +234,7 @@ private Q_SLOTS: void handleScreenChanged(QScreen *screen); void setTransientParent_helper(QQuickWindow *window); void runJobsAfterSwap(); - + void handleApplicationStateChanged(Qt::ApplicationState state); private: friend class QQuickItem; friend class QQuickWidget; @@ -243,6 +243,10 @@ private: Q_DISABLE_COPY(QQuickWindow) }; +#ifndef QT_NO_DEBUG_STREAM +QDebug Q_QUICK_EXPORT operator<<(QDebug debug, const QQuickWindow *item); +#endif + QT_END_NAMESPACE Q_DECLARE_METATYPE(QQuickWindow *) diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index ebf5809658..f048f12bf9 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -52,6 +52,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcTransient) + class QQuickWindowQmlImplPrivate : public QQuickWindowPrivate { public: |