diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-08-19 17:47:38 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-08-19 23:49:22 +0000 |
commit | 91d53ba22e1de1c81e9f082517fd81d711c69909 (patch) | |
tree | beb661db3472814aaef02962b89bd5e897c06114 /src/plugins/platforms/cocoa/qnsview_mouse.mm | |
parent | e0e64df0de0731545a8631ea69ffb52c20bfaa56 (diff) |
macOS: close popups on mousedown within the window frame
On macOS, we close active popups when handling mouse-down events in the
NSView, but not for such events in the window frame. This allows users
to close a window that has a context menu open via the window's close
button, which then leaves open popups behind.
Factor the popup-closing code out into a dedicated method that we can
call from within the NSWindow::sendEvent implementation for mouse down
events.
Fixes: QTBUG-30522
Change-Id: I9c354efc449cfefff3ed84fa34b1cd8a0da3b4a7
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 70b94eea10d7af83cced09296755a8af28e167b5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/plugins/platforms/cocoa/qnsview_mouse.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_mouse.mm | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index d00cfb7886..2a95d409a9 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -176,6 +176,38 @@ QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons, button, eventType); } + +- (bool)closePopups:(NSEvent *)theEvent +{ + QList<QCocoaWindow *> *popups = QCocoaIntegration::instance()->popupWindowStack(); + if (!popups->isEmpty()) { + // Check if the click is outside all popups. + bool inside = false; + QPointF qtScreenPoint = QCocoaScreen::mapFromNative([self screenMousePoint:theEvent]); + for (QList<QCocoaWindow *>::const_iterator it = popups->begin(); it != popups->end(); ++it) { + if ((*it)->geometry().contains(qtScreenPoint.toPoint())) { + inside = true; + break; + } + } + // Close the popups if the click was outside. + if (!inside) { + bool selfClosed = false; + Qt::WindowType type = QCocoaIntegration::instance()->activePopupWindow()->window()->type(); + while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) { + selfClosed = self == popup->view(); + QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(popup->window()); + if (!m_platformWindow) + return true; // Bail out if window was destroyed + } + // Consume the mouse event when closing the popup, except for tool tips + // were it's expected that the event is processed normally. + if (type != Qt::ToolTip || selfClosed) + return true; + } + } + return false; +} @end @implementation QNSView (Mouse) @@ -379,33 +411,8 @@ // that particular poup type (for example context menus). However, Qt expects // that plain popup QWindows will also be closed, so we implement the logic // here as well. - QList<QCocoaWindow *> *popups = QCocoaIntegration::instance()->popupWindowStack(); - if (!popups->isEmpty()) { - // Check if the click is outside all popups. - bool inside = false; - QPointF qtScreenPoint = QCocoaScreen::mapFromNative([self screenMousePoint:theEvent]); - for (QList<QCocoaWindow *>::const_iterator it = popups->begin(); it != popups->end(); ++it) { - if ((*it)->geometry().contains(qtScreenPoint.toPoint())) { - inside = true; - break; - } - } - // Close the popups if the click was outside. - if (!inside) { - bool selfClosed = false; - Qt::WindowType type = QCocoaIntegration::instance()->activePopupWindow()->window()->type(); - while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) { - selfClosed = self == popup->view(); - QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(popup->window()); - if (!m_platformWindow) - return; // Bail out if window was destroyed - } - // Consume the mouse event when closing the popup, except for tool tips - // were it's expected that the event is processed normally. - if (type != Qt::ToolTip || selfClosed) - return; - } - } + if ([self closePopups:theEvent]) + return; QPointF qtWindowPoint; QPointF qtScreenPoint; |