@@ -90,7 +90,6 @@ bool MenuHasVisibleItems(const electron::ElectronMenuModel* model) {
9090// "(empty)" into the submenu. Matches Windows behavior.
9191NSMenu * MakeEmptySubmenu () {
9292 NSMenu * submenu = [[NSMenu alloc ] initWithTitle: @" " ];
93- submenu.autoenablesItems = NO ;
9493 NSString * empty_menu_title =
9594 l10n_util::GetNSString (IDS_APP_MENU_EMPTY_SUBMENU);
9695
@@ -232,9 +231,6 @@ - (void)cancel {
232231// be invoked recursively.
233232- (NSMenu *)menuFromModel : (electron::ElectronMenuModel*)model {
234233 NSMenu * menu = [[NSMenu alloc ] initWithTitle: @" " ];
235- // We manually manage enabled/disabled/hidden state for every item,
236- // including Cocoa role-based selectors.
237- menu.autoenablesItems = NO ;
238234
239235 const int count = model->GetItemCount ();
240236 for (int index = 0 ; index < count; index++) {
@@ -244,7 +240,6 @@ - (NSMenu*)menuFromModel:(electron::ElectronMenuModel*)model {
244240 [self addItemToMenu: menu atIndex: index fromModel: model];
245241 }
246242
247- menu.delegate = self;
248243 return menu;
249244}
250245
@@ -299,11 +294,9 @@ - (NSMenu*)createShareMenuForItem:(const SharingItem&)item {
299294 if ([items count ] == 0 )
300295 return MakeEmptySubmenu ();
301296 NSMenu * menu = [[NSMenu alloc ] init ];
302- menu.autoenablesItems = NO ;
303297 NSArray * services = [NSSharingService sharingServicesForItems: items];
304298 for (NSSharingService * service in services)
305299 [menu addItem: [self menuItemForService: service withItems: items]];
306- [menu setDelegate: self ];
307300 return menu;
308301}
309302
@@ -360,22 +353,27 @@ - (NSMenuItem*)makeMenuItemForIndex:(NSInteger)index
360353 std::u16string title = u" Services" ;
361354 NSString * sub_label = l10n_util::FixUpWindowsStyleLabel (title);
362355
363- item. target = nil ;
364- item. action = nil ;
356+ [ item setTarget: nil ] ;
357+ [ item setAction: nil ] ;
365358 NSMenu * submenu = [[NSMenu alloc ] initWithTitle: sub_label];
366- item. submenu = submenu;
359+ [ item setSubmenu: submenu] ;
367360 [NSApp setServicesMenu: submenu];
368361 } else if (role == u" sharemenu" ) {
369362 SharingItem sharing_item;
370363 model->GetSharingItemAt (index, &sharing_item);
371- item. target = nil ;
372- item. action = nil ;
364+ [ item setTarget: nil ] ;
365+ [ item setAction: nil ] ;
373366 [item setSubmenu: [self createShareMenuForItem: sharing_item]];
374367 } else if (type == electron::ElectronMenuModel::TYPE_SUBMENU &&
375368 model->IsVisibleAt (index)) {
369+ // We need to specifically check that the submenu top-level item has been
370+ // enabled as it's not validated by validateUserInterfaceItem
371+ if (!model->IsEnabledAt (index))
372+ [item setEnabled: NO ];
373+
376374 // Recursively build a submenu from the sub-model at this index.
377- item. target = nil ;
378- item. action = nil ;
375+ [ item setTarget: nil ] ;
376+ [ item setAction: nil ] ;
379377 electron::ElectronMenuModel* submenuModel =
380378 static_cast <electron::ElectronMenuModel*>(
381379 model->GetSubmenuModelAt (index));
@@ -390,12 +388,8 @@ - (NSMenuItem*)makeMenuItemForIndex:(NSInteger)index
390388 }
391389 }
392390
393- submenu.title = item.title ;
394- item.submenu = submenu;
395- item.tag = index;
396- item.representedObject =
397- [WeakPtrToElectronMenuModelAsNSObject weakPtrForModel: model];
398- submenu.delegate = self;
391+ [submenu setTitle: [item title ]];
392+ [item setSubmenu: submenu];
399393
400394 // Set submenu's role.
401395 if ((role == u" window" || role == u" windowmenu" ) && [submenu numberOfItems ])
@@ -410,9 +404,9 @@ - (NSMenuItem*)makeMenuItemForIndex:(NSInteger)index
410404 // the model so hierarchical menus check the correct index in the correct
411405 // model. Setting the target to |self| allows this class to participate
412406 // in validation of the menu items.
413- item. tag = index;
414- item. representedObject =
415- [WeakPtrToElectronMenuModelAsNSObject weakPtrForModel: model];
407+ [ item setTag: index] ;
408+ [ item setRepresentedObject: [WeakPtrToElectronMenuModelAsNSObject
409+ weakPtrForModel: model] ];
416410 ui::Accelerator accelerator;
417411 if (model->GetAcceleratorAtWithParams (index, useDefaultAccelerator_,
418412 &accelerator)) {
@@ -440,20 +434,20 @@ - (NSMenuItem*)makeMenuItemForIndex:(NSInteger)index
440434 ui::MacKeyCodeForWindowsKeyCode (accelerator.key_code (), modifier_mask,
441435 nullptr , &character);
442436 }
443- item. keyEquivalent = [NSString stringWithFormat: @" %C " , character];
444- item. keyEquivalentModifierMask = modifier_mask;
437+ [ item setKeyEquivalent: [NSString stringWithFormat: @" %C " , character] ];
438+ [ item setKeyEquivalentModifierMask: modifier_mask] ;
445439 }
446440
447441 [(id )item
448442 setAllowsKeyEquivalentWhenHidden: (model->WorksWhenHiddenAt (index))];
449443
450444 // Set menu item's role.
451- item. target = self;
445+ [ item setTarget: self ] ;
452446 if (!role.empty ()) {
453447 for (const Role& pair : kRolesMap ) {
454448 if (role == base::ASCIIToUTF16 (pair.role )) {
455- item. target = nil ;
456- item. action = pair.selector ;
449+ [ item setTarget: nil ] ;
450+ [ item setAction: pair.selector] ;
457451 break ;
458452 }
459453 }
@@ -463,37 +457,6 @@ - (NSMenuItem*)makeMenuItemForIndex:(NSInteger)index
463457 return item;
464458}
465459
466- - (void )applyStateToMenuItem : (NSMenuItem *)item {
467- id represented = item.representedObject ;
468- if (!represented)
469- return ;
470-
471- electron::ElectronMenuModel* model =
472- [WeakPtrToElectronMenuModelAsNSObject getFrom: represented];
473- if (!model)
474- return ;
475-
476- NSInteger index = item.tag ;
477- int count = model->GetItemCount ();
478- if (index < 0 || index >= count)
479- return ;
480-
481- item.hidden = !model->IsVisibleAt (index);
482- item.enabled = model->IsEnabledAt (index);
483- item.state = model->IsItemCheckedAt (index) ? NSControlStateValueOn
484- : NSControlStateValueOff ;
485- }
486-
487- // Recursively refreshes the menu tree starting from |menu|, applying the
488- // model state to each menu item.
489- - (void )refreshMenuTree : (NSMenu *)menu {
490- for (NSMenuItem * item in menu.itemArray ) {
491- [self applyStateToMenuItem: item];
492- if (item.submenu )
493- [self refreshMenuTree: item.submenu];
494- }
495- }
496-
497460// Adds an item or a hierarchical menu to the item at the |index|,
498461// associated with the entry in the model identified by |modelIndex|.
499462- (void )addItemToMenu : (NSMenu *)menu
@@ -503,6 +466,32 @@ - (void)addItemToMenu:(NSMenu*)menu
503466 atIndex: index];
504467}
505468
469+ // Called before the menu is to be displayed to update the state (enabled,
470+ // radio, etc) of each item in the menu.
471+ - (BOOL )validateUserInterfaceItem : (id <NSValidatedUserInterfaceItem >)item {
472+ SEL action = [item action ];
473+ if (action == @selector (performShare: ))
474+ return YES ;
475+ if (action != @selector (itemSelected: ))
476+ return NO ;
477+
478+ NSInteger modelIndex = [item tag ];
479+ electron::ElectronMenuModel* model = [WeakPtrToElectronMenuModelAsNSObject
480+ getFrom: [(id )item representedObject ]];
481+ DCHECK (model);
482+ if (model) {
483+ BOOL checked = model->IsItemCheckedAt (modelIndex);
484+ DCHECK ([(id )item isKindOfClass: [NSMenuItem class ]]);
485+
486+ [(id )item
487+ setState: (checked ? NSControlStateValueOn : NSControlStateValueOff )];
488+ [(id )item setHidden: (!model->IsVisibleAt (modelIndex))];
489+
490+ return model->IsEnabledAt (modelIndex);
491+ }
492+ return NO ;
493+ }
494+
506495// Called when the user chooses a particular menu item. |sender| is the menu
507496// item chosen.
508497- (void )itemSelected : (id )sender {
@@ -537,11 +526,10 @@ - (NSMenu*)menu {
537526 menu_ = menu;
538527 } else {
539528 menu_ = [[NSMenu alloc ] initWithTitle: @" " ];
540- menu_.autoenablesItems = NO ;
541529 if (model_)
542530 [self populateWithModel: model_.get ()];
543531 }
544- menu_. delegate = self;
532+ [ menu_ setDelegate: self ] ;
545533 return menu_;
546534}
547535
@@ -551,7 +539,6 @@ - (BOOL)isMenuOpen {
551539
552540- (void )menuWillOpen : (NSMenu *)menu {
553541 isMenuOpen_ = YES ;
554- [self refreshMenuTree: menu];
555542 if (model_)
556543 model_->MenuWillShow ();
557544}
0 commit comments