diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 12 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 61 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 3 |
3 files changed, 35 insertions, 41 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 53f855e56d..bd37323ef9 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7309,10 +7309,18 @@ void QQuickItem::unsetCursor() void QQuickItem::grabMouse() { Q_D(QQuickItem); - if (!d->window) + if (!d->window || d->window->mouseGrabberItem() == this) return; QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window); - windowPriv->setMouseGrabber(this); + bool fromTouch = windowPriv->isDeliveringTouchAsMouse(); + auto point = fromTouch ? + windowPriv->pointerEventInstance(windowPriv->touchMouseDevice)->pointById(windowPriv->touchMouseId) : + windowPriv->pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0); + if (point) { + QQuickItem *oldGrabber = point->grabber(); + point->setGrabber(this); + windowPriv->sendUngrabEvent(oldGrabber, fromTouch); + } } /*! diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index fa251b7d78..fbcfa84948 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -738,40 +738,6 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve return false; } -void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber) -{ - Q_Q(QQuickWindow); - if (q->mouseGrabberItem() == grabber) - return; - - qCDebug(DBG_MOUSE_TARGET) << "grabber" << q->mouseGrabberItem() << "->" << grabber; - QQuickItem *oldGrabber = q->mouseGrabberItem(); - bool fromTouch = false; - - if (grabber && touchMouseId != -1 && touchMouseDevice) { - // update the touch item for mouse touch id to the new grabber - qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << touchMouseId << "->" << q->mouseGrabberItem(); - auto point = pointerEventInstance(touchMouseDevice)->pointById(touchMouseId); - if (point) - point->setGrabber(grabber); - fromTouch = true; - } else { - QQuickPointerEvent *event = pointerEventInstance(QQuickPointerDevice::genericMouseDevice()); - Q_ASSERT(event->pointCount() == 1); - event->point(0)->setGrabber(grabber); - } - - if (oldGrabber) { - QEvent e(QEvent::UngrabMouse); - QSet<QQuickItem *> hasFiltered; - if (!sendFilteredMouseEvent(oldGrabber->parentItem(), oldGrabber, &e, &hasFiltered)) { - oldGrabber->mouseUngrabEvent(); - if (fromTouch) - oldGrabber->touchUngrabEvent(); - } - } -} - void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector<int> &ids) { QSet<QQuickItem*> ungrab; @@ -817,8 +783,14 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to { Q_Q(QQuickWindow); if (Q_LIKELY(mouse) && q->mouseGrabberItem() == grabber) { - qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << q->mouseGrabberItem() << "-> null"; - setMouseGrabber(nullptr); + bool fromTouch = isDeliveringTouchAsMouse(); + auto point = fromTouch ? + pointerEventInstance(touchMouseDevice)->pointById(touchMouseId) : + pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0); + QQuickItem *oldGrabber = point->grabber(); + qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << oldGrabber << "-> null"; + point->setGrabber(nullptr); + sendUngrabEvent(oldGrabber, fromTouch); } if (Q_LIKELY(touch)) { const auto touchDevices = QQuickPointerDevice::touchDevices(); @@ -836,6 +808,19 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to } } +void QQuickWindowPrivate::sendUngrabEvent(QQuickItem *grabber, bool touch) +{ + if (!grabber) + return; + QEvent e(QEvent::UngrabMouse); + QSet<QQuickItem *> hasFiltered; + if (!sendFilteredMouseEvent(grabber->parentItem(), grabber, &e, &hasFiltered)) { + grabber->mouseUngrabEvent(); + if (touch) + grabber->touchUngrabEvent(); + } +} + /*! 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). @@ -1494,7 +1479,7 @@ QQuickItem *QQuickWindow::mouseGrabberItem() const { Q_D(const QQuickWindow); - if (d->touchMouseId != -1 && d->touchMouseDevice) { + if (d->isDeliveringTouchAsMouse()) { if (QQuickPointerEvent *event = d->queryPointerEventInstance(d->touchMouseDevice)) { auto point = event->pointById(d->touchMouseId); return point ? point->grabber() : nullptr; @@ -1656,7 +1641,7 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven auto point = pointerEvent->point(0); lastMousePosition = point->scenePos(); QQuickItem *grabber = point->grabber(); - if (!grabber && touchMouseId != -1 && touchMouseDevice) + if (!grabber && isDeliveringTouchAsMouse()) grabber = q->mouseGrabberItem(); if (grabber) { diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index e47dde6464..7dbfed099e 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -141,10 +141,11 @@ public: // Mouse positions are saved in widget coordinates QPointF lastMousePosition; bool deliverTouchAsMouse(QQuickItem *item, QQuickPointerEvent *pointerEvent); + bool isDeliveringTouchAsMouse() const { return touchMouseId != -1 && touchMouseDevice; } void translateTouchEvent(QTouchEvent *touchEvent); - void setMouseGrabber(QQuickItem *grabber); void grabTouchPoints(QQuickItem *grabber, const QVector<int> &ids); void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true); + void sendUngrabEvent(QQuickItem *grabber, bool touch); static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0); void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent); bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QEvent *, QSet<QQuickItem *> *); |