diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-09-08 14:57:37 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-09-13 19:14:29 +0200 |
commit | 73753ee3af58456bfccba8281bda19228aa98bd1 (patch) | |
tree | cd95895a31f550b4f8a18e443299f5fff038e74a /src/plugins/platforms/cocoa/qnswindow.mm | |
parent | 1093562d08f325bbbdcd60627eadae535779e376 (diff) |
macOS: Don't close popups in Cocoa plugin for most mouse events
QWidget and QApplication handle popup closing for most events at the
right time for the Qt-internal state logic. On other platforms popup
QWindows are never closed automatically when clicking outside.
So don't close any popups in the Cocoa plugin either, and let the Qt
logic take care of it. This ensures that window activation is done at
the right time, that Qt's modal popup stack is consistent, and that
mouse replay for events closing a popup works.
There are however two exceptions: mouse events in the window frame don't
produce a QMouseEvent for Qt; and mouse events in a modally blocked (by
Cocoa) window don't reach Qt at all. For those case, the logic in QWidget
and QApplication is not enough.
For the former, leave the change introduced in 70b94eea10d7af83cced092967
to explicitly close popups for LMB down in the frame. This still needs
to happen before the event is delivered.
For the latter case, deliver the event explicitly to Qt when we discover
that the target window is modally blocked while a popup is active. The
handleMouseEvent implementation then takes care of the redirect to the
active popup, and Qt will further respect the modal stack in the
QApplication::isWindowBlocked implementation.
Change-Id: I578eb5e6aebc897a0ff1f69bc5c53bcaa05d138d
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa/qnswindow.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qnswindow.mm | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 9656d0e970..1fa11e2789 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -45,6 +45,7 @@ #include "qcocoawindow.h" #include "qcocoahelpers.h" #include "qcocoaeventdispatcher.h" +#include "qcocoaintegration.h" #include <qpa/qwindowsysteminterface.h> #include <qoperatingsystemversion.h> @@ -370,6 +371,17 @@ OSStatus CGSClearWindowTags(const CGSConnectionID, const CGSWindowID, int *, int if (!m_platformWindow) return; // Platform window went away while processing event + // Cocoa will not deliver mouse events to a window that is modally blocked (by Cocoa, + // not Qt). However, an active popup is expected to grab any mouse event within the + // application, so we need to handle those explicitly and trust Qt's isWindowBlocked + // implementation to eat events that shouldn't be delivered anyway. + if (isMouseEvent(theEvent) && QCocoaIntegration::instance()->activePopupWindow() + && QGuiApplicationPrivate::instance()->isWindowBlocked(m_platformWindow->window(), nullptr)) { + qCDebug(lcQpaWindow) << "Mouse event over modally blocked window" << m_platformWindow->window() + << "while popup" << QCocoaIntegration::instance()->activePopupWindow() + << "is open - redirecting"; + [qnsview_cast(m_platformWindow->view()) handleMouseEvent:theEvent]; + } if (m_platformWindow->frameStrutEventsEnabled() && mouseEventInFrameStrut) [qnsview_cast(m_platformWindow->view()) handleFrameStrutMouseEvent:theEvent]; } |