diff options
-rw-r--r-- | src/quick/items/qquickevents.cpp | 44 | ||||
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 15 | ||||
-rw-r--r-- | src/quick/items/qquickmultipointtoucharea.cpp | 36 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 82 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 6 | ||||
-rw-r--r-- | tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp | 13 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem/tst_qquickitem.cpp | 32 | ||||
-rw-r--r-- | tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp | 5 | ||||
-rw-r--r-- | tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp | 13 | ||||
-rw-r--r-- | tests/auto/quick/qquickwindow/tst_qquickwindow.cpp | 82 |
10 files changed, 150 insertions, 178 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 57693e169e..0f7e613371 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -1245,8 +1245,7 @@ QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event) default: break; } - // for now, reuse the device ID as the point ID; TODO use ev->point(0).id when it becomes possible - m_point->reset(state, ev->scenePosition(), int(ev->device()->systemId()), ev->timestamp()); + m_point->reset(state, ev->scenePosition(), ev->point(0).id(), ev->timestamp()); return this; } @@ -1356,8 +1355,7 @@ QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event) default: break; } - quint64 deviceId = ev->device()->systemId(); - m_point->reset(state, ev->scenePosition(), deviceId << 24, ev->timestamp()); + m_point->reset(state, ev->scenePosition(), ev->point(0).id(), ev->timestamp()); return this; } #endif // QT_CONFIG(gestures) @@ -1520,8 +1518,7 @@ QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event) m_phase = ev->phase(); m_synthSource = ev->source(); m_inverted = ev->inverted(); - - m_point->reset(QEventPoint::State::Updated, ev->position(), quint64(1) << 24, ev->timestamp()); // mouse has device ID 1 + m_point->reset(QEventPoint::State::Updated, ev->position(), ev->point(0).id(), ev->timestamp()); } #endif // TODO else if (event->type() == QEvent::Scroll) ... @@ -1571,9 +1568,8 @@ QMouseEvent *QQuickPointerMouseEvent::asMouseEvent(const QPointF &localPos) cons { if (!m_event) return nullptr; - auto event = static_cast<QMouseEvent *>(m_event); - event->setLocalPos(localPos); - return event; + static_cast<QMutableSinglePointEvent *>(m_event)->mutablePoint().setPosition(localPos); + return static_cast<QMouseEvent *>(m_event); } /*! @@ -1767,15 +1763,16 @@ QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickIte return nullptr; } m_synthMouseEvent = QMouseEvent(type, relativeTo->mapFromScene(p->scenePosition()), - p->scenePosition(), p->globalPosition(), Qt::LeftButton, buttons, m_event->modifiers()); + p->scenePosition(), p->globalPosition(), Qt::LeftButton, buttons, m_event->modifiers(), + Qt::MouseEventSynthesizedByQt, device()); m_synthMouseEvent.setAccepted(true); m_synthMouseEvent.setTimestamp(m_event->timestamp()); // ### Qt 6: try to always have valid velocity in every QEventPoint (either from the platform, or synthesized in QtGui). // QQuickFlickablePrivate::handleMouseMoveEvent() checks for QInputDevice::Capability::Velocity - // and if it is set, then it does not need to do its own velocity calculations. So we keep faking it this way for now. - if (device()) - QGuiApplicationPrivate::setMouseEventCapsAndVelocity(&m_synthMouseEvent, device()->capabilities(), p->velocity()); - QGuiApplicationPrivate::setMouseEventSource(&m_synthMouseEvent, Qt::MouseEventSynthesizedByQt); + // and if it is set, then it does not need to do its own velocity calculations. + // But because m_synthMouseEvent gets the same device() where the (usually) touch event came from, + // the capability won't be set, in practice, until we have the velocity in place. + QMutableSinglePointEvent::from(m_synthMouseEvent).mutablePoint().setVelocity(p->velocity()); return &m_synthMouseEvent; } @@ -1975,7 +1972,7 @@ const QEventPoint *QQuickPointerTouchEvent::touchPointById(int pointId) const QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool isFiltering) const { QList<QEventPoint> touchPoints; - QEventPoint::States eventStates; + QEventPoint::States eventStates; // TODO maybe avoid accumulating this, since the touchevent ctor doesn't need it // TODO maybe add QQuickItem::mapVector2DFromScene(QVector2D) to avoid needing QQuickItemPrivate here // Or else just document that velocity is always scene-relative and is not scaled and rotated with the item // but that would require changing tst_qquickwindow::touchEvent_velocity(): it expects transformed velocity @@ -2012,16 +2009,14 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i continue; if ((p->state() == QQuickEventPoint::Pressed || p->state() == QQuickEventPoint::Released) && isInside) anyPressOrReleaseInside = true; - const QEventPoint *tp = touchPointById(p->pointId()); + // we don't use QMutableEventPoint::from() because it's fine to have const here + const QMutableEventPoint *tp = static_cast<const QMutableEventPoint *>(touchPointById(p->pointId())); if (tp) { - if (isInside && tp->d->stationaryWithModifiedProperty) + if (isInside && tp->stationaryWithModifiedProperty()) anyStationaryWithModifiedPropertyInside = true; eventStates |= tp->state(); - QEventPoint tpCopy = *tp; - tpCopy.setPos(item->mapFromScene(tpCopy.scenePosition())); - tpCopy.setLastPos(item->mapFromScene(tpCopy.lastScenePos())); - tpCopy.setStartPos(item->mapFromScene(tpCopy.scenePressPosition())); - tpCopy.setEllipseDiameters(tpCopy.ellipseDiameters()); + QMutableEventPoint tpCopy(*tp); + tpCopy.setPosition(item->mapFromScene(tp->scenePosition())); tpCopy.setVelocity(transformMatrix.mapVector(tpCopy.velocity()).toVector2D()); touchPoints << tpCopy; } @@ -2048,9 +2043,8 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i break; } - QTouchEvent *touchEvent = new QTouchEvent(eventType, event.pointingDevice(), - event.modifiers(), eventStates, touchPoints); - touchEvent->setWindow(event.window()); + QMutableTouchEvent *touchEvent = new QMutableTouchEvent(eventType, event.pointingDevice(), + event.modifiers(), touchPoints); touchEvent->setTarget(item); touchEvent->setTimestamp(event.timestamp()); touchEvent->accept(); diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index bd7242e99f..d20f23466b 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -1320,10 +1320,9 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event) qint64 currentTimestamp = computeCurrentTime(event); QVector2D deltas = QVector2D(event->position() - pressPos); bool overThreshold = false; - QVector2D velocity = QGuiApplicationPrivate::mouseEventVelocity(event); + QVector2D velocity = event->point(0).velocity(); // TODO guarantee that events always have velocity so that it never needs to be computed here - // TODO use event->device->caps() - if (!(QGuiApplicationPrivate::mouseEventCaps(event) & int(QInputDevice::Capability::Velocity))) { + if (!event->device()->capabilities().testFlag(QInputDevice::Capability::Velocity)) { qint64 lastTimestamp = (lastPos.isNull() ? lastPressTime : lastPosTime); if (currentTimestamp == lastTimestamp) return; // events are too close together: velocity would be infinite @@ -1363,8 +1362,8 @@ void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event) qreal vVelocity = 0; if (elapsed < 100 && vData.velocity != 0.) { - vVelocity = (QGuiApplicationPrivate::mouseEventCaps(event) & int(QInputDevice::Capability::Velocity)) - ? QGuiApplicationPrivate::mouseEventVelocity(event).y() : vData.velocity; + vVelocity = (event->device()->capabilities().testFlag(QInputDevice::Capability::Velocity) + ? event->point(0).velocity().y() : vData.velocity); } if ((vData.atBeginning && vVelocity > 0.) || (vData.atEnd && vVelocity < 0.)) { vVelocity /= 2; @@ -1378,8 +1377,8 @@ void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event) qreal hVelocity = 0; if (elapsed < 100 && hData.velocity != 0.) { - hVelocity = (QGuiApplicationPrivate::mouseEventCaps(event) & int(QInputDevice::Capability::Velocity)) - ? QGuiApplicationPrivate::mouseEventVelocity(event).x() : hData.velocity; + hVelocity = (event->device()->capabilities().testFlag(QInputDevice::Capability::Velocity) + ? event->point(0).velocity().x() : hData.velocity); } if ((hData.atBeginning && hVelocity > 0.) || (hData.atEnd && hVelocity < 0.)) { hVelocity /= 2; diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index e230b1285d..cebfe74df0 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -44,6 +44,7 @@ #include <private/qquickitem_p.h> #include <private/qquickwindow_p.h> #include <private/qguiapplication_p.h> +#include <QtGui/private/qevent_p.h> #include <QEvent> #include <QMouseEvent> #include <QDebug> @@ -592,20 +593,10 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) case QEvent::MouseMove: case QEvent::MouseButtonRelease: { QMouseEvent *me = static_cast<QMouseEvent*>(event); - _mouseQpaTouchPoint.setPos(me->position()); - _mouseQpaTouchPoint.setScenePos(me->scenePosition()); - _mouseQpaTouchPoint.setScreenPos(me->globalPosition()); - if (event->type() == QEvent::MouseMove) - _mouseQpaTouchPoint.setState(QEventPoint::State::Updated); - else if (event->type() == QEvent::MouseButtonRelease) - _mouseQpaTouchPoint.setState(QEventPoint::State::Released); - else { // QEvent::MouseButtonPress + _mouseQpaTouchPoint = me->point(0); + if (event->type() == QEvent::MouseButtonPress) { addTouchPoint(me); started = true; - _mouseQpaTouchPoint.setStartPos(me->position()); - _mouseQpaTouchPoint.setStartScenePos(me->scenePosition()); - _mouseQpaTouchPoint.setStartScreenPos(me->globalPosition()); - _mouseQpaTouchPoint.setState(QEventPoint::State::Pressed); } touchPoints << _mouseQpaTouchPoint; break; @@ -641,7 +632,8 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) // (we may have just obtained enough points to start tracking them -- in that case moved or stationary count as newly pressed) addTouchPoint(&p); started = true; - } else if ((touchPointState & QEventPoint::State::Updated) || p.d->stationaryWithModifiedProperty) { + } else if ((touchPointState & QEventPoint::State::Updated) || + QMutableEventPoint::from(const_cast<QEventPoint &>(p)).stationaryWithModifiedProperty()) { // React to a stationary point with a property change (velocity, pressure) as if the point moved. (QTBUG-77142) QQuickTouchPoint* dtp = static_cast<QQuickTouchPoint*>(_touchPoints.value(id)); Q_ASSERT(dtp); @@ -741,7 +733,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e) dtp = new QQuickTouchPoint(false); updateTouchPoint(dtp, e); dtp->setPressed(true); - _touchPoints.insert(_touchMouseDevice && _mouseQpaTouchPoint.id() > 0 ? _mouseQpaTouchPoint.id() : -1, dtp); + _touchPoints.insert(_mouseQpaTouchPoint.id(), dtp); _pressedTouchPoints.append(dtp); _mouseTouchPoint = dtp; } @@ -794,8 +786,8 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QE dtp->setArea(area); dtp->setStartX(p->pressPosition().x()); dtp->setStartY(p->pressPosition().y()); - dtp->setPreviousX(p->lastPos().x()); - dtp->setPreviousY(p->lastPos().y()); + dtp->setPreviousX(p->lastPosition().x()); + dtp->setPreviousY(p->lastPosition().y()); dtp->setSceneX(p->scenePosition().x()); dtp->setSceneY(p->scenePosition().y()); } @@ -911,13 +903,11 @@ bool QQuickMultiPointTouchArea::sendMouseEvent(QMouseEvent *event) QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr; bool stealThisEvent = _stealMouse; if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab())) { - QMouseEvent mouseEvent(event->type(), localPos, event->scenePosition(), event->globalPosition(), - event->button(), event->buttons(), event->modifiers()); + QMouseEvent mouseEvent = *event; + auto mut = QMutableSinglePointEvent::from(&mouseEvent); + mut->mutablePoint().setPosition(localPos); + mut->setSource(Qt::MouseEventSynthesizedByQt); mouseEvent.setAccepted(false); - QGuiApplicationPrivate::setMouseEventCapsAndVelocity(&mouseEvent, - QGuiApplicationPrivate::mouseEventCaps(event), - QGuiApplicationPrivate::mouseEventVelocity(event)); - QGuiApplicationPrivate::setMouseEventSource(&mouseEvent, Qt::MouseEventSynthesizedByQt); switch (mouseEvent.type()) { case QEvent::MouseMove: diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 9c9b99bca5..76c5a3ecf0 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -68,6 +68,7 @@ #include <QtGui/qpainter.h> #include <QtGui/qevent.h> #include <QtGui/qmatrix4x4.h> +#include <QtGui/private/qevent_p.h> #include <QtGui/private/qpointingdevice_p.h> #include <QtGui/qpa/qplatformtheme.h> #include <QtCore/qvarlengtharray.h> @@ -854,12 +855,13 @@ QQmlListProperty<QObject> QQuickWindowPrivate::data() QQuickWindowPrivate::data_removeLast); } -static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QEventPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true) +QMouseEvent *QQuickWindowPrivate::touchToMouseEvent(QEvent::Type type, const QEventPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded) { Q_ASSERT(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)); // The touch point local position and velocity are not yet transformed. QMouseEvent *me = new QMouseEvent(type, transformNeeded ? item->mapFromScene(p.scenePosition()) : p.position(), p.scenePosition(), p.globalPosition(), - Qt::LeftButton, (type == QEvent::MouseButtonRelease ? Qt::NoButton : Qt::LeftButton), event->modifiers()); + Qt::LeftButton, (type == QEvent::MouseButtonRelease ? Qt::NoButton : Qt::LeftButton), event->modifiers(), + Qt::MouseEventSynthesizedByQt, event->pointingDevice()); me->setAccepted(true); me->setTimestamp(event->timestamp()); QVector2D transformedVelocity = p.velocity(); @@ -868,8 +870,7 @@ static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QEventPoint &p, Q QMatrix4x4 transformMatrix(itemPrivate->windowToItemTransform()); transformedVelocity = transformMatrix.mapVector(p.velocity()).toVector2D(); } - QGuiApplicationPrivate::setMouseEventCapsAndVelocity(me, event->pointingDevice()->capabilities(), transformedVelocity); - QGuiApplicationPrivate::setMouseEventSource(me, Qt::MouseEventSynthesizedByQt); + QMutableSinglePointEvent::from(me)->mutablePoint().setVelocity(transformedVelocity); return me; } @@ -1130,20 +1131,20 @@ void QQuickWindowPrivate::sendUngrabEvent(QQuickItem *grabber, bool touch) } } -/*! -Translates the data in \a touchEvent to this window. This method leaves the item local positions in -\a touchEvent untouched (these are filled in later). +/*! \internal + Translates QEventPoint::scenePosition() in \a touchEvent to this window, + and modifies QEventPoint::id() to be globally unique. + + The item-local QEventPoint::position() is updated later, not here. */ void QQuickWindowPrivate::translateTouchEvent(QTouchEvent *touchEvent) { - QList<QEventPoint> touchPoints = touchEvent->touchPoints(); - for (int i = 0; i < touchPoints.count(); ++i) { - QEventPoint &touchPoint = touchPoints[i]; - touchPoint.setScenePos(touchPoint.position()); - touchPoint.setStartScenePos(touchPoint.pressPosition()); - touchPoint.setLastScenePos(touchPoint.lastPos()); + const int deviceMask = QInputDevice::devices().indexOf(touchEvent->device()) << 24; + for (QEventPoint &touchPoint : QMutableTouchEvent::from(touchEvent)->touchPoints()) { + QMutableEventPoint &mut = QMutableEventPoint::from(touchPoint); + mut.setScenePosition(touchPoint.position()); + mut.setId(deviceMask + touchPoint.id()); } - touchEvent->setTouchPoints(touchPoints); } @@ -2095,17 +2096,15 @@ void QQuickWindowPrivate::deliverKeyEvent(QKeyEvent *e) } } +// TODO can we return by value to avoid heap allocation? +// QQuickFlickablePrivate::delayedPressEvent is a ptr so that it can be null; +// but QMouseEvent::isValid() would be an alternative if we can write it QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos) { - int caps = QGuiApplicationPrivate::mouseEventCaps(event); - QVector2D velocity = QGuiApplicationPrivate::mouseEventVelocity(event); - QMouseEvent *me = new QMouseEvent(event->type(), - transformedLocalPos ? *transformedLocalPos : event->position(), - event->scenePosition(), event->globalPosition(), - event->button(), event->buttons(), event->modifiers()); - QGuiApplicationPrivate::setMouseEventCapsAndVelocity(me, caps, velocity); - QGuiApplicationPrivate::setMouseEventSource(me, QGuiApplicationPrivate::mouseEventSource(event)); - me->setTimestamp(event->timestamp()); + QMouseEvent *me = new QMouseEvent(*event); + QMutableEventPoint &point = QMutableSinglePointEvent::from(me)->mutablePoint(); + point.setTimestamp(event->timestamp()); + point.setPosition(transformedLocalPos ? *transformedLocalPos : event->position()); return me; } @@ -2409,6 +2408,8 @@ void QQuickWindow::tabletEvent(QTabletEvent *event) { Q_D(QQuickWindow); qCDebug(lcTablet) << event; + const int deviceIndex = QInputDevice::devices().indexOf(event->device()); + QMutableSinglePointEvent::from(event)->mutablePoint().setId((deviceIndex << 24) + event->point(0).id()); // TODO Qt 6: make sure TabletEnterProximity and TabletLeaveProximity are delivered here d->deliverPointerEvent(d->pointerEventInstance(event)); } @@ -2447,14 +2448,13 @@ bool QQuickWindowPrivate::compressTouchEvent(QTouchEvent *event) { Q_Q(QQuickWindow); QEventPoint::States states = event->touchPointStates(); - if (((states & (QEventPoint::State::Updated | QEventPoint::State::Stationary)) == 0) - || ((states & (QEventPoint::State::Pressed | QEventPoint::State::Released)) != 0)) { + if (states.testFlag(QEventPoint::State::Pressed) || states.testFlag(QEventPoint::State::Released)) { // we can only compress something that isn't a press or release return false; } if (!delayedTouch) { - delayedTouch.reset(new QTouchEvent(event->type(), event->pointingDevice(), event->modifiers(), event->touchPointStates(), event->touchPoints())); + delayedTouch.reset(new QMutableTouchEvent(event->type(), event->pointingDevice(), event->modifiers(), event->touchPoints())); delayedTouch->setTimestamp(event->timestamp()); if (renderControl) QQuickRenderControlPrivate::get(renderControl)->maybeUpdate(); @@ -2473,7 +2473,6 @@ bool QQuickWindowPrivate::compressTouchEvent(QTouchEvent *event) bool mismatch = false; QList<QEventPoint> tpts = event->touchPoints(); - QEventPoint::States states; for (int i = 0; i < event->touchPoints().count(); ++i) { const QEventPoint &tp = tpts.at(i); const QEventPoint &tpDelayed = delayedTouch->touchPoints().at(i); @@ -2483,18 +2482,14 @@ bool QQuickWindowPrivate::compressTouchEvent(QTouchEvent *event) } if (tpDelayed.state() == QEventPoint::State::Updated && tp.state() == QEventPoint::State::Stationary) - tpts[i].setState(QEventPoint::State::Updated); - tpts[i].setLastPos(tpDelayed.lastPos()); - tpts[i].setLastScenePos(tpDelayed.lastScenePos()); - tpts[i].setLastScreenPos(tpDelayed.lastScreenPos()); - tpts[i].setLastNormalizedPos(tpDelayed.lastNormalizedPos()); - - states |= tpts.at(i).state(); + QMutableEventPoint::from(tpts[i]).setState(QEventPoint::State::Updated); } - // matching touch event? then merge the new event into the old one + // matching touch event? then give delayedTouch a merged set of touchpoints if (!mismatch) { - delayedTouch->setTouchPoints(tpts); + // have to create a new event because QMutableTouchEvent::setTouchPoints() is missing + // TODO optimize, or move event compression elsewhere + delayedTouch.reset(new QMutableTouchEvent(event->type(), event->pointingDevice(), event->modifiers(), tpts)); delayedTouch->setTimestamp(event->timestamp()); return true; } @@ -2502,8 +2497,8 @@ bool QQuickWindowPrivate::compressTouchEvent(QTouchEvent *event) // merging wasn't possible, so deliver the delayed event first, and then delay this one deliverDelayedTouchEvent(); - delayedTouch.reset(new QTouchEvent(event->type(), event->pointingDevice(), - event->modifiers(), event->touchPointStates(), event->touchPoints())); + delayedTouch.reset(new QMutableTouchEvent(event->type(), event->pointingDevice(), + event->modifiers(), event->touchPoints())); delayedTouch->setTimestamp(event->timestamp()); return true; } @@ -2572,6 +2567,8 @@ void QQuickWindowPrivate::handleMouseEvent(QMouseEvent *event) return; } qCDebug(DBG_MOUSE) << "QQuickWindow::handleMouseEvent()" << event->type() << event->position() << event->button() << event->buttons(); + const int deviceIndex = QInputDevice::devices().indexOf(event->device()); + QMutableSinglePointEvent::from(event)->mutablePoint().setId((deviceIndex << 24) + event->point(0).id()); switch (event->type()) { case QEvent::MouseButtonPress: @@ -3321,7 +3318,7 @@ QPair<QQuickItem*, QQuickPointerHandler*> QQuickWindowPrivate::findCursorItemAnd if (itemPrivate->hasCursorHandler) { if (auto handler = itemPrivate->effectiveCursorHandler()) { QQuickPointerEvent *pointerEvent = pointerEventInstance(QPointingDevice::primaryPointingDevice(), QEvent::MouseMove); - pointerEvent->point(0)->reset(QEventPoint::State::Updated, scenePos, quint64(1) << 24 /* mouse has device ID 1 */, 0); + pointerEvent->point(0)->reset(QEventPoint::State::Updated, scenePos, 0, 0); pointerEvent->point(0)->setAccepted(true); pointerEvent->localize(item); if (handler->parentContains(pointerEvent->point(0))) @@ -3488,12 +3485,11 @@ bool QQuickWindowPrivate::sendFilteredMouseEvent(QEvent *event, QQuickItem *rece bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold) { QStyleHints *styleHints = QGuiApplication::styleHints(); - int caps = QGuiApplicationPrivate::mouseEventCaps(event); - bool dragVelocityLimitAvailable = (caps & int(QInputDevice::Capability::Velocity)) + bool dragVelocityLimitAvailable = event->device()->capabilities().testFlag(QInputDevice::Capability::Velocity) && styleHints->startDragVelocity(); bool overThreshold = qAbs(d) > (startDragThreshold >= 0 ? startDragThreshold : styleHints->startDragDistance()); if (dragVelocityLimitAvailable) { - QVector2D velocityVec = QGuiApplicationPrivate::mouseEventVelocity(event); + QVector2D velocityVec = event->point(0).velocity(); qreal velocity = axis == Qt::XAxis ? velocityVec.x() : velocityVec.y(); overThreshold |= qAbs(velocity) > styleHints->startDragVelocity(); } diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index e79f2634e1..09851c5fa5 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -65,6 +65,7 @@ #include <QtCore/qwaitcondition.h> #include <QtCore/qrunnable.h> +#include <QtGui/private/qevent_p.h> #include <QtGui/private/qwindow_p.h> #include <QtGui/qevent.h> #include <QtGui/qstylehints.h> @@ -185,6 +186,7 @@ public: QQuickPointerEvent *pointerEventInstance(const QPointingDevice *device, QEvent::Type eventType = QEvent::None) const; // delivery of pointer events: + QMouseEvent *touchToMouseEvent(QEvent::Type type, const QEventPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true); QQuickPointerEvent *pointerEventInstance(QEvent *ev) const; void deliverPointerEvent(QQuickPointerEvent *); void deliverTouchEvent(QQuickPointerTouchEvent *); @@ -269,7 +271,7 @@ public: QSGRenderLoop *windowManager; QQuickRenderControl *renderControl; QScopedPointer<QQuickAnimatorController> animationController; - QScopedPointer<QTouchEvent> delayedTouch; + QScopedPointer<QMutableTouchEvent> delayedTouch; int pointerEventRecursionGuard; diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp index 89e9fa3f23..cd24d8643e 100644 --- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp @@ -29,8 +29,9 @@ #include <QtTest/QtTest> #include <QtTest/QSignalSpy> #include <QtGui/QStyleHints> +#include <QtGui/private/qevent_p.h> #include <qpa/qwindowsysteminterface.h> -#include <private/qquickpinchhandler_p.h> +#include <QtQuick/private/qquickpinchhandler_p.h> #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/qquickview.h> #include <QtQml/qqmlcontext.h> @@ -186,12 +187,12 @@ void tst_QQuickPinchHandler::pinchProperties() QCOMPARE(rotMaxSpy.count(),1); } -QEventPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i) +QMutableEventPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i) { - QEventPoint touchPoint(id); - touchPoint.setPos(i->mapFromScene(p)); - touchPoint.setScreenPos(v->mapToGlobal(p)); - touchPoint.setScenePos(p); + QMutableEventPoint touchPoint(id); + touchPoint.setPosition(i->mapFromScene(p)); + touchPoint.setGlobalPosition(v->mapToGlobal(p)); + touchPoint.setScenePosition(p); return touchPoint; } diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index 0e7ab12074..f8986ce66b 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -33,6 +33,7 @@ #include <QtQuick/qquickview.h> #include "private/qquickfocusscope_p.h" #include "private/qquickitem_p.h" +#include <QtGui/private/qevent_p.h> #include <qpa/qwindowsysteminterface.h> #ifdef Q_OS_WIN #include <QOpenGLContext> @@ -1341,15 +1342,12 @@ void tst_qquickitem::touchEventAcceptIgnore() // Send Begin, Update & End touch sequence { - QEventPoint point; - point.setId(1); - point.setPos(QPointF(50, 50)); - point.setScreenPos(point.position()); - point.setState(QEventPoint::State::Pressed); + QMutableEventPoint point(1, QEventPoint::State::Pressed); + point.setPosition(QPointF(50, 50)); + point.setGlobalPosition(point.position()); QTouchEvent event(QEvent::TouchBegin, device, Qt::NoModifier, - QEventPoint::State::Pressed, QList<QEventPoint>() << point); event.setAccepted(true); @@ -1365,15 +1363,12 @@ void tst_qquickitem::touchEventAcceptIgnore() QCOMPARE(accepted && event.isAccepted(), true); } { - QEventPoint point; - point.setId(1); - point.setPos(QPointF(60, 60)); - point.setScreenPos(point.position()); - point.setState(QEventPoint::State::Updated); + QMutableEventPoint point(1, QEventPoint::State::Updated); + point.setPosition(QPointF(60, 60)); + point.setGlobalPosition(point.position()); QTouchEvent event(QEvent::TouchUpdate, device, Qt::NoModifier, - QEventPoint::State::Updated, QList<QEventPoint>() << point); event.setAccepted(true); @@ -1389,15 +1384,12 @@ void tst_qquickitem::touchEventAcceptIgnore() QCOMPARE(accepted && event.isAccepted(), true); } { - QEventPoint point; - point.setId(1); - point.setPos(QPointF(60, 60)); - point.setScreenPos(point.position()); - point.setState(QEventPoint::State::Released); + QMutableEventPoint point(1, QEventPoint::State::Released); + point.setPosition(QPointF(60, 60)); + point.setGlobalPosition(point.position()); QTouchEvent event(QEvent::TouchEnd, device, Qt::NoModifier, - QEventPoint::State::Released, QList<QEventPoint>() << point); event.setAccepted(true); @@ -1620,7 +1612,7 @@ void tst_qquickitem::hoverEvent_data() // ### For some unknown reason QTest::mouseMove() isn't working correctly. static void sendMouseMove(QObject *object, const QPoint &position) { - QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, nullptr); + QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, Qt::NoModifier); QGuiApplication::sendEvent(object, &moveEvent); } diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index 0806914763..47f7943d12 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -35,6 +35,7 @@ #include <qpa/qwindowsysteminterface.h> #include <QtQuick/qquickview.h> #include <QtGui/QScreen> +#include <QtGui/private/qevent_p.h> #include "../../shared/util.h" #include "../shared/viewtestutil.h" @@ -1373,9 +1374,9 @@ void tst_QQuickMultiPointTouchArea::stationaryTouchWithChangingPressure() // QTB QCOMPARE(point1->pressed(), false); QPoint p1(20,100); - QEventPoint tp1(1); + QMutableEventPoint tp1(1); - tp1.setScreenPos(window->mapToGlobal(p1)); + tp1.setGlobalPosition(window->mapToGlobal(p1)); tp1.setState(QEventPoint::State::Pressed); tp1.setPressure(0.5); qt_handleTouchEvent(window.data(), device, {tp1}); diff --git a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp index b65e12d2be..a9f35e8727 100644 --- a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp +++ b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -29,6 +29,7 @@ #include <QtTest/QtTest> #include <QtTest/QSignalSpy> #include <QtGui/QStyleHints> +#include <QtGui/private/qevent_p.h> #include <qpa/qwindowsysteminterface.h> #include <private/qquickpincharea_p.h> #include <QtQuick/private/qquickrectangle_p.h> @@ -175,12 +176,12 @@ void tst_QQuickPinchArea::pinchProperties() QCOMPARE(rotMaxSpy.count(),1); } -QEventPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i) +QMutableEventPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i) { - QEventPoint touchPoint(id); - touchPoint.setPos(i->mapFromScene(p)); - touchPoint.setScreenPos(v->mapToGlobal(p)); - touchPoint.setScenePos(p); + QMutableEventPoint touchPoint(id); + touchPoint.setPosition(i->mapFromScene(p)); + touchPoint.setGlobalPosition(v->mapToGlobal(p)); + touchPoint.setScenePosition(p); return touchPoint; } diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index ef304894bc..603fa28bee 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -68,18 +68,16 @@ struct TouchEventData { QList<QEventPoint> touchPoints; }; -static QEventPoint makeTouchPoint(QQuickItem *item, const QPointF &p, const QPointF &lastPoint = QPointF()) +static QMutableEventPoint makeTouchPoint(QQuickItem *item, const QPointF &p, const QPointF &lastPoint = QPointF()) { QPointF last = lastPoint.isNull() ? p : lastPoint; - QEventPoint tp; + QMutableEventPoint tp; - tp.setPos(p); - tp.setLastPos(last); - tp.setScenePos(item->mapToScene(p)); - tp.setLastScenePos(item->mapToScene(last)); - tp.setScreenPos(item->window()->mapToGlobal(tp.scenePosition().toPoint())); - tp.setLastScreenPos(item->window()->mapToGlobal(tp.lastScenePos().toPoint())); + tp.setPosition(p); + tp.setScenePosition(item->mapToScene(p)); + tp.setGlobalPosition(item->mapToGlobal(p)); + tp.setGlobalLastPosition(item->mapToGlobal(last)); return tp; } @@ -98,12 +96,12 @@ static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, QEventPoint:: #define COMPARE_TOUCH_POINTS(tp1, tp2) \ { \ - QCOMPARE(tp1.position(), tp2.pos()); \ - QCOMPARE(tp1.lastPos(), tp2.lastPos()); \ - QCOMPARE(tp1.scenePos(), tp2.scenePos()); \ - QCOMPARE(tp1.lastScenePos(), tp2.lastScenePos()); \ - QCOMPARE(tp1.screenPos(), tp2.screenPos()); \ - QCOMPARE(tp1.lastScreenPos(), tp2.lastScreenPos()); \ + QCOMPARE(tp1.position(), tp2.position()); \ + QCOMPARE(tp1.lastPosition(), tp2.lastPosition()); \ + QCOMPARE(tp1.scenePosition(), tp2.scenePosition()); \ + QCOMPARE(tp1.sceneLastPosition(), tp2.sceneLastPosition()); \ + QCOMPARE(tp1.globalPosition(), tp2.globalPosition()); \ + QCOMPARE(tp1.globalLastPosition(), tp2.globalLastPosition()); \ } #define COMPARE_TOUCH_DATA(d1, d2) \ @@ -207,7 +205,7 @@ public: return; } ++touchEventCount; - lastEvent = makeTouchData(event->type(), event->window(), event->touchPointStates(), event->touchPoints()); + lastEvent = makeTouchData(event->type(), nullptr, event->touchPointStates(), event->touchPoints()); if (event->device()->capabilities().testFlag(QPointingDevice::Capability::Velocity) && !event->touchPoints().isEmpty()) { lastVelocity = event->touchPoints().first().velocity(); } else { @@ -234,7 +232,7 @@ public: return; } mouseMoveCount = ++mouseMoveNum; - lastVelocityFromMouseMove = QGuiApplicationPrivate::mouseEventVelocity(e); + lastVelocityFromMouseMove = e->point(0).velocity(); lastMouseCapabilityFlags = e->device()->capabilities(); lastMousePos = e->position().toPoint(); } @@ -1006,14 +1004,12 @@ void tst_qquickwindow::touchEvent_velocity() item->setPosition(QPointF(50, 50)); item->setSize(QSizeF(150, 150)); - QList<QEventPoint> points; - QEventPoint tp; - tp.setId(1); - tp.setState(QEventPoint::State::Pressed); + QList<QMutableEventPoint> points; + QMutableEventPoint tp(1, QEventPoint::State::Pressed); const QPointF localPos = item->mapToScene(QPointF(10, 10)); const QPointF screenPos = window->mapToGlobal(localPos.toPoint()); - tp.setPos(localPos); - tp.setScreenPos(screenPos); + tp.setPosition(localPos); + tp.setGlobalPosition(screenPos); tp.setEllipseDiameters(QSizeF(4, 4)); points << tp; QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, @@ -1023,8 +1019,8 @@ void tst_qquickwindow::touchEvent_velocity() QCOMPARE(item->touchEventCount, 1); points[0].setState(QEventPoint::State::Updated); - points[0].setPos(localPos + QPointF(5, 5)); - points[0].setScreenPos(screenPos + QPointF(5, 5)); + points[0].setPosition(localPos + QPointF(5, 5)); + points[0].setGlobalPosition(screenPos + QPointF(5, 5)); QVector2D velocity(1.5, 2.5); points[0].setVelocity(velocity); QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, @@ -1040,8 +1036,8 @@ void tst_qquickwindow::touchEvent_velocity() QMatrix4x4 transformMatrix; transformMatrix.rotate(-90, 0, 0, 1); // counterclockwise QVector2D transformedVelocity = transformMatrix.mapVector(velocity).toVector2D(); - points[0].setPos(points[0].position() + QPointF(5, 5)); - points[0].setScreenPos(points[0].globalPosition() + QPointF(5, 5)); + points[0].setPosition(points[0].position() + QPointF(5, 5)); + points[0].setGlobalPosition(points[0].globalPosition() + QPointF(5, 5)); QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window)); QGuiApplication::processEvents(); @@ -1150,14 +1146,12 @@ void tst_qquickwindow::mouseFromTouch_basic() item->setSize(QSizeF(150, 150)); item->acceptTouchEvents = false; - QList<QEventPoint> points; - QEventPoint tp; - tp.setId(1); - tp.setState(QEventPoint::State::Pressed); + QList<QMutableEventPoint> points; + QMutableEventPoint tp(1, QEventPoint::State::Pressed); const QPointF localPos = item->mapToScene(QPointF(10, 10)); const QPointF screenPos = window->mapToGlobal(localPos.toPoint()); - tp.setPos(localPos); - tp.setScreenPos(screenPos); + tp.setPosition(localPos); + tp.setGlobalPosition(screenPos); tp.setEllipseDiameters(QSizeF(4, 4)); points << tp; QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, @@ -1165,8 +1159,8 @@ void tst_qquickwindow::mouseFromTouch_basic() QGuiApplication::processEvents(); QQuickTouchUtils::flush(window); points[0].setState(QEventPoint::State::Updated); - points[0].setPos(localPos + QPointF(5, 5)); - points[0].setScreenPos(screenPos + QPointF(5, 5)); + points[0].setPosition(localPos + QPointF(5, 5)); + points[0].setGlobalPosition(screenPos + QPointF(5, 5)); QVector2D velocity(1.5, 2.5); points[0].setVelocity(velocity); QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, @@ -1194,15 +1188,15 @@ void tst_qquickwindow::mouseFromTouch_basic() QVector2D transformedVelocity = transformMatrix.mapVector(velocity).toVector2D(); points[0].setState(QEventPoint::State::Pressed); points[0].setVelocity(velocity); - tp.setPos(localPos); - tp.setScreenPos(screenPos); + tp.setPosition(localPos); + tp.setGlobalPosition(screenPos); QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window)); QGuiApplication::processEvents(); QQuickTouchUtils::flush(window); points[0].setState(QEventPoint::State::Updated); - points[0].setPos(localPos + QPointF(5, 5)); - points[0].setScreenPos(screenPos + QPointF(5, 5)); + points[0].setPosition(localPos + QPointF(5, 5)); + points[0].setGlobalPosition(screenPos + QPointF(5, 5)); QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window)); QGuiApplication::processEvents(); @@ -2846,8 +2840,8 @@ void tst_qquickwindow::pointerEventTypeAndPointCount() QPointF screenPosition(333, 366); QMouseEvent me(QEvent::MouseButtonPress, localPosition, scenePosition, screenPosition, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); - QTouchEvent te(QEvent::TouchBegin, touchDevice, Qt::NoModifier, QEventPoint::State::Pressed, - QList<QEventPoint>() << QEventPoint(1)); + QMutableTouchEvent te(QEvent::TouchBegin, touchDevice, Qt::NoModifier, + QList<QEventPoint>() << QEventPoint(1)); QQuickPointerMouseEvent pme(nullptr, QPointingDevice::primaryPointingDevice()); @@ -2874,14 +2868,16 @@ void tst_qquickwindow::pointerEventTypeAndPointCount() QCOMPARE(pte.touchPointById(1)->id(), 1); QVERIFY(!pte.touchPointById(0)); - te.setTouchPoints(QList<QEventPoint>() << QEventPoint(1) << QEventPoint(2)); + te = QMutableTouchEvent(QEvent::TouchBegin, touchDevice, Qt::NoModifier, + QList<QEventPoint>() << QEventPoint(1) << QEventPoint(2)); pte.reset(&te); QCOMPARE(pte.pointCount(), 2); QCOMPARE(pte.touchPointById(1)->id(), 1); QCOMPARE(pte.touchPointById(2)->id(), 2); QVERIFY(!pte.touchPointById(0)); - te.setTouchPoints(QList<QEventPoint>() << QEventPoint(2)); + te = QMutableTouchEvent(QEvent::TouchBegin, touchDevice, Qt::NoModifier, + QList<QEventPoint>() << QEventPoint(2)); pte.reset(&te); QCOMPARE(pte.pointCount(), 1); QCOMPARE(pte.touchPointById(2)->id(), 2); |