aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickitem.cpp11
-rw-r--r--src/quick/items/qquickitem.h1
-rw-r--r--src/quick/items/qquickmousearea.cpp6
-rw-r--r--src/quick/items/qquickmousearea_p.h1
-rw-r--r--src/quick/items/qquickwindow.cpp40
-rw-r--r--src/quick/items/qquickwindow_p.h1
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);