diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm index abee622e65f..aa224682d50 100644 --- a/src/plugins/platforms/cocoa/qnsview_keys.mm +++ b/src/plugins/platforms/cocoa/qnsview_keys.mm @@ -250,6 +250,25 @@ static bool sendAsShortcut(const KeyEvent &keyEvent, QWindow *window) } } +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000) +- (void)contextMenuKeyDown:(NSEvent *)nsevent +{ + qCDebug(lcQpaKeys) << "Handling context menu key down for" << nsevent; + + if ([self isTransparentForUserInput]) + return [super contextMenuKeyDown:nsevent]; + + if ([self handleKeyEvent:nsevent]) { + qCDebug(lcQpaKeys) << "Accepted context menu event as regular key down"; + m_acceptedKeyDowns.insert(nsevent.keyCode); + } else { + // Forward up the responder chain to trigger default system + // behavior of calling showContextMenuForSelection. + [super contextMenuKeyDown:nsevent]; + } +} +#endif + @end // ------------------------------------------------------------------------- diff --git a/src/plugins/platforms/cocoa/qnsview_menus.mm b/src/plugins/platforms/cocoa/qnsview_menus.mm index 28409369756..9c3121ab387 100644 --- a/src/plugins/platforms/cocoa/qnsview_menus.mm +++ b/src/plugins/platforms/cocoa/qnsview_menus.mm @@ -39,6 +39,43 @@ return [super supplementalTargetForAction:action sender:sender]; } +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000) +- (void)showContextMenuForSelection:(id)sender +{ + QPointF windowPoint; + QPointF screenPoint; + [self convertFromScreen:[NSEvent mouseLocation] + toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + + auto *keyMapper = QCocoaIntegration::instance()->keyMapper(); + auto keyboardModifiers = keyMapper->queryKeyboardModifiers(); + + // We currently propagate this as QContextMenuEvent::Reason::Keyboard, + // but we can also get here via an accessibility ShowMenu action, in + // which case QContextMenuEvent::Reason::Other reason might fit better. + // Unfortunately QWSI/QGuiApplication/QWidgetWindow doesn't handle that + // yet. FIXME: Teach other parts of Qt about QContextMenuEvent::Other. + const bool mouseTriggered = false; + + qCDebug(lcQpaMenus) << "Initiating context menu at" + << windowPoint.toPoint() << "in" << m_platformWindow + << "with" << keyboardModifiers; + + bool accepted = QWindowSystemInterface::handleContextMenuEvent< + QWindowSystemInterface::SynchronousDelivery>( + m_platformWindow->window(), mouseTriggered, + windowPoint.toPoint(), screenPoint.toPoint(), + keyboardModifiers); + + qCDebug(lcQpaMenus) << "Context menu event accepted =" << accepted; + + // If the view does not support a context menu we should pass + // the request up the responder chain. + if (!accepted) + [[self nextResponder] tryToPerform:_cmd with:sender]; +} +#endif + @end @interface QNSViewMenuHelper ()