From a92c202b49777696cbc64003f6292e6b61952140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 12 Apr 2023 17:04:24 +0200 Subject: macOS: Localize title of edit menu's NSMenuItem via AppKit In 939b7bfe66221975d3a12a6d0a6dd14d9ad04344 we synced up the NSMenuItem's title to that of the corresponding NSMenu, as AppKit was observed to use the NSMenuItem title for its heuristics of when to add dictation and emoji entries to the menu. But AppKit's heuristics are based on the localized name of the edit menu, so we need to follow suit and look up AppKit's own localizations. This is of course fragile, as we're relying on this localization continuing to live in the InputManager table, but if that changes we'll just fall back to using the title from the NSMenu, as we did before. In addition, AppKit's heuristics also look for menu items in the menu that match selectors such as copy:, paste:, etc, so even if our lookup of the localized title fails, the additional heuristics would in most cases still succeed in detecting the edit menu. Task-number: QTBUG-53085 Task-number: QTBUG-79565 Pick-to: 6.5 Change-Id: I5e12973b86ab35f10a8f7434bcae8a4cf134ecfd Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoamenubar.mm | 43 +++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'src/plugins/platforms/cocoa') diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index ece6189bff..7cc57055c7 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -174,10 +174,45 @@ void QCocoaMenuBar::syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate) } } - if (NSMenuItem *attachedItem = cocoaMenu->attachedItem()) { - // Non-nil attached item means the item's submenu is set - attachedItem.title = cocoaMenu->nsMenu().title; - attachedItem.hidden = shouldHide; + if (NSMenuItem *menuItem = cocoaMenu->attachedItem()) { + // Non-nil menu item means the item's sub menu is set + + NSString *menuTitle = cocoaMenu->nsMenu().title; + + // The NSMenu's title is what's visible to the user, and AppKit uses this + // for some of its heuristics of when to add special items to the menus, + // such as 'Enter Full Screen' in the View menu, the search bare in the + // Help menu, and the "Send App feedback to Apple" in the Help menu. + // This relies on the title matching AppKit's localized value from the + // MenuCommands table, which in turn depends on the preferredLocalizations + // of the AppKit bundle. We don't do any automatic translation of menu + // titles visible to the user, so this relies on the application developer + // having chosen translated titles that match AppKit's, and that the Qt + // preferred UI languages match AppKit's preferredLocalizations. + + // In the case of the Edit menu, AppKit uses the NSMenuItem's title + // for its heuristics of when to add the dictation and emoji entries, + // and this title is not visible to the user. But like above, the + // heuristics are based on the localized title of the menu, so we need + // to ensure the title matches AppKit's localization. + + // Unfortunately, the title we have at this point may have gone through + // Qt's i18n machinery already, via e.g. tr("Edit") in the application, + // in which case we don't know the context of the translation, and can't + // do a reverse lookup to go back to the untranslated title to pass to + // AppKit. As a workaround we translate the title via a our context, + // and document that the user needs to ensure their application matches + // this translation. + if ([menuTitle isEqual:@"Edit"] || [menuTitle isEqual:tr("Edit").toNSString()]) { + static const NSBundle *appKit = [NSBundle bundleForClass:NSApplication.class]; + menuItem.title = [appKit localizedStringForKey:@"Edit" value:menuTitle table:@"InputManager"]; + } else { + // The Edit menu is the only case we know of so far, but to be on + // the safe side we always sync the menu title. + menuItem.title = menuTitle; + } + + menuItem.hidden = shouldHide; } } -- cgit v1.2.3