aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-16 15:00:08 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-18 09:53:04 +0100
commitd63ad7efb56452e3ad019c38ddf887ddcc8d338a (patch)
treed0a4f58cdd05357869ed5f76faa21d7a7a6d76b1 /src/quick
parentda9b9a4e6e2cddd6dd1dbf2e126fc2d332bc0616 (diff)
Use QMutable*Event classes to copy and synthesize events
QMutableTouch/SinglePointEvent can be publicly copy constructed from their non-mutable counterparts, make use of that. Change-Id: I7f56a9f9649bb7726cca1eaddccfdc3f21d47554 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickflickable.cpp7
-rw-r--r--src/quick/items/qquickitem.cpp10
-rw-r--r--src/quick/items/qquickitem_p.h2
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp14
-rw-r--r--src/quick/items/qquickpathview.cpp8
-rw-r--r--src/quick/items/qquickwindow.cpp48
-rw-r--r--src/quick/items/qquickwindow_p.h2
7 files changed, 45 insertions, 46 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 9e7b2a4f17..b451c275c2 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1451,10 +1451,9 @@ void QQuickFlickable::mouseReleaseEvent(QMouseEvent *event)
d->replayDelayedPress();
// Now send the release
- auto &firstPoint = event->point(0);
- if (auto grabber = qmlobject_cast<QQuickItem *>(event->exclusiveGrabber(firstPoint))) {
- QMouseEvent localized(*event);
- QMutableEventPoint::from(firstPoint).setPosition(grabber->mapFromScene(event->scenePosition()));
+ if (auto grabber = qmlobject_cast<QQuickItem *>(event->exclusiveGrabber(event->point(0)))) {
+ QMutableSinglePointEvent localized(*event);
+ localized.mutablePoint().setPosition(grabber->mapFromScene(localized.scenePosition()));
QCoreApplication::sendEvent(window(), &localized);
}
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 116d1a370b..5dcc191053 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -8389,7 +8389,7 @@ QQuickItemLayer *QQuickItemPrivate::layer() const
monitor eventpoint movements until a drag threshold is exceeded or the
requirements for a gesture to be recognized are met in some other way.
*/
-QTouchEvent QQuickItemPrivate::localizedTouchEvent(const QTouchEvent *event, bool isFiltering)
+void QQuickItemPrivate::localizedTouchEvent(const QTouchEvent *event, bool isFiltering, QMutableTouchEvent *localized)
{
Q_Q(QQuickItem);
QList<QEventPoint> touchPoints;
@@ -8449,8 +8449,10 @@ QTouchEvent QQuickItemPrivate::localizedTouchEvent(const QTouchEvent *event, boo
// Now touchPoints will have only points which are inside the item.
// But if none of them were just pressed inside, and the item has no other reason to care, ignore them anyway.
- if (touchPoints.isEmpty() || (!anyPressOrReleaseInside && !anyGrabber && !isFiltering))
- return QTouchEvent(QEvent::None);
+ if (touchPoints.isEmpty() || (!anyPressOrReleaseInside && !anyGrabber && !isFiltering)) {
+ *localized = QMutableTouchEvent(QEvent::None);
+ return;
+ }
// if all points have the same state, set the event type accordingly
QEvent::Type eventType = event->type();
@@ -8470,7 +8472,7 @@ QTouchEvent QQuickItemPrivate::localizedTouchEvent(const QTouchEvent *event, boo
ret.setTarget(q);
ret.setTimestamp(event->timestamp());
ret.accept();
- return ret;
+ *localized = ret;
}
bool QQuickItemPrivate::hasPointerHandlers() const
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 1e33eadeac..b97b9cefd5 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -281,7 +281,7 @@ public:
QQuickItemLayer *layer() const;
- QTouchEvent localizedTouchEvent(const QTouchEvent *event, bool isFiltering);
+ void localizedTouchEvent(const QTouchEvent *event, bool isFiltering, QMutableTouchEvent *localized);
bool hasPointerHandlers() const;
bool hasHoverHandlers() const;
virtual void addPointerHandler(QQuickPointerHandler *h);
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 23cf6c0351..e23e7365df 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -908,21 +908,21 @@ bool QQuickMultiPointTouchArea::sendMouseEvent(QMouseEvent *event)
QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr;
bool stealThisEvent = _stealMouse;
if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab())) {
- QMouseEvent mouseEvent = *event;
- auto mut = QMutableSinglePointEvent::from(&mouseEvent);
- mut->mutablePoint().setPosition(localPos);
- mut->setSource(Qt::MouseEventSynthesizedByQt);
+ QMutableSinglePointEvent mouseEvent(*event);
+ mouseEvent.mutablePoint().setPosition(localPos);
+ mouseEvent.setSource(Qt::MouseEventSynthesizedByQt);
mouseEvent.setAccepted(false);
+ QMouseEvent *pmouseEvent = static_cast<QMouseEvent *>(static_cast<QSinglePointEvent *>(&mouseEvent));
switch (mouseEvent.type()) {
case QEvent::MouseMove:
- mouseMoveEvent(&mouseEvent);
+ mouseMoveEvent(pmouseEvent);
break;
case QEvent::MouseButtonPress:
- mousePressEvent(&mouseEvent);
+ mousePressEvent(pmouseEvent);
break;
case QEvent::MouseButtonRelease:
- mouseReleaseEvent(&mouseEvent);
+ mouseReleaseEvent(pmouseEvent);
break;
default:
break;
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index d7f85c288d..d90ae7eb77 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1859,20 +1859,20 @@ bool QQuickPathView::childMouseEventFilter(QQuickItem *i, QEvent *e)
bool stealThisEvent = d->stealMouse;
if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab() || grabberDisabled)) {
// Make a localized copy of the QMouseEvent.
- QMouseEvent localizedEvent(*static_cast<QMouseEvent *>(pe));
+ QMutableSinglePointEvent localizedEvent(*static_cast<QMouseEvent *>(pe));
QMutableEventPoint::from(localizedEvent.point(0)).setPosition(localPos);
localizedEvent.setAccepted(false);
switch (localizedEvent.type()) {
case QEvent::MouseMove:
- d->handleMouseMoveEvent(&localizedEvent);
+ d->handleMouseMoveEvent(static_cast<QMouseEvent *>(static_cast<QSinglePointEvent *>(&localizedEvent)));
break;
case QEvent::MouseButtonPress:
- d->handleMousePressEvent(&localizedEvent);
+ d->handleMousePressEvent(static_cast<QMouseEvent *>(static_cast<QSinglePointEvent *>(&localizedEvent)));
stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above
break;
case QEvent::MouseButtonRelease:
- d->handleMouseReleaseEvent(&localizedEvent);
+ d->handleMouseReleaseEvent(static_cast<QMouseEvent *>(static_cast<QSinglePointEvent *>(&localizedEvent)));
break;
default:
break;
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 8183988835..e09723e973 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -868,18 +868,15 @@ QQmlListProperty<QObject> QQuickWindowPrivate::data()
QQuickWindowPrivate::data_removeLast);
}
-QMouseEvent QQuickWindowPrivate::touchToMouseEvent(QEvent::Type type, const QEventPoint &p, QTouchEvent *event, QQuickItem *item)
+void QQuickWindowPrivate::touchToMouseEvent(QEvent::Type type, const QEventPoint &p, const QTouchEvent *touchEvent, QMutableSinglePointEvent *mouseEvent)
{
- Q_UNUSED(item)
Q_ASSERT(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents));
- QMutableSinglePointEvent ret(type, event->pointingDevice(), p,
+ QMutableSinglePointEvent ret(type, touchEvent->pointingDevice(), p,
(type == QEvent::MouseMove ? Qt::NoButton : Qt::LeftButton),
(type == QEvent::MouseButtonRelease ? Qt::NoButton : Qt::LeftButton),
- event->modifiers(), Qt::MouseEventSynthesizedByQt);
+ touchEvent->modifiers(), Qt::MouseEventSynthesizedByQt);
ret.setAccepted(true); // this now causes the persistent touchpoint to be accepted too
- ret.setTimestamp(event->timestamp());
- static_assert(sizeof(QMutableSinglePointEvent) == sizeof(QMouseEvent));
- return *static_cast<QMouseEvent*>(static_cast<QSinglePointEvent*>(&ret));
+ *mouseEvent = ret;
}
bool QQuickWindowPrivate::checkIfDoubleTapped(ulong newPressEventTimestamp, QPoint newPressPos)
@@ -947,7 +944,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEvent *poi
}
// FIXME: make this work for mouse events too and get rid of the asTouchEvent in here.
- QTouchEvent event = QQuickItemPrivate::get(item)->localizedTouchEvent(pointerEvent, false);
+ QMutableTouchEvent event;
+ QQuickItemPrivate::get(item)->localizedTouchEvent(pointerEvent, false, &event);
if (!event.points().count())
return false;
@@ -964,7 +962,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEvent *poi
break;
qCDebug(DBG_TOUCH_TARGET) << device << "TP (mouse)" << Qt::hex << p.id() << "->" << item;
- QMouseEvent mousePress = touchToMouseEvent(QEvent::MouseButtonPress, p, &event, item);
+ QMutableSinglePointEvent mousePress(QEvent::None, nullptr, QEventPoint());
+ touchToMouseEvent(QEvent::MouseButtonPress, p, &event, &mousePress);
// Send a single press and see if that's accepted
QCoreApplication::sendEvent(item, &mousePress);
@@ -979,7 +978,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEvent *poi
if (checkIfDoubleTapped(event.timestamp(), p.globalPosition().toPoint())) {
// since we synth the mouse event from from touch, we respect the
// QPlatformTheme::TouchDoubleTapDistance instead of QPlatformTheme::MouseDoubleClickDistance
- QMouseEvent mouseDoubleClick = touchToMouseEvent(QEvent::MouseButtonDblClick, p, &event, item);
+ QMutableSinglePointEvent mouseDoubleClick(QEvent::None, nullptr, QEventPoint());
+ touchToMouseEvent(QEvent::MouseButtonDblClick, p, &event, &mouseDoubleClick);
QCoreApplication::sendEvent(item, &mouseDoubleClick);
event.setAccepted(mouseDoubleClick.isAccepted());
if (!mouseDoubleClick.isAccepted())
@@ -1000,7 +1000,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEvent *poi
touchMousePressTimestamp = 0; // Got dragged too far, dismiss the double tap
}
if (QQuickItem *mouseGrabberItem = qmlobject_cast<QQuickItem *>(pointerEvent->exclusiveGrabber(p))) {
- QMouseEvent me = touchToMouseEvent(QEvent::MouseMove, p, &event, mouseGrabberItem);
+ QMutableSinglePointEvent me(QEvent::None, nullptr, QEventPoint());
+ touchToMouseEvent(QEvent::MouseMove, p, &event, &me);
QCoreApplication::sendEvent(item, &me);
event.setAccepted(me.isAccepted());
if (me.isAccepted())
@@ -1010,7 +1011,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEvent *poi
// no grabber, check if we care about mouse hover
// FIXME: this should only happen once, not recursively... I'll ignore it just ignore hover now.
// hover for touch???
- QMouseEvent me = touchToMouseEvent(QEvent::MouseMove, p, &event, item);
+ QMutableSinglePointEvent me(QEvent::None, nullptr, QEventPoint());
+ touchToMouseEvent(QEvent::MouseMove, p, &event, &me);
if (lastMousePosition.isNull())
lastMousePosition = me.scenePosition();
QPointF last = lastMousePosition;
@@ -1026,7 +1028,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEvent *poi
} else if (p.state() & QEventPoint::State::Released) {
// currently handled point was released
if (QQuickItem *mouseGrabberItem = qmlobject_cast<QQuickItem *>(pointerEvent->exclusiveGrabber(p))) {
- QMouseEvent me = touchToMouseEvent(QEvent::MouseButtonRelease, p, &event, mouseGrabberItem);
+ QMutableSinglePointEvent me(QEvent::None, nullptr, QEventPoint());
+ touchToMouseEvent(QEvent::MouseButtonRelease, p, &event, &me);
QCoreApplication::sendEvent(item, &me);
if (item->acceptHoverEvents() && p.globalPosition() != QGuiApplicationPrivate::lastCursorPosition) {
@@ -2057,14 +2060,7 @@ void QQuickWindowPrivate::deliverKeyEvent(QKeyEvent *e)
*/
QPointerEvent *QQuickWindowPrivate::clonePointerEvent(QPointerEvent *event, std::optional<QPointF> transformedLocalPos)
{
- QPointerEvent *ret = nullptr;
- if (isMouseEvent(event)) {
- ret = new QMouseEvent(*(static_cast<QMouseEvent *>(event)));
- } else if (isTouchEvent(event)) {
- ret = new QTouchEvent(*(static_cast<QTouchEvent *>(event)));
- } else if (isTabletEvent(event)) {
- ret = new QTabletEvent(*(static_cast<QTabletEvent *>(event)));
- }
+ QPointerEvent *ret = static_cast<QPointerEvent*>(event->clone());
QMutableEventPoint &point = QMutableEventPoint::from(ret->point(0));
point.detach();
point.setTimestamp(event->timestamp());
@@ -2945,7 +2941,8 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, bool isG
return;
bool eventAccepted = false;
- QTouchEvent touchEvent = QQuickItemPrivate::get(item)->localizedTouchEvent(static_cast<QTouchEvent *>(pointerEvent), false);
+ QMutableTouchEvent touchEvent;
+ QQuickItemPrivate::get(item)->localizedTouchEvent(static_cast<QTouchEvent *>(pointerEvent), false, &touchEvent);
if (touchEvent.type() == QEvent::None)
return; // no points inside this item
@@ -3261,8 +3258,8 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QPointerEvent *event, QQu
} else if (acceptsTouchEvents || receiver->acceptedMouseButtons()) {
// get a touch event customized for delivery to filteringParent
// TODO should not be necessary? because QQuickWindowPrivate::deliverMatchingPointsToItem() does it
- QTouchEvent filteringParentTouchEvent =
- QQuickItemPrivate::get(receiver)->localizedTouchEvent(static_cast<QTouchEvent *>(event), true);
+ QMutableTouchEvent filteringParentTouchEvent;
+ QQuickItemPrivate::get(receiver)->localizedTouchEvent(static_cast<QTouchEvent *>(event), true, &filteringParentTouchEvent);
if (filteringParentTouchEvent.type() != QEvent::None) {
qCDebug(DBG_TOUCH) << "letting parent" << filteringParent << "filter for" << receiver << &filteringParentTouchEvent;
if (filteringParent->childMouseEventFilter(receiver, &filteringParentTouchEvent)) {
@@ -3299,7 +3296,8 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QPointerEvent *event, QQu
if (touchMouseUnset || touchMouseId == tp.id()) {
// convert filteringParentTouchEvent (which is already transformed wrt local position, velocity, etc.)
// into a synthetic mouse event, and let childMouseEventFilter() have another chance with that
- QMouseEvent mouseEvent = touchToMouseEvent(t, tp, &filteringParentTouchEvent, receiver);
+ QMutableSinglePointEvent mouseEvent(QEvent::None, nullptr, QEventPoint());
+ touchToMouseEvent(t, tp, &filteringParentTouchEvent, &mouseEvent);
// If a filtering item calls QQuickWindow::mouseGrabberItem(), it should
// report the touchpoint's grabber. Whenever we send a synthetic mouse event,
// touchMouseId and touchMouseDevice must be set, even if it's only temporarily and isn't grabbed.
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 3be6f5cd8c..18a43487c1 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -197,7 +197,7 @@ public:
static bool isTabletEvent(const QPointerEvent *ev);
// delivery of pointer events:
- QMouseEvent touchToMouseEvent(QEvent::Type type, const QEventPoint &p, QTouchEvent *event, QQuickItem *item);
+ void touchToMouseEvent(QEvent::Type type, const QEventPoint &p, const QTouchEvent *touchEvent, QMutableSinglePointEvent *mouseEvent);
void ensureDeviceConnected(const QPointingDevice *dev);
void deliverPointerEvent(QPointerEvent *);
bool deliverTouchCancelEvent(QTouchEvent *);