summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qnswindow.mm
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-09-08 14:57:37 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-09-13 19:14:29 +0200
commit73753ee3af58456bfccba8281bda19228aa98bd1 (patch)
treecd95895a31f550b4f8a18e443299f5fff038e74a /src/plugins/platforms/cocoa/qnswindow.mm
parent1093562d08f325bbbdcd60627eadae535779e376 (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.mm12
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];
}