From d2848809a2d100956761851e456796665601960b Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 27 Sep 2019 12:14:18 +0100 Subject: [PATCH] Implement auto generate standard osx app menu items. --- native/Avalonia.Native/src/OSX/common.h | 2 +- native/Avalonia.Native/src/OSX/main.mm | 14 +++++-- native/Avalonia.Native/src/OSX/menu.mm | 49 ++++++++++++++++++++++++- samples/ControlCatalog/App.xaml | 15 -------- 4 files changed, 58 insertions(+), 22 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h index c91f562989..10534dea26 100644 --- a/native/Avalonia.Native/src/OSX/common.h +++ b/native/Avalonia.Native/src/OSX/common.h @@ -22,7 +22,7 @@ extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* extern IAvnAppMenu* CreateAppMenu(); extern IAvnAppMenuItem* CreateAppMenuItem(); extern IAvnAppMenuItem* CreateAppMenuItemSeperator(); -extern void SetAppMenu (IAvnAppMenu* appMenu); +extern void SetAppMenu (NSString* appName, IAvnAppMenu* appMenu); extern IAvnAppMenu* GetAppMenu (); extern NSMenuItem* GetAppMenuItem (); diff --git a/native/Avalonia.Native/src/OSX/main.mm b/native/Avalonia.Native/src/OSX/main.mm index 1a46e495ba..9418782fd1 100644 --- a/native/Avalonia.Native/src/OSX/main.mm +++ b/native/Avalonia.Native/src/OSX/main.mm @@ -5,10 +5,16 @@ #define COM_GUIDS_MATERIALIZE #include "common.h" +static NSString* s_appTitle = @"Avalonia"; + // Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -void SetProcessName(CFStringRef process_name) { +void SetProcessName(NSString* appTitle) { + s_appTitle = appTitle; + + CFStringRef process_name = (__bridge CFStringRef)appTitle; + if (!process_name || CFStringGetLength(process_name) == 0) { //NOTREACHED() << "SetProcessName given bad name."; return; @@ -108,8 +114,8 @@ public: [[NSProcessInfo processInfo] setProcessName:appTitle]; - CFStringRef titleRef = (__bridge CFStringRef)appTitle; - SetProcessName(titleRef); + + SetProcessName(appTitle); return S_OK; } @@ -245,7 +251,7 @@ public: virtual HRESULT SetAppMenu (IAvnAppMenu* appMenu) override { - ::SetAppMenu(appMenu); + ::SetAppMenu(s_appTitle, appMenu); return S_OK; } diff --git a/native/Avalonia.Native/src/OSX/menu.mm b/native/Avalonia.Native/src/OSX/menu.mm index 397d587ec3..84dc80806a 100644 --- a/native/Avalonia.Native/src/OSX/menu.mm +++ b/native/Avalonia.Native/src/OSX/menu.mm @@ -209,15 +209,60 @@ extern IAvnAppMenuItem* CreateAppMenuItemSeperator() static IAvnAppMenu* s_appMenu = nullptr; static NSMenuItem* s_appMenuItem = nullptr; -extern void SetAppMenu (IAvnAppMenu* appMenu) +extern void SetAppMenu (NSString* appName, IAvnAppMenu* menu) { - s_appMenu = appMenu; + s_appMenu = menu; if(s_appMenu != nullptr) { auto nativeMenu = dynamic_cast(s_appMenu); s_appMenuItem = [nativeMenu->GetNative() itemAtIndex:0]; + + auto appMenu = [s_appMenuItem submenu]; + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Services item and menu + auto servicesItem = [[NSMenuItem alloc] init]; + servicesItem.title = @"Services"; + NSMenu *servicesMenu = [[NSMenu alloc] initWithTitle:@"Services"]; + servicesItem.submenu = servicesMenu; + [NSApplication sharedApplication].servicesMenu = servicesMenu; + [appMenu addItem:servicesItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Hide Application + auto hideItem = [[NSMenuItem alloc] initWithTitle:[@"Hide " stringByAppendingString:appName] action:@selector(hide:) keyEquivalent:@"h"]; + //hideItem.target = self; + [appMenu addItem:hideItem]; + + // Hide Others + auto hideAllOthersItem = [[NSMenuItem alloc] initWithTitle:@"Hide Others" + action:@selector(hideOtherApplications:) + keyEquivalent:@"h"]; + //hideAllOthersItem.target = self; + hideAllOthersItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagOption; + [appMenu addItem:hideAllOthersItem]; + + // Show All + auto showAllItem = [[NSMenuItem alloc] initWithTitle:@"Show All" + action:@selector(unhideAllApplications:) + keyEquivalent:@""]; + //showAllItem.target = self; + [appMenu addItem:showAllItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Quit Application + auto quitItem = [[NSMenuItem alloc] init]; + quitItem.title = [@"Quit " stringByAppendingString:appName]; + quitItem.keyEquivalent = @"q"; + // This will remain true until synced with a QCocoaMenuItem. + // This way, we will always have a functional Quit menu item + // even if no QAction is added. + quitItem.action = @selector(terminate:); + [appMenu addItem:quitItem]; } else { diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml index a82996773f..726a3c915e 100644 --- a/samples/ControlCatalog/App.xaml +++ b/samples/ControlCatalog/App.xaml @@ -27,21 +27,6 @@ - - - - - - - - - - - - - - -