mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: use xib file to construct macOS Menu (#20670)
* fix: use xib file to construct macOS Menu * add nib files back to zip manifests * address final review comments
This commit is contained in:
@@ -534,7 +534,7 @@ void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopStartCommon() {
|
||||
#if defined(OS_MACOSX)
|
||||
InitializeEmptyApplicationMenu();
|
||||
InitializeMainNib();
|
||||
RegisterURLHandler();
|
||||
#endif
|
||||
media::SetLocalizedStringProvider(MediaStringProvider);
|
||||
|
||||
@@ -106,7 +106,7 @@ class AtomBrowserMainParts : public content::BrowserMainParts {
|
||||
#if defined(OS_MACOSX)
|
||||
void FreeAppDelegate();
|
||||
void RegisterURLHandler();
|
||||
void InitializeEmptyApplicationMenu();
|
||||
void InitializeMainNib();
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
||||
@@ -4,56 +4,16 @@
|
||||
|
||||
#include "shell/browser/atom_browser_main_parts.h"
|
||||
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "shell/browser/atom_paths.h"
|
||||
#import "shell/browser/mac/atom_application.h"
|
||||
#include "shell/browser/mac/atom_application_delegate.h"
|
||||
#include "ui/base/l10n/l10n_util_mac.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
base::scoped_nsobject<NSMenuItem> CreateMenuItem(NSString* title,
|
||||
SEL action,
|
||||
NSString* key_equivalent) {
|
||||
return base::scoped_nsobject<NSMenuItem>([[NSMenuItem alloc]
|
||||
initWithTitle:title
|
||||
action:action
|
||||
keyEquivalent:key_equivalent]);
|
||||
}
|
||||
|
||||
// The App Menu refers to the dropdown titled "Electron".
|
||||
base::scoped_nsobject<NSMenu> BuildAppMenu() {
|
||||
// The title is not used, as the title will always be the name of the App.
|
||||
base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
|
||||
|
||||
NSString* app_name = [[[NSBundle mainBundle] infoDictionary]
|
||||
objectForKey:(id)kCFBundleNameKey];
|
||||
|
||||
base::scoped_nsobject<NSMenuItem> item =
|
||||
CreateMenuItem([NSString stringWithFormat:@"Quit %@", app_name],
|
||||
@selector(terminate:), @"q");
|
||||
[menu addItem:item];
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
base::scoped_nsobject<NSMenu> BuildEmptyMainMenu() {
|
||||
base::scoped_nsobject<NSMenu> main_menu([[NSMenu alloc] initWithTitle:@""]);
|
||||
|
||||
using Builder = base::scoped_nsobject<NSMenu> (*)();
|
||||
static const Builder kBuilderFuncs[] = {&BuildAppMenu};
|
||||
for (auto* builder : kBuilderFuncs) {
|
||||
NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:@""
|
||||
action:NULL
|
||||
keyEquivalent:@""] autorelease];
|
||||
item.submenu = builder();
|
||||
[main_menu addItem:item];
|
||||
}
|
||||
return main_menu;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
// Set our own application delegate.
|
||||
AtomApplicationDelegate* delegate = [[AtomApplicationDelegate alloc] init];
|
||||
@@ -77,9 +37,37 @@ void AtomBrowserMainParts::RegisterURLHandler() {
|
||||
[[AtomApplication sharedApplication] registerURLHandler];
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::InitializeEmptyApplicationMenu() {
|
||||
base::scoped_nsobject<NSMenu> main_menu = BuildEmptyMainMenu();
|
||||
[[NSApplication sharedApplication] setMainMenu:main_menu];
|
||||
// Replicates NSApplicationMain, but doesn't start a run loop.
|
||||
void AtomBrowserMainParts::InitializeMainNib() {
|
||||
auto infoDictionary = base::mac::OuterBundle().infoDictionary;
|
||||
|
||||
auto principalClass =
|
||||
NSClassFromString([infoDictionary objectForKey:@"NSPrincipalClass"]);
|
||||
auto application = [principalClass sharedApplication];
|
||||
|
||||
NSString* mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"];
|
||||
|
||||
NSNib* mainNib;
|
||||
|
||||
@try {
|
||||
mainNib = [[NSNib alloc] initWithNibNamed:mainNibName
|
||||
bundle:base::mac::FrameworkBundle()];
|
||||
// Handle failure of initWithNibNamed on SMB shares
|
||||
// TODO(codebytere): Remove when
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=932935 is fixed
|
||||
} @catch (NSException* exception) {
|
||||
NSString* nibPath =
|
||||
[NSString stringWithFormat:@"Resources/%@.nib", mainNibName];
|
||||
nibPath = [base::mac::FrameworkBundle().bundlePath
|
||||
stringByAppendingPathComponent:nibPath];
|
||||
|
||||
NSData* data = [NSData dataWithContentsOfFile:nibPath];
|
||||
mainNib = [[NSNib alloc] initWithNibData:data
|
||||
bundle:base::mac::FrameworkBundle()];
|
||||
}
|
||||
|
||||
[mainNib instantiateWithOwner:application topLevelObjects:nil];
|
||||
[mainNib release];
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.10.0</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>AtomApplication</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
|
||||
@@ -128,11 +128,9 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
|
||||
// Locate & retain the recent documents menu item
|
||||
if (!recentDocumentsMenuItem_) {
|
||||
base::string16 title = base::ASCIIToUTF16("Open Recent");
|
||||
NSString* openTitle = l10n_util::FixUpWindowsStyleLabel(title);
|
||||
|
||||
recentDocumentsMenuItem_.reset([[[[[NSApp mainMenu]
|
||||
itemWithTitle:@"Electron"] submenu] itemWithTitle:openTitle] retain]);
|
||||
recentDocumentsMenuItem_.reset(
|
||||
[[[[[NSApp mainMenu] itemWithTitle:@"Electron"] submenu]
|
||||
itemWithTitle:@"Open Recent"] retain]);
|
||||
}
|
||||
|
||||
model_ = model;
|
||||
@@ -195,17 +193,8 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
// Replaces the item's submenu instance with the singleton recent documents
|
||||
// menu. Previously replaced menu items will be recovered.
|
||||
- (void)replaceSubmenuShowingRecentDocuments:(NSMenuItem*)item {
|
||||
NSMenu* recentDocumentsMenu = [recentDocumentsMenuItem_ submenu];
|
||||
if (!recentDocumentsMenu) {
|
||||
base::string16 title = base::ASCIIToUTF16("Clear Menu");
|
||||
NSString* clearTitle = l10n_util::FixUpWindowsStyleLabel(title);
|
||||
recentDocumentsMenu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||
[recentDocumentsMenu
|
||||
addItem:[[[NSMenuItem alloc]
|
||||
initWithTitle:clearTitle
|
||||
action:@selector(clearRecentDocuments:)
|
||||
keyEquivalent:@""] autorelease]];
|
||||
}
|
||||
NSMenu* recentDocumentsMenu =
|
||||
[[[recentDocumentsMenuItem_ submenu] retain] autorelease];
|
||||
|
||||
// Remove menu items in recent documents back to swap menu
|
||||
[self moveMenuItems:recentDocumentsMenu to:recentDocumentsMenuSwap_];
|
||||
|
||||
Reference in New Issue
Block a user