diff options
Diffstat (limited to 'src/quick')
27 files changed, 292 insertions, 190 deletions
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index 5bc5b0faff..2f76671b1a 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(); } void QQuickAnimatedImage::setSource(const QUrl &url) @@ -278,10 +278,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); @@ -335,10 +332,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 } } @@ -369,7 +364,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()); @@ -390,12 +385,10 @@ 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->setCacheMode(QMovie::CacheAll); d->status = Ready; emit statusChanged(d->status); @@ -406,22 +399,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); @@ -440,7 +432,7 @@ void QQuickAnimatedImage::movieUpdate() d->frameMap.clear(); } - if (d->_movie) { + if (d->movie) { d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this))); emit frameChanged(); } @@ -450,12 +442,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(); } } @@ -466,13 +458,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); } } @@ -488,13 +478,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 68c4f2d359..e172962ee4 100644 --- a/src/quick/items/qquickanimatedimage_p_p.h +++ b/src/quick/items/qquickanimatedimage_p_p.h @@ -70,28 +70,29 @@ class QQuickAnimatedImagePrivate : public QQuickImagePrivate public: QQuickAnimatedImagePrivate() - : playing(true), paused(false), preset_currentframe(0), _movie(0), oldPlaying(false) + : playing(true), paused(false), oldPlaying(false), padding(0) + , presetCurrentFrame(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; - int preset_currentframe; - QMovie *_movie; - bool oldPlaying; + bool playing : 1; + bool paused : 1; + bool oldPlaying : 1; + unsigned padding: 29; + int presetCurrentFrame; + 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 ae5bdc3083..2ad65058b3 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 8609a15fcd..bdffeb2101 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 042ee21aec..20ba067a6b 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 c56cfd3005..2be64362b2 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 @@ -895,7 +894,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 6b123d1dfe..dac37e284b 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 2f0c316602..285e86048c 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 { @@ -574,6 +573,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 fcf6e49135..b89ee764c3 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -111,6 +111,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, @@ -125,6 +129,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; } @@ -134,6 +139,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 27b8d32707..d5601292b7 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 a056575f41..8b8469f801 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 @@ -2953,8 +2965,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); } @@ -3485,6 +3499,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*))); @@ -4927,6 +4942,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 022c4738f2..5ec5a0f95f 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -232,7 +232,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; @@ -241,6 +241,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 45e3f0004d..6165ce1ba1 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: diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp index 30088846a6..4cec84646e 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp @@ -233,11 +233,11 @@ void QSGAbstractSoftwareRenderer::setBackgroundColor(const QColor &color) renderableNode(m_background)->markMaterialDirty(); } -void QSGAbstractSoftwareRenderer::setBackgroundSize(const QSize &size) +void QSGAbstractSoftwareRenderer::setBackgroundRect(const QRect &rect) { - if (m_background->rect().size().toSize() == size) + if (m_background->rect().toRect() == rect) return; - m_background->setRect(0.0f, 0.0f, size.width(), size.height()); + m_background->setRect(rect); renderableNode(m_background)->markGeometryDirty(); // Invalidate the whole scene when the background is resized markDirty(); @@ -248,9 +248,9 @@ QColor QSGAbstractSoftwareRenderer::backgroundColor() return m_background->color(); } -QSize QSGAbstractSoftwareRenderer::backgroundSize() +QRect QSGAbstractSoftwareRenderer::backgroundRect() { - return m_background->rect().size().toSize(); + return m_background->rect().toRect(); } void QSGAbstractSoftwareRenderer::nodeAdded(QSGNode *node) diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h index f20c2cf977..f6594d931a 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h @@ -83,9 +83,9 @@ protected: QRegion optimizeRenderList(); void setBackgroundColor(const QColor &color); - void setBackgroundSize(const QSize &size); + void setBackgroundRect(const QRect &rect); QColor backgroundColor(); - QSize backgroundSize(); + QRect backgroundRect(); // only known after calling optimizeRenderList() bool isOpaque() const { return m_isOpaque; } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp index 186fd92fb7..303f98c801 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp @@ -79,7 +79,7 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target) QElapsedTimer renderTimer; // Setup background item - setBackgroundSize(QSize(target->width(), target->height())); + setBackgroundRect(m_projectionRect); setBackgroundColor(clearColor()); renderTimer.start(); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp index 85d04fe136..d403884b4e 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp @@ -112,7 +112,8 @@ void QSGSoftwareRenderer::render() QElapsedTimer renderTimer; setBackgroundColor(clearColor()); - setBackgroundSize(QSize(m_paintDevice->width() / m_paintDevice->devicePixelRatio(), + setBackgroundRect(QRect(0, 0, + m_paintDevice->width() / m_paintDevice->devicePixelRatio(), m_paintDevice->height() / m_paintDevice->devicePixelRatio())); // Build Renderlist diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 61380b3ea0..aecb7115ea 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -281,15 +281,19 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, return; } - QQmlProperty prop = property(propertyName); //### better way to check for signal property? - - if (prop.type() & QQmlProperty::SignalProperty) { - QQuickReplaceSignalHandler *handler = new QQuickReplaceSignalHandler; - handler->property = prop; - handler->expression.take(new QQmlBoundSignalExpression(object, QQmlPropertyPrivate::get(prop)->signalIndex(), - QQmlContextData::get(qmlContext(q)), object, compilationUnit->runtimeFunctions.at(binding->value.compiledScriptIndex))); - signalReplacements << handler; - return; + if (propertyName.count() >= 3 && + propertyName.at(0) == QLatin1Char('o') && + propertyName.at(1) == QLatin1Char('n') && + propertyName.at(2).isUpper()) { + QQmlProperty prop = property(propertyName); + if (prop.isSignalProperty()) { + QQuickReplaceSignalHandler *handler = new QQuickReplaceSignalHandler; + handler->property = prop; + handler->expression.take(new QQmlBoundSignalExpression(object, QQmlPropertyPrivate::get(prop)->signalIndex(), + QQmlContextData::get(qmlContext(q)), object, compilationUnit->runtimeFunctions.at(binding->value.compiledScriptIndex))); + signalReplacements << handler; + return; + } } if (binding->type == QV4::CompiledData::Binding::Type_Script) { @@ -395,7 +399,10 @@ QQmlProperty QQuickPropertyChangesPrivate::property(const QString &property) { Q_Q(QQuickPropertyChanges); - QQmlProperty prop(object, property, qmlContext(q)); + QQmlContextData *context = nullptr; + if (QQmlData *ddata = QQmlData::get(q)) + context = ddata->outerContext; + QQmlProperty prop = QQmlPropertyPrivate::create(object, property, context); if (!prop.isValid()) { qmlWarning(q) << QQuickPropertyChanges::tr("Cannot assign to non-existent property \"%1\"").arg(property); return QQmlProperty(); @@ -415,9 +422,10 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions() ActionList list; for (int ii = 0; ii < d->properties.count(); ++ii) { + QQmlProperty prop = d->property(d->properties.at(ii).first); - QQuickStateAction a(d->object, d->properties.at(ii).first, - qmlContext(this), d->properties.at(ii).second); + QQuickStateAction a(d->object, prop, d->properties.at(ii).first, + d->properties.at(ii).second); if (a.property.isValid()) { a.restore = restoreEntryValues(); @@ -426,7 +434,6 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions() } for (int ii = 0; ii < d->signalReplacements.count(); ++ii) { - QQuickReplaceSignalHandler *handler = d->signalReplacements.at(ii); if (handler->property.isValid()) { diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index 58f7fc8439..78dc855326 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -122,7 +122,8 @@ Q_QUICK_PRIVATE_EXPORT ContextMatcher qt_quick_shortcut_context_matcher() Q_QUICK_PRIVATE_EXPORT void qt_quick_set_shortcut_context_matcher(ContextMatcher matcher) { - *ctxMatcher() = matcher; + if (!ctxMatcher.isDestroyed()) + *ctxMatcher() = matcher; } QT_BEGIN_NAMESPACE diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp index 0a49d41491..ca8b7bbc2b 100644 --- a/src/quick/util/qquickstate.cpp +++ b/src/quick/util/qquickstate.cpp @@ -68,10 +68,9 @@ QQuickStateAction::QQuickStateAction(QObject *target, const QString &propertyNam fromValue = property.read(); } -QQuickStateAction::QQuickStateAction(QObject *target, const QString &propertyName, - QQmlContext *context, const QVariant &value) +QQuickStateAction::QQuickStateAction(QObject *target, const QQmlProperty &property, const QString &propertyName, const QVariant &value) : restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), - property(target, propertyName, context), toValue(value), + property(property), toValue(value), fromBinding(0), event(0), specifiedObject(target), specifiedProperty(propertyName) { diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h index 7d22ca9f8c..3826daf283 100644 --- a/src/quick/util/qquickstate_p.h +++ b/src/quick/util/qquickstate_p.h @@ -69,8 +69,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateAction public: QQuickStateAction(); QQuickStateAction(QObject *, const QString &, const QVariant &); - QQuickStateAction(QObject *, const QString &, - QQmlContext *, const QVariant &); + QQuickStateAction(QObject *, const QQmlProperty &property, const QString &, + const QVariant &); bool restore:1; bool actionDone:1; diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp index 29690a4857..6ae89c4ed4 100644 --- a/src/quick/util/qquicktransition.cpp +++ b/src/quick/util/qquicktransition.cpp @@ -109,7 +109,7 @@ protected: void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override; }; -class QQuickTransitionPrivate : public QObjectPrivate, QAnimationJobChangeListener +class QQuickTransitionPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QQuickTransition) public: @@ -120,11 +120,8 @@ public: { } - void removeStateChangeListener(QAbstractAnimationJob *anim) - { - if (anim) - anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange); - } + static QQuickTransitionPrivate *get(QQuickTransition *q) { return q->d_func(); } + void animationStateChanged(QAbstractAnimationJob::State newState); QString fromState; QString toState; @@ -134,7 +131,6 @@ public: bool reversible; bool enabled; protected: - void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; static void append_animation(QQmlListProperty<QQuickAbstractAnimation> *list, QQuickAbstractAnimation *a); static int animation_count(QQmlListProperty<QQuickAbstractAnimation> *list); @@ -171,7 +167,16 @@ void QQuickTransitionPrivate::clear_animations(QQmlListProperty<QQuickAbstractAn } } -void QQuickTransitionPrivate::animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) +void QQuickTransitionInstance::animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) +{ + if (!m_transition) + return; + + QQuickTransitionPrivate *transition = QQuickTransitionPrivate::get(m_transition); + transition->animationStateChanged(newState); +} + +void QQuickTransitionPrivate::animationStateChanged(QAbstractAnimationJob::State newState) { Q_Q(QQuickTransition); @@ -197,15 +202,16 @@ void ParallelAnimationWrapper::updateState(QAbstractAnimationJob::State newState } } -QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim) +QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransition *transition, QAbstractAnimationJob *anim) : m_transition(transition) , m_anim(anim) { + anim->addAnimationChangeListener(this, QAbstractAnimationJob::StateChange); } QQuickTransitionInstance::~QQuickTransitionInstance() { - m_transition->removeStateChangeListener(m_anim); + removeStateChangeListener(); delete m_anim; } @@ -270,8 +276,7 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action group->setDirection(d->reversed ? QAbstractAnimationJob::Backward : QAbstractAnimationJob::Forward); - group->addAnimationChangeListener(d, QAbstractAnimationJob::StateChange); - QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(d, group); + QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(this, group); return wrapper; } diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h index d6f365f99e..6d2e41fc9d 100644 --- a/src/quick/util/qquicktransition_p.h +++ b/src/quick/util/qquicktransition_p.h @@ -53,6 +53,7 @@ #include "qquickstate_p.h" #include <private/qabstractanimationjob_p.h> +#include <private/qqmlguard_p.h> #include <qqml.h> #include <QtCore/qobject.h> @@ -64,10 +65,10 @@ class QQuickTransitionPrivate; class QQuickTransitionManager; class QQuickTransition; -class QQuickTransitionInstance +class QQuickTransitionInstance : QAnimationJobChangeListener { public: - QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim); + QQuickTransitionInstance(QQuickTransition *transition, QAbstractAnimationJob *anim); ~QQuickTransitionInstance(); void start(); @@ -75,8 +76,16 @@ public: bool isRunning() const; +protected: + void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; + + void removeStateChangeListener() + { + m_anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange); + } + private: - QQuickTransitionPrivate *m_transition; + QQmlGuard<QQuickTransition> m_transition; QAbstractAnimationJob *m_anim; friend class QQuickTransition; }; |