mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
fix: refresh menu item state on key equivalent dispatch (#49875)
This commit is contained in:
@@ -258,7 +258,7 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
|
||||
// Empties the source menu items to the destination.
|
||||
- (void)moveMenuItems:(NSMenu*)source to:(NSMenu*)destination {
|
||||
const NSInteger count = [source numberOfItems];
|
||||
const NSInteger count = source.numberOfItems;
|
||||
for (NSInteger index = 0; index < count; index++) {
|
||||
NSMenuItem* removedItem = [source itemAtIndex:0];
|
||||
[source removeItemAtIndex:0];
|
||||
@@ -269,25 +269,25 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
// 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];
|
||||
NSMenu* recentDocumentsMenu = recentDocumentsMenuItem_.submenu;
|
||||
|
||||
// Remove menu items in recent documents back to swap menu
|
||||
[self moveMenuItems:recentDocumentsMenu to:recentDocumentsMenuSwap_];
|
||||
// Swap back the submenu
|
||||
[recentDocumentsMenuItem_ setSubmenu:recentDocumentsMenuSwap_];
|
||||
recentDocumentsMenuItem_.submenu = recentDocumentsMenuSwap_;
|
||||
|
||||
// Retain the item's submenu for a future recovery
|
||||
recentDocumentsMenuSwap_ = [item submenu];
|
||||
recentDocumentsMenuSwap_ = item.submenu;
|
||||
|
||||
// Repopulate with items from the submenu to be replaced
|
||||
[self moveMenuItems:recentDocumentsMenuSwap_ to:recentDocumentsMenu];
|
||||
// Update the submenu's title
|
||||
[recentDocumentsMenu setTitle:[recentDocumentsMenuSwap_ title]];
|
||||
recentDocumentsMenu.title = recentDocumentsMenuSwap_.title;
|
||||
// Replace submenu
|
||||
[item setSubmenu:recentDocumentsMenu];
|
||||
item.submenu = recentDocumentsMenu;
|
||||
|
||||
DCHECK_EQ([item action], @selector(submenuAction:));
|
||||
DCHECK_EQ([item target], recentDocumentsMenu);
|
||||
DCHECK_EQ(item.action, @selector(submenuAction:));
|
||||
DCHECK_EQ(item.target, recentDocumentsMenu);
|
||||
|
||||
// Remember the new menu item that carries the recent documents menu
|
||||
recentDocumentsMenuItem_ = item;
|
||||
@@ -303,7 +303,7 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
NSArray* services = [NSSharingService sharingServicesForItems:items];
|
||||
for (NSSharingService* service in services)
|
||||
[menu addItem:[self menuItemForService:service withItems:items]];
|
||||
[menu setDelegate:self];
|
||||
menu.delegate = self;
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -313,9 +313,9 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:service.menuItemTitle
|
||||
action:@selector(performShare:)
|
||||
keyEquivalent:@""];
|
||||
[item setTarget:self];
|
||||
[item setImage:service.image];
|
||||
[item setRepresentedObject:@{@"service" : service, @"items" : items}];
|
||||
item.target = self;
|
||||
item.image = service.image;
|
||||
item.representedObject = @{@"service" : service, @"items" : items};
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
submenu.delegate = self;
|
||||
|
||||
// Set submenu's role.
|
||||
if ((role == u"window" || role == u"windowmenu") && [submenu numberOfItems])
|
||||
if ((role == u"window" || role == u"windowmenu") && submenu.numberOfItems)
|
||||
[NSApp setWindowsMenu:submenu];
|
||||
else if (role == u"help")
|
||||
[NSApp setHelpMenu:submenu];
|
||||
@@ -463,6 +463,14 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
// Called by AppKit before displaying a menu and when a key equivalent is
|
||||
// pressed. This ensures menu item states (enabled, checked, hidden) are
|
||||
// refreshed from the model even when the menu is closed, which is necessary
|
||||
// since we set autoenablesItems = NO.
|
||||
- (void)menuNeedsUpdate:(NSMenu*)menu {
|
||||
[self refreshMenuTree:menu];
|
||||
}
|
||||
|
||||
- (void)applyStateToMenuItem:(NSMenuItem*)item {
|
||||
id represented = item.representedObject;
|
||||
if (!represented)
|
||||
@@ -487,7 +495,7 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
// When the menu is closed, we need to allow shortcuts to be triggered even
|
||||
// if the menu item is disabled. So we only disable the menu item when the
|
||||
// menu is open. This matches behavior of |validateUserInterfaceItem|.
|
||||
item.enabled = model->IsEnabledAt(index) || !isMenuOpen_;
|
||||
item.enabled = model->IsEnabledAt(index);
|
||||
item.hidden = !model->IsVisibleAt(index);
|
||||
item.state = model->IsItemCheckedAt(index) ? NSControlStateValueOn
|
||||
: NSControlStateValueOff;
|
||||
@@ -566,7 +574,6 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
[menu removeItem:item];
|
||||
}
|
||||
|
||||
[self refreshMenuTree:menu];
|
||||
if (model_)
|
||||
model_->MenuWillShow();
|
||||
}
|
||||
@@ -577,7 +584,6 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
return;
|
||||
|
||||
isMenuOpen_ = NO;
|
||||
[self refreshMenuTree:menu];
|
||||
|
||||
// There are two scenarios where we should emit menu-did-close:
|
||||
// 1. It's a popup and the top level menu is closed.
|
||||
|
||||
Reference in New Issue
Block a user