diff options
author | Liang Qi <liang.qi@qt.io> | 2017-09-22 12:33:21 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-09-22 12:33:21 +0200 |
commit | 35e0b6f9f4b71dc48480c00b9aef8e9ad108b3e5 (patch) | |
tree | abc40b7b370e09db62b3a56480d44f090afe008f /src/quick/items | |
parent | 6334ae9fa983d03d0591e11d0be58bbbc4d45270 (diff) | |
parent | 112d668c0fded8c6ab7bf40fd3800cf43e005f95 (diff) |
Merge remote-tracking branch 'origin/5.10' into dev
Change-Id: I3878bbf2ac7b62651215938c98ead7171be49c74
Diffstat (limited to 'src/quick/items')
-rw-r--r-- | src/quick/items/context2d/qquickcontext2dtexture.cpp | 37 | ||||
-rw-r--r-- | src/quick/items/context2d/qquickcontext2dtexture_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickanimatedimage.cpp | 22 | ||||
-rw-r--r-- | src/quick/items/qquickanimatedimage_p.h | 3 | ||||
-rw-r--r-- | src/quick/items/qquickanimatedimage_p_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickdrag.cpp | 1 | ||||
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquicktextedit.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 53 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 5 |
10 files changed, 81 insertions, 46 deletions
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index df6dd9dba2..a8bf14ba9f 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -54,6 +54,9 @@ #include <QtGui/QGuiApplication> QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcCanvas, "qt.quick.canvas") + #if QT_CONFIG(opengl) #define QT_MINIMUM_FBO_SIZE 64 @@ -96,6 +99,7 @@ QQuickContext2DTexture::QQuickContext2DTexture() #endif , m_surface(0) , m_item(0) + , m_canvasDevicePixelRatio(1) , m_canvasWindowChanged(false) , m_dirtyTexture(false) , m_smooth(true) @@ -161,12 +165,22 @@ void QQuickContext2DTexture::setItem(QQuickCanvasItem* item) bool QQuickContext2DTexture::setCanvasWindow(const QRect& r) { + qreal canvasDevicePixelRatio = (m_item && m_item->window()) ? + m_item->window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio(); + if (!qFuzzyCompare(m_canvasDevicePixelRatio, canvasDevicePixelRatio)) { + qCDebug(lcCanvas, "%s device pixel ratio %.1lf -> %.1lf", + (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())), + m_canvasDevicePixelRatio, canvasDevicePixelRatio); + m_canvasDevicePixelRatio = canvasDevicePixelRatio; + m_canvasWindowChanged = true; + } + if (m_canvasWindow != r) { m_canvasWindow = r; m_canvasWindowChanged = true; - return true; } - return false; + + return m_canvasWindowChanged; } bool QQuickContext2DTexture::setDirtyRect(const QRect &r) @@ -549,9 +563,6 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting() { QQuickContext2DTexture::beginPainting(); - const qreal devicePixelRatio = (m_item && m_item->window()) ? - m_item->window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio(); - if (m_canvasWindow.size().isEmpty()) { delete m_fbo; delete m_multisampledFbo; @@ -566,7 +577,7 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting() delete m_paint_device; m_paint_device = 0; - m_fboSize = npotAdjustedSize(m_canvasWindow.size() * devicePixelRatio); + m_fboSize = npotAdjustedSize(m_canvasWindow.size() * m_canvasDevicePixelRatio); m_canvasWindowChanged = false; if (doMultisampling()) { @@ -604,7 +615,10 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting() QOpenGLPaintDevice *gl_device = new QOpenGLPaintDevice(m_fbo->size()); gl_device->setPaintFlipped(true); gl_device->setSize(m_fbo->size()); - gl_device->setDevicePixelRatio(devicePixelRatio); + gl_device->setDevicePixelRatio(m_canvasDevicePixelRatio); + qCDebug(lcCanvas, "%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", + (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())), + m_item->width(), m_item->height(), m_fbo->size().width(), m_fbo->size().height(), m_canvasDevicePixelRatio); m_paint_device = gl_device; } @@ -710,14 +724,15 @@ QPaintDevice* QQuickContext2DImageTexture::beginPainting() if (m_canvasWindow.size().isEmpty()) return 0; - const qreal devicePixelRatio = (m_item && m_item->window()) ? - m_item->window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio(); if (m_canvasWindowChanged) { - m_image = QImage(m_canvasWindow.size() * devicePixelRatio, QImage::Format_ARGB32_Premultiplied); - m_image.setDevicePixelRatio(devicePixelRatio); + m_image = QImage(m_canvasWindow.size() * m_canvasDevicePixelRatio, QImage::Format_ARGB32_Premultiplied); + m_image.setDevicePixelRatio(m_canvasDevicePixelRatio); m_image.fill(0x00000000); m_canvasWindowChanged = false; + qCDebug(lcCanvas, "%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", + (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())), + m_item->width(), m_item->height(), m_image.size().width(), m_image.size().height(), m_canvasDevicePixelRatio); } return &m_image; diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h index 97135816a2..81896dcdc1 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture_p.h +++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h @@ -168,6 +168,7 @@ protected: QSize m_canvasSize; QSize m_tileSize; QRect m_canvasWindow; + qreal m_canvasDevicePixelRatio; QMutex m_mutex; QWaitCondition m_condition; diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index a30d71dd1e..5bc5b0faff 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -279,8 +279,7 @@ void QQuickAnimatedImage::setSource(const QUrl &url) d->oldPlaying = isPlaying(); if (d->_movie) { - delete d->_movie; - d->_movie = 0; + d->setMovie(nullptr); } d->url = url; @@ -320,7 +319,7 @@ void QQuickAnimatedImage::load() QString lf = QQmlFile::urlToLocalFileOrQrc(loadUrl); if (!lf.isEmpty()) { - d->_movie = new QMovie(lf); + d->setMovie(new QMovie(lf)); movieRequestFinished(); } else { #if QT_CONFIG(qml_network) @@ -366,14 +365,13 @@ void QQuickAnimatedImage::movieRequestFinished() } d->redirectCount=0; - d->_movie = new QMovie(d->reply); + d->setMovie(new QMovie(d->reply)); } #endif if (!d->_movie || !d->_movie->isValid()) { qmlWarning(this) << "Error Reading Animated Image File " << d->url.toString(); - delete d->_movie; - d->_movie = 0; + d->setMovie(nullptr); d->setImage(QImage()); if (d->progress != 0) { d->progress = 0; @@ -490,6 +488,18 @@ void QQuickAnimatedImage::componentComplete() load(); } +void QQuickAnimatedImagePrivate::setMovie(QMovie *movie) +{ + Q_Q(QQuickAnimatedImage); + const int oldFrameCount = q->frameCount(); + + delete _movie; + _movie = movie; + + if (oldFrameCount != q->frameCount()) + emit q->frameCountChanged(); +} + QT_END_NAMESPACE #include "moc_qquickanimatedimage_p.cpp" diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h index 54da093259..94e44f27cd 100644 --- a/src/quick/items/qquickanimatedimage_p.h +++ b/src/quick/items/qquickanimatedimage_p.h @@ -69,7 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage Q_PROPERTY(bool playing READ isPlaying WRITE setPlaying NOTIFY playingChanged) Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY frameChanged) - Q_PROPERTY(int frameCount READ frameCount) + Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged) // read-only for AnimatedImage Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged) @@ -97,6 +97,7 @@ Q_SIGNALS: void playingChanged(); void pausedChanged(); void frameChanged(); + void frameCountChanged(); private Q_SLOTS: void movieUpdate(); diff --git a/src/quick/items/qquickanimatedimage_p_p.h b/src/quick/items/qquickanimatedimage_p_p.h index 9eff6a44e3..68c4f2d359 100644 --- a/src/quick/items/qquickanimatedimage_p_p.h +++ b/src/quick/items/qquickanimatedimage_p_p.h @@ -91,6 +91,7 @@ public: #endif QMap<int, QQuickPixmap *> frameMap; QSize currentSourceSize; + void setMovie(QMovie *movie); }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp index 41847e5f01..7c936ff21c 100644 --- a/src/quick/items/qquickdrag.cpp +++ b/src/quick/items/qquickdrag.cpp @@ -772,6 +772,7 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct drag->setPixmap(QPixmap::fromImage(pixmapLoader.image())); } + drag->setHotSpot(hotSpot.toPoint()); emit q->dragStarted(); Qt::DropAction dropAction = drag->exec(supportedActions); diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index ce584cd283..ee5f177855 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -56,6 +56,7 @@ #include <QtCore/qmath.h> #include "qplatformdefs.h" +#include <math.h> #include <cmath> QT_BEGIN_NAMESPACE @@ -1771,6 +1772,7 @@ void QQuickFlickable::flick(qreal xVelocity, qreal yVelocity) d->vData.reset(); d->hData.velocity = xVelocity; d->vData.velocity = yVelocity; + d->hData.vTime = d->vData.vTime = d->timeline.time(); bool flickedX = d->flickX(xVelocity); bool flickedY = d->flickY(yVelocity); diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index da11913bde..8f3a8998f5 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -2511,7 +2511,7 @@ void QQuickTextEdit::updateSize() if (d->isImplicitResizeEnabled()) { // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed. - if (!widthValid() && !d->requireImplicitWidth) + if (!widthValid()) setImplicitSize(newWidth + leftPadding() + rightPadding(), newHeight + topPadding() + bottomPadding()); else setImplicitHeight(newHeight + topPadding() + bottomPadding()); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 21f06febde..bd1a5076fd 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -780,8 +780,8 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber) if (oldGrabber) { QEvent e(QEvent::UngrabMouse); - QSet<QQuickItem *> hasFiltered; - if (!sendFilteredMouseEvent(oldGrabber->parentItem(), oldGrabber, &e, &hasFiltered)) + hasFiltered.clear(); + if (!sendFilteredMouseEvent(&e, oldGrabber, oldGrabber->parentItem())) oldGrabber->mouseUngrabEvent(); } } @@ -1757,10 +1757,9 @@ bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item, hoverEvent.setTimestamp(timestamp); hoverEvent.setAccepted(accepted); - QSet<QQuickItem *> hasFiltered; - if (sendFilteredMouseEvent(item->parentItem(), item, &hoverEvent, &hasFiltered)) { + hasFiltered.clear(); + if (sendFilteredMouseEvent(&hoverEvent, item, item->parentItem())) return true; - } QCoreApplication::sendEvent(item, &hoverEvent); @@ -2233,6 +2232,7 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) // the usecase a bit evil, but we at least don't want to lose events. ++pointerEventRecursionGuard; + skipDelivery.clear(); if (event->asPointerMouseEvent()) { deliverMouseEvent(event->asPointerMouseEvent()); } else if (event->asPointerTouchEvent()) { @@ -2427,7 +2427,6 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event, } } - QVarLengthArray<QQuickItem *> filteredItems; for (QQuickItem *item : targetItems) { if (!handlersOnly && sendFilteredPointerEvent(event, item)) { if (event->isAccepted()) { @@ -2435,15 +2434,12 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event, event->point(i)->setAccepted(); return true; } - filteredItems << item; + skipDelivery.append(item); } - // Do not deliverMatchingPointsTo any item for which the parent-filter already intercepted the event - if (filteredItems.contains(item)) - continue; - // Do not deliverMatchingPointsTo any item which already had a chance to filter - // e.g. if Flickable has filtered events from one of its children, it does not need normal delivery - if (hasFiltered.contains(item)) + // Do not deliverMatchingPointsTo any item for which the filtering parent already intercepted the event, + // nor to any item which already had a chance to filter. + if (skipDelivery.contains(item)) continue; deliverMatchingPointsToItem(item, event, handlersOnly); if (event->allPointsAccepted()) @@ -2744,8 +2740,11 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event if (receiver->acceptedMouseButtons()) { QPointF localPos = receiver->mapFromScene(pme->point(0)->scenePosition()); QMouseEvent *me = pme->asMouseEvent(localPos); - if (filteringParent->childMouseEventFilter(receiver, me)) + if (filteringParent->childMouseEventFilter(receiver, me)) { + qCDebug(DBG_MOUSE) << "mouse event intercepted by childMouseEventFilter of " << filteringParent; + skipDelivery.append(filteringParent); filtered = true; + } } } else if (QQuickPointerTouchEvent *pte = event->asPointerTouchEvent()) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -2761,6 +2760,7 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event QVarLengthArray<QPair<QQuickPointerHandler *, QQuickEventPoint *>, 32> passiveGrabsToCancel; if (filteringParent->childMouseEventFilter(receiver, filteringParentTouchEvent.data())) { qCDebug(DBG_TOUCH) << "touch event intercepted by childMouseEventFilter of " << filteringParent; + skipDelivery.append(filteringParent); filteringParent->grabMouse(); for (auto point: qAsConst(filteringParentTouchEvent->touchPoints())) { auto pointerEventPoint = pte->pointById(point.id()); @@ -2805,6 +2805,7 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event touchMouseDevice = event->device(); if (filteringParent->childMouseEventFilter(receiver, mouseEvent.data())) { qCDebug(DBG_TOUCH) << "touch event intercepted as synth mouse event by childMouseEventFilter of " << filteringParent; + skipDelivery.append(filteringParent); if (t != QEvent::MouseButtonRelease) { qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << tp.id() << "->" << filteringParent; pointerEventInstance(touchMouseDevice)->pointById(tp.id())->setGrabberItem(filteringParent); @@ -2840,24 +2841,26 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event return sendFilteredPointerEventImpl(event, receiver, filteringParent->parentItem()) || filtered; } -bool QQuickWindowPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem *item, QEvent *event, QSet<QQuickItem *> *hasFiltered) +bool QQuickWindowPrivate::sendFilteredMouseEvent(QEvent *event, QQuickItem *receiver, QQuickItem *filteringParent) { - if (!target) + if (!filteringParent) return false; - QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(target); - if (targetPrivate->replayingPressEvent) + QQuickItemPrivate *filteringParentPrivate = QQuickItemPrivate::get(filteringParent); + if (filteringParentPrivate->replayingPressEvent) return false; bool filtered = false; - if (targetPrivate->filtersChildMouseEvents && !hasFiltered->contains(target)) { - hasFiltered->insert(target); - if (target->childMouseEventFilter(item, event)) + if (filteringParentPrivate->filtersChildMouseEvents && !hasFiltered.contains(filteringParent)) { + hasFiltered.append(filteringParent); + if (filteringParent->childMouseEventFilter(receiver, event)) { filtered = true; - qCDebug(DBG_MOUSE_TARGET) << "for" << item << target << "childMouseEventFilter ->" << filtered; + skipDelivery.append(filteringParent); + } + qCDebug(DBG_MOUSE_TARGET) << "for" << receiver << filteringParent << "childMouseEventFilter ->" << filtered; } - return sendFilteredMouseEvent(target->parentItem(), item, event, hasFiltered) || filtered; + return sendFilteredMouseEvent(event, receiver, filteringParent->parentItem()) || filtered; } bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold) @@ -3007,8 +3010,8 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e) case QEvent::MouseButtonDblClick: case QEvent::MouseMove: { // XXX todo - should sendEvent be doing this? how does it relate to forwarded events? - QSet<QQuickItem *> hasFiltered; - if (!d->sendFilteredMouseEvent(item->parentItem(), item, e, &hasFiltered)) { + d->hasFiltered.clear(); + if (!d->sendFilteredMouseEvent(e, item, item->parentItem())) { // accept because qml items by default accept and have to explicitly opt out of accepting e->accept(); QCoreApplication::sendEvent(item, e); diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 2a2507904b..0399b26f62 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -147,7 +147,7 @@ public: void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true); static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0); void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent); - bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QEvent *, QSet<QQuickItem *> *); + bool sendFilteredMouseEvent(QEvent *event, QQuickItem *receiver, QQuickItem *filteringParent); bool sendFilteredPointerEvent(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent = nullptr); bool sendFilteredPointerEventImpl(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent); #if QT_CONFIG(wheelevent) @@ -227,7 +227,8 @@ public: QList<QSGNode *> cleanupNodeList; QVector<QQuickItem *> itemsToPolish; - QVector<QQuickItem *> hasFiltered; // during event delivery, the items for which childMouseEventFilter was already called + QVector<QQuickItem *> hasFiltered; // during event delivery to a single receiver, the filtering parents for which childMouseEventFilter was already called + QVector<QQuickItem *> skipDelivery; // during delivery of one event to all receivers, Items to which we know delivery is no longer necessary qreal devicePixelRatio; QMetaObject::Connection physicalDpiChangedConnection; |