From 48defe41e1f6fb38800675922289dd7364fad8af Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 17 Apr 2018 15:36:09 -0700 Subject: Cocoa Menus: Allow separators in app menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We extend QCocoaNSMenuItem with separator items capabilities and use it as any other custom item in the app menu. Addition and removal of items in the app menu remains very basic because that menu doesn't exist as such. Instead, it's hinted through the QAction's menu role. Change-Id: Ia13bfcc008c75e49fd21705d2528da5a85ed1c73 Task-number: QTBUG-63756 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoamenu.mm | 2 +- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 12 +++++++----- src/plugins/platforms/cocoa/qcocoamenuloader.mm | 13 ++++++++----- src/plugins/platforms/cocoa/qcocoansmenu.h | 1 + src/plugins/platforms/cocoa/qcocoansmenu.mm | 13 +++++++++++++ 5 files changed, 30 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 75d5ea2dd8..ea28c305d6 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -205,7 +205,7 @@ void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem) QCocoaMenuItem *QCocoaMenu::itemOrNull(int index) const { if ((index < 0) || (index >= m_menuItems.size())) - return 0; + return nullptr; return m_menuItems.at(index); } diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index bd8cab9b23..ee70e059a1 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -219,12 +219,11 @@ void QCocoaMenuItem::setNativeContents(WId item) NSMenuItem *QCocoaMenuItem::sync() { - if (m_isSeparator != [m_native isSeparatorItem]) { + if (m_isSeparator != m_native.separatorItem) { [m_native release]; - if (m_isSeparator) { - m_native = [[NSMenuItem separatorItem] retain]; - [m_native setTag:reinterpret_cast(this)]; - } else + if (m_isSeparator) + m_native = [[QCocoaNSMenuItem separatorItemWithPlatformMenuItem:this] retain]; + else m_native = nil; } @@ -435,6 +434,9 @@ void QCocoaMenuItem::setIconSize(int size) void QCocoaMenuItem::resolveTargetAction() { + if (m_native.separatorItem) + return; + // Some items created by QCocoaMenuLoader are not // instances of QCocoaNSMenuItem and have their // target/action set as Interface Builder would. diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index d4009cf63b..9bd6108d0d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -272,18 +272,21 @@ - (NSMenuItem *)appSpecificMenuItem:(QCocoaMenuItem *)platformItem { + // No reason to create the item if it already exists. for (NSMenuItem *item in appMenu.itemArray) if ([item isMemberOfClass:[QCocoaNSMenuItem class]] - && static_cast(item).platformMenuItem == platformItem) { - // No reason to create the item if it already exists. + && static_cast(item).platformMenuItem == platformItem) return [[item retain] autorelease]; - } // Create an App-Specific menu item, insert it into the menu and return // it as an autorelease item. - QCocoaNSMenuItem *item = [[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:platformItem]; + QCocoaNSMenuItem *item; + if (platformItem->isSeparator()) + item = [[QCocoaNSMenuItem separatorItemWithPlatformMenuItem:platformItem] retain]; + else + item = [[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:platformItem]; - NSInteger location = [appMenu indexOfItem:lastAppSpecificItem]; + const auto location = [appMenu indexOfItem:lastAppSpecificItem]; if (!lastAppSpecificItem.separatorItem) [lastAppSpecificItem release]; diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.h b/src/plugins/platforms/cocoa/qcocoansmenu.h index 6988c2a084..a4af56fa02 100644 --- a/src/plugins/platforms/cocoa/qcocoansmenu.h +++ b/src/plugins/platforms/cocoa/qcocoansmenu.h @@ -80,6 +80,7 @@ QT_FORWARD_DECLARE_CLASS(QCocoaMenuItem); @property (nonatomic) QCocoaMenuItem *platformMenuItem; ++ (instancetype)separatorItemWithPlatformMenuItem:(QCocoaMenuItem *)menuItem; - (instancetype)initWithPlatformMenuItem:(QCocoaMenuItem *)menuItem; @end diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.mm b/src/plugins/platforms/cocoa/qcocoansmenu.mm index 99c56f9191..c082158313 100644 --- a/src/plugins/platforms/cocoa/qcocoansmenu.mm +++ b/src/plugins/platforms/cocoa/qcocoansmenu.mm @@ -97,6 +97,19 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string) QPointer _platformMenuItem; } ++ (instancetype)separatorItemWithPlatformMenuItem:(QCocoaMenuItem *)menuItem +{ + // Safe because +[NSMenuItem separatorItem] invokes [[self alloc] init] + auto *item = static_cast([self separatorItem]); + Q_ASSERT_X([item isMemberOfClass:[QCocoaNSMenuItem class]], + qPrintable(__FUNCTION__), + "Did +[NSMenuItem separatorItem] not invoke [[self alloc] init]?"); + if (item) + item.platformMenuItem = menuItem; + + return item; +} + - (instancetype)initWithPlatformMenuItem:(QCocoaMenuItem *)menuItem { if ((self = [super initWithTitle:@"" action:nil keyEquivalent:@""])) { -- cgit v1.2.3