aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-09-22 12:33:21 +0200
committerLiang Qi <liang.qi@qt.io>2017-09-22 12:33:21 +0200
commit35e0b6f9f4b71dc48480c00b9aef8e9ad108b3e5 (patch)
treeabc40b7b370e09db62b3a56480d44f090afe008f /src/quick/items
parent6334ae9fa983d03d0591e11d0be58bbbc4d45270 (diff)
parent112d668c0fded8c6ab7bf40fd3800cf43e005f95 (diff)
Merge remote-tracking branch 'origin/5.10' into dev
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp37
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture_p.h1
-rw-r--r--src/quick/items/qquickanimatedimage.cpp22
-rw-r--r--src/quick/items/qquickanimatedimage_p.h3
-rw-r--r--src/quick/items/qquickanimatedimage_p_p.h1
-rw-r--r--src/quick/items/qquickdrag.cpp1
-rw-r--r--src/quick/items/qquickflickable.cpp2
-rw-r--r--src/quick/items/qquicktextedit.cpp2
-rw-r--r--src/quick/items/qquickwindow.cpp53
-rw-r--r--src/quick/items/qquickwindow_p.h5
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;