diff options
-rw-r--r-- | src/quick/items/qquickitem.cpp | 11 | ||||
-rw-r--r-- | src/quick/items/qquickitem.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickmousearea.cpp | 6 | ||||
-rw-r--r-- | src/quick/items/qquickmousearea_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 40 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 1 |
6 files changed, 38 insertions, 22 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 5dcc191053..fa2f388fe6 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4226,17 +4226,6 @@ bool QQuickItem::childMouseEventFilter(QQuickItem *item, QEvent *event) return false; } -/*! - \internal - */ -void QQuickItem::windowDeactivateEvent() -{ - const auto children = childItems(); - for (QQuickItem* item : children) { - item->windowDeactivateEvent(); - } -} - #if QT_CONFIG(im) /*! This method is only relevant for input items. diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index 7b72b6032d..c7bc2f54c3 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -449,7 +449,6 @@ protected: virtual void dropEvent(QDropEvent *); #endif virtual bool childMouseEventFilter(QQuickItem *, QEvent *); - virtual void windowDeactivateEvent(); virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); virtual void releaseResources(); diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index b306c0ddf4..6e7688a734 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -1038,12 +1038,6 @@ void QQuickMouseArea::timerEvent(QTimerEvent *event) } } -void QQuickMouseArea::windowDeactivateEvent() -{ - ungrabMouse(); - QQuickItem::windowDeactivateEvent(); -} - void QQuickMouseArea::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickMouseArea); diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index c368f43b30..e0f7397f06 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -180,7 +180,6 @@ protected: #endif bool childMouseEventFilter(QQuickItem *i, QEvent *e) override; void timerEvent(QTimerEvent *event) override; - void windowDeactivateEvent() override; void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; void itemChange(ItemChange change, const ItemChangeData& value) override; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 3721620bf2..0515a62b1e 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -849,7 +849,7 @@ void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state) { Q_D(QQuickWindow); if (state != Qt::ApplicationActive && d->contentItem) - d->contentItem->windowDeactivateEvent(); + d->handleWindowDeactivate(); } /*! @@ -1945,8 +1945,7 @@ bool QQuickWindow::event(QEvent *e) break; #endif case QEvent::WindowDeactivate: - if (d->contentItem) - d->contentItem->windowDeactivateEvent(); + d->handleWindowDeactivate(); break; case QEvent::PlatformSurface: if ((static_cast<QPlatformSurfaceEvent *>(e))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) { @@ -2296,6 +2295,41 @@ void QQuickWindowPrivate::deliverDelayedTouchEvent() deliverPointerEvent(e.data()); } +/*! \internal + The handler for the QEvent::WindowDeactivate event, and also when + Qt::ApplicationState tells us the application is no longer active. + It clears all exclusive grabs of items and handlers whose window is this one, + for all known pointing devices. + + The QEvent is not passed into this function because in the first case it's + just a plain QEvent with no extra data, and because the application state + change is delivered via a signal rather than an event. +*/ +void QQuickWindowPrivate::handleWindowDeactivate() +{ + Q_Q(QQuickWindow); + qCDebug(DBG_FOCUS) << "deactivated" << windowTitle; + const auto inputDevices = QInputDevice::devices(); + for (auto device : inputDevices) { + if (auto pointingDevice = qobject_cast<const QPointingDevice *>(device)) { + auto devPriv = QPointingDevicePrivate::get(const_cast<QPointingDevice *>(pointingDevice)); + for (auto epd : devPriv->activePoints.values()) { + if (!epd.exclusiveGrabber.isNull()) { + bool relevant = false; + if (QQuickItem *item = qmlobject_cast<QQuickItem *>(epd.exclusiveGrabber.data())) + relevant = (item->window() == q); + else if (QQuickPointerHandler *handler = qmlobject_cast<QQuickPointerHandler *>(epd.exclusiveGrabber.data())) + relevant = (handler->parentItem()->window() == q); + if (relevant) + devPriv->setExclusiveGrabber(nullptr, epd.eventPoint, nullptr); + } + // For now, we don't clearPassiveGrabbers(), just in case passive grabs + // can be useful to keep monitoring the mouse even after window deactivation. + } + } + } +} + bool QQuickWindowPrivate::allUpdatedPointsAccepted(const QPointerEvent *ev) { for (auto &point : ev->points()) { diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 18a43487c1..6e4d24da85 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -187,6 +187,7 @@ public: bool compressTouchEvent(QTouchEvent *); void flushFrameSynchronousEvents(); void deliverDelayedTouchEvent(); + void handleWindowDeactivate(); // utility functions that used to be in QQuickPointerEvent et al. bool allUpdatedPointsAccepted(const QPointerEvent *ev); |