diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm | 83 |
1 files changed, 64 insertions, 19 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index a94e0dc517..7601fb7e17 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -73,9 +73,12 @@ #import "qcocoaapplicationdelegate.h" -#import "qnswindowdelegate.h" -#import "qcocoamenuloader.h" #include "qcocoaintegration.h" +#include "qcocoamenu.h" +#include "qcocoamenuloader.h" +#include "qcocoamenuitem.h" +#include "qcocoansmenu.h" + #include <qevent.h> #include <qurl.h> #include <qdebug.h> @@ -86,7 +89,11 @@ QT_USE_NAMESPACE -@implementation QCocoaApplicationDelegate +@implementation QCocoaApplicationDelegate { + bool startedQuit; + NSObject <NSApplicationDelegate> *reflectionDelegate; + bool inLaunch; +} + (instancetype)sharedDelegate { @@ -102,7 +109,7 @@ QT_USE_NAMESPACE return shared; } -- (id)init +- (instancetype)init { self = [super init]; if (self) { @@ -125,7 +132,7 @@ QT_USE_NAMESPACE - (void)dealloc { - [dockMenu release]; + [_dockMenu release]; if (reflectionDelegate) { [[NSApplication sharedApplication] setDelegate:reflectionDelegate]; [reflectionDelegate release]; @@ -135,23 +142,16 @@ QT_USE_NAMESPACE [super dealloc]; } -- (void)setDockMenu:(NSMenu*)newMenu -{ - [newMenu retain]; - [dockMenu release]; - dockMenu = newMenu; -} - - (NSMenu *)applicationDockMenu:(NSApplication *)sender { Q_UNUSED(sender); // Manually invoke the delegate's -menuWillOpen: method. // See QTBUG-39604 (and its fix) for details. - [[dockMenu delegate] menuWillOpen:dockMenu]; - return [[dockMenu retain] autorelease]; + [self.dockMenu.delegate menuWillOpen:self.dockMenu]; + return [[self.dockMenu retain] autorelease]; } -- (BOOL) canQuit +- (BOOL)canQuit { [[NSApp mainMenu] cancelTracking]; @@ -219,7 +219,7 @@ QT_USE_NAMESPACE return NSTerminateCancel; } -- (void) applicationWillFinishLaunching:(NSNotification *)notification +- (void)applicationWillFinishLaunching:(NSNotification *)notification { Q_UNUSED(notification); @@ -249,14 +249,14 @@ QT_USE_NAMESPACE } // called by QCocoaIntegration's destructor before resetting the application delegate to nil -- (void) removeAppleEventHandlers +- (void)removeAppleEventHandlers { NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager]; [eventManager removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEQuitApplication]; [eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL]; } -- (bool) inLaunch +- (bool)inLaunch { return inLaunch; } @@ -440,3 +440,48 @@ QT_USE_NAMESPACE } @end + +@implementation QCocoaApplicationDelegate (Menus) + +- (BOOL)validateMenuItem:(NSMenuItem*)item +{ + auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(item); + if (!nativeItem) + return item.enabled; // FIXME Test with with Qt as plugin or embedded QWindow. + + auto *platformItem = nativeItem.platformMenuItem; + if (!platformItem) // Try a bit harder with orphan menu itens + return item.hasSubmenu || (item.enabled && (item.action != @selector(qt_itemFired:))); + + // Menu-holding items are always enabled, as it's conventional in Cocoa + if (platformItem->menu()) + return YES; + + return platformItem->isEnabled(); +} + +@end + +@implementation QCocoaApplicationDelegate (MenuAPI) + +- (void)qt_itemFired:(QCocoaNSMenuItem *)item +{ + if (item.hasSubmenu) + return; + + auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(item); + Q_ASSERT_X(nativeItem, qPrintable(__FUNCTION__), "Triggered menu item is not a QCocoaNSMenuItem."); + auto *platformItem = nativeItem.platformMenuItem; + // Menu-holding items also get a target to play nicely + // with NSMenuValidation but should not trigger. + if (!platformItem || platformItem->menu()) + return; + + QScopedScopeLevelCounter scopeLevelCounter(QGuiApplicationPrivate::instance()->threadData); + QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers:[NSEvent modifierFlags]]; + + static QMetaMethod activatedSignal = QMetaMethod::fromSignal(&QCocoaMenuItem::activated); + activatedSignal.invoke(platformItem, Qt::QueuedConnection); +} + +@end |