aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-09-28 21:36:14 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2020-10-02 15:56:37 +0200
commitcb173de493b3b70bad88e138bf1fe2c1ef7990d2 (patch)
treed9503151a3635841a62e3202733d33da2ec49adf /src/quick
parentb2e1183cb7f4f552bb4409172f82327111f754bb (diff)
PathView: stop using QQWindowPriv::cloneMouseEvent; refactor filtering
There's no need to heap-allocate a short-term mouse event; and localizing one is easy enough via QMutableEventPoint::setPosition. The sendMouseEvent() function (and its name) didn't make as much sense as handling the filtering completely in the childMouseEventFilter() function. Checking and changing the grabber is also now possible via accessors in the event itself, so now we have one fewer use of QQuickItem::grabMouse() and QQuickWindow::mouseGrabberItem(). Change-Id: I84f9f26e349a8d1aabacdbdbb264949d1103e91d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickpathview.cpp109
-rw-r--r--src/quick/items/qquickpathview_p.h1
2 files changed, 50 insertions, 60 deletions
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index e6ec9e21d9..14ae811bc6 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1837,71 +1837,62 @@ void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *event)
q->movementEnding();
}
-bool QQuickPathView::sendMouseEvent(QMouseEvent *event)
+bool QQuickPathView::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
Q_D(QQuickPathView);
- QPointF localPos = mapFromScene(event->scenePosition());
-
- QQuickWindow *c = window();
- QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr;
- if (grabber == this && d->stealMouse) {
- // we are already the grabber and we do want the mouse event to ourselves.
- return true;
- }
-
- bool grabberDisabled = grabber && !grabber->isEnabled();
- bool stealThisEvent = d->stealMouse;
- if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab() || grabberDisabled)) {
- QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
- mouseEvent->setAccepted(false);
-
- switch (mouseEvent->type()) {
- case QEvent::MouseMove:
- d->handleMouseMoveEvent(mouseEvent.data());
- break;
- case QEvent::MouseButtonPress:
- d->handleMousePressEvent(mouseEvent.data());
- stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above
- break;
- case QEvent::MouseButtonRelease:
- d->handleMouseReleaseEvent(mouseEvent.data());
- break;
- default:
- break;
- }
- grabber = c ? c->mouseGrabberItem() : nullptr;
- if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || grabberDisabled) {
- grabMouse();
- }
+ if (!isVisible() || !d->interactive || !e->isPointerEvent())
+ return QQuickItem::childMouseEventFilter(i, e);
- const bool filtered = stealThisEvent || grabberDisabled;
- if (filtered) {
- event->setAccepted(false);
+ QPointerEvent *pe = static_cast<QPointerEvent *>(e);
+ if (QQuickWindowPrivate::isMouseEvent(pe)) {
+ // The event is localized for the intended receiver (in the delegate, probably),
+ // but we need to look at position relative to the PathView itself.
+ const auto &point = pe->points().first();
+ QPointF localPos = mapFromScene(point.scenePosition());
+ QQuickItem *grabber = qmlobject_cast<QQuickItem *>(pe->exclusiveGrabber(point));
+ if (grabber == this && d->stealMouse) {
+ // we are already the grabber and we do want the mouse event to ourselves.
+ return true;
}
- return filtered;
- } else if (d->timer.isValid()) {
- d->timer.invalidate();
- d->fixOffset();
- }
- if (event->type() == QEvent::MouseButtonRelease || (grabber && grabber->keepMouseGrab() && !grabberDisabled)) {
- d->stealMouse = false;
- }
- return false;
-}
-bool QQuickPathView::childMouseEventFilter(QQuickItem *i, QEvent *e)
-{
- Q_D(QQuickPathView);
- if (!isVisible() || !d->interactive)
- return QQuickItem::childMouseEventFilter(i, e);
+ bool grabberDisabled = grabber && !grabber->isEnabled();
+ 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));
+ QMutableEventPoint::from(localizedEvent.point(0)).setPosition(localPos);
+ localizedEvent.setAccepted(false);
+
+ switch (localizedEvent.type()) {
+ case QEvent::MouseMove:
+ d->handleMouseMoveEvent(&localizedEvent);
+ break;
+ case QEvent::MouseButtonPress:
+ d->handleMousePressEvent(&localizedEvent);
+ stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above
+ break;
+ case QEvent::MouseButtonRelease:
+ d->handleMouseReleaseEvent(&localizedEvent);
+ break;
+ default:
+ break;
+ }
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseMove:
- case QEvent::MouseButtonRelease:
- return sendMouseEvent(static_cast<QMouseEvent *>(e));
- default:
- break;
+ grabber = qmlobject_cast<QQuickItem *>(localizedEvent.exclusiveGrabber(localizedEvent.points().first()));
+ if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || grabberDisabled)
+ pe->setExclusiveGrabber(point, this);
+
+ const bool filtered = stealThisEvent || grabberDisabled;
+ if (filtered)
+ pe->setAccepted(false);
+ return filtered;
+ } else if (d->timer.isValid()) {
+ d->timer.invalidate();
+ d->fixOffset();
+ }
+ if (pe->type() == QEvent::MouseButtonRelease || (grabber && grabber->keepMouseGrab() && !grabberDisabled))
+ d->stealMouse = false;
+ return false;
}
return QQuickItem::childMouseEventFilter(i, e);
diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h
index 0c5a6578c3..c14b56cfc0 100644
--- a/src/quick/items/qquickpathview_p.h
+++ b/src/quick/items/qquickpathview_p.h
@@ -229,7 +229,6 @@ protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *) override;
- bool sendMouseEvent(QMouseEvent *event);
bool childMouseEventFilter(QQuickItem *, QEvent *) override;
void mouseUngrabEvent() override;
void componentComplete() override;