macOS: Reset NSApp main menu temporarily when re-using top level menu

AppKit's built in logic for customizing menu entries, such as adding
text input (emoji, dictation) entries to the Edit menu, happens via
[NSApplication _customizeMainMenu], which is triggered either from
[NSApplication finishedLaunching], or [NSApplication setMainMenu:],
but in the latter case, only if the menu is different.

In our case, we might be re-using the same menu as before, but the
menu now has additional sub menus such as an Edit menu. In that case
we still want AppKit to do its magic, so we need to reset the main
menu temporarily to nil so that AppKit sees the menu as a "new" menu.

Pick-to: 6.6 6.5 6.6.0
Fixes: QTBUG-116903
Change-Id: Ibd9da72fb81b7cd1d707bd350a62d0c93356dbd4
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Tor Arne Vestbø 2023-09-11 15:49:28 +02:00
parent d184f4153c
commit 5994e94fd1

View File

@ -327,7 +327,21 @@ void QCocoaMenuBar::updateMenuBarImmediately()
}
[mergedItems release];
[NSApp setMainMenu:mb->nsMenu()];
NSMenu *newMainMenu = mb->nsMenu();
if (NSApp.mainMenu == newMainMenu) {
// NSApplication triggers _customizeMainMenu when the menu
// changes, which takes care of adding text input items to
// the edit menu e.g., but this doesn't happen if the menu
// is the same. In our case we might be re-using an existing
// menu, but the menu might have new sub menus that need to
// be customized. To ensure NSApplication does the right
// thing we reset the main menu first.
qCDebug(lcQpaMenus) << "Clearing main menu temporarily";
NSApp.mainMenu = nil;
}
NSApp.mainMenu = newMainMenu;
insertWindowMenu();
[loader qtTranslateApplicationMenu];
}