Skip to content

Commit

Permalink
Bug 1808223: Work around a bug in macOS that causes hidden menu items…
Browse files Browse the repository at this point in the history
… to be added every time a user switches between windows, ultimately causing significant slowdowns when switching between windows. Based on a patch by David Levy. r=mstange

Differential Revision: https://phabricator.services.mozilla.com/D193415
  • Loading branch information
Stephen A Pohl committed Nov 15, 2023
1 parent 1a7724c commit f569cd0
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions widget/cocoa/nsMenuBarX.mm
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,46 @@ - (void)menuDidClose:(NSMenu*)menu {
NS_OBJC_END_TRY_ABORT_BLOCK;
}

// macOS is adding some (currently 3) hidden menu items every time that
// `NSApp.mainMenu` is set, but never removes them. This ultimately causes a
// significant slowdown when switching between windows because the number of
// items in `NSApp.mainMenu` is growing without bounds.
//
// The known hidden, problematic menu items are associated with the following
// menus:
// - Start Dictation...
// - Emoji & Symbols
//
// Removing these items before setting `NSApp.mainMenu` prevents this slowdown.
// See bug 1808223.
static bool RemoveProblematicMenuItems(NSMenu* aMenu) {
uint8_t problematicMenuItemCount = 3;
NSMutableArray* itemsToRemove =
[NSMutableArray arrayWithCapacity:problematicMenuItemCount];

for (NSInteger i = 0; i < aMenu.numberOfItems; i++) {
NSMenuItem* item = [aMenu itemAtIndex:i];

if (item.hidden &&
(item.action == @selector(startDictation:) ||
item.action == @selector(orderFrontCharacterPalette:))) {
[itemsToRemove addObject:@(i)];
}

if (item.hasSubmenu && RemoveProblematicMenuItems(item.submenu)) {
return true;
}
}

bool didRemoveItems = false;
for (NSNumber* index in [itemsToRemove reverseObjectEnumerator]) {
[aMenu removeItemAtIndex:index.integerValue];
didRemoveItems = true;
}

return didRemoveItems;
}

nsresult nsMenuBarX::Paint() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;

Expand All @@ -433,6 +473,8 @@ - (void)menuDidClose:(NSMenu*)menu {
[mNativeMenu insertItem:appMenuItem atIndex:0];
[appMenuItem release];

RemoveProblematicMenuItems(mNativeMenu);

// Set menu bar and event target.
NSApp.mainMenu = mNativeMenu;
SetSystemHelpMenu();
Expand Down

0 comments on commit f569cd0

Please sign in to comment.