macOS: add default Edit menu items, if not added by AppKit
AppKit automatically appends "Start Dictation..." and "Emoji & Symbols" menu items, after a separator, to a menu in the menu bar that has the title "Edit" in the operating system language. Qt applications might however be translated to some other language, in which case the "Edit" menu is not recognized by AppKit, and the menu items won't be added. This is bad for accessibility and for users wanting to type emojis. If we have a menu that has the title "Edit" as translated in Qt's i18n system, then create those items manually. To prevent a duplication of the system- provided menu items, don't add the items if there already is one with the action being set to the relevant selector. Otherwise, perform the selector or call the NSApplication method ourselves. This then results in the relevant keyboard input through regular code paths. Fixes: QTBUG-79565 Change-Id: Ifd06036211756277550d398034689aca8e770133 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
e2fc3246d2
commit
d42cfeb84f
@ -80,12 +80,14 @@ private:
|
||||
|
||||
bool needsImmediateUpdate();
|
||||
bool shouldDisable(QCocoaWindow *active) const;
|
||||
void insertDefaultEditItems(QCocoaMenu *menu);
|
||||
|
||||
NSMenuItem *nativeItemForMenu(QCocoaMenu *menu) const;
|
||||
|
||||
QList<QPointer<QCocoaMenu> > m_menus;
|
||||
NSMenu *m_nativeMenu;
|
||||
QPointer<QCocoaWindow> m_window;
|
||||
QList<QPointer<QCocoaMenuItem>> m_defaultEditMenuItems;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -194,6 +194,11 @@ void QCocoaMenuBar::syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate)
|
||||
for (QCocoaMenuItem *item : cocoaMenu->items())
|
||||
cocoaMenu->syncMenuItem_helper(item, menubarUpdate);
|
||||
|
||||
const QString captionNoAmpersand = QString::fromNSString(cocoaMenu->nsMenu().title)
|
||||
.remove(QLatin1Char('&'));
|
||||
if (captionNoAmpersand == QCoreApplication::translate("QCocoaMenu", "Edit"))
|
||||
insertDefaultEditItems(cocoaMenu);
|
||||
|
||||
BOOL shouldHide = YES;
|
||||
if (cocoaMenu->isVisible()) {
|
||||
// If the NSMenu has no visible items, or only separators, we should hide it
|
||||
@ -400,6 +405,48 @@ QCocoaWindow *QCocoaMenuBar::cocoaWindow() const
|
||||
return m_window.data();
|
||||
}
|
||||
|
||||
void QCocoaMenuBar::insertDefaultEditItems(QCocoaMenu *menu)
|
||||
{
|
||||
if (menu->items().isEmpty())
|
||||
return;
|
||||
|
||||
NSMenu *nsEditMenu = menu->nsMenu();
|
||||
if ([nsEditMenu itemAtIndex:nsEditMenu.numberOfItems - 1].action
|
||||
== @selector(orderFrontCharacterPalette:)) {
|
||||
for (auto defaultEditMenuItem : qAsConst(m_defaultEditMenuItems)) {
|
||||
if (menu->items().contains(defaultEditMenuItem))
|
||||
menu->removeMenuItem(defaultEditMenuItem);
|
||||
}
|
||||
qDeleteAll(m_defaultEditMenuItems);
|
||||
m_defaultEditMenuItems.clear();
|
||||
} else {
|
||||
if (m_defaultEditMenuItems.isEmpty()) {
|
||||
QCocoaMenuItem *separator = new QCocoaMenuItem;
|
||||
separator->setIsSeparator(true);
|
||||
|
||||
QCocoaMenuItem *dictationItem = new QCocoaMenuItem;
|
||||
dictationItem->setText(QCoreApplication::translate("QCocoaMenuItem", "Start Dictation..."));
|
||||
QObject::connect(dictationItem, &QPlatformMenuItem::activated, this, []{
|
||||
[NSApplication.sharedApplication performSelector:@selector(startDictation:)];
|
||||
});
|
||||
|
||||
QCocoaMenuItem *emojiItem = new QCocoaMenuItem;
|
||||
emojiItem->setText(QCoreApplication::translate("QCocoaMenuItem", "Emoji && Symbols"));
|
||||
emojiItem->setShortcut(QKeyCombination(Qt::MetaModifier|Qt::ControlModifier, Qt::Key_Space));
|
||||
QObject::connect(emojiItem, &QPlatformMenuItem::activated, this, []{
|
||||
[NSApplication.sharedApplication orderFrontCharacterPalette:nil];
|
||||
});
|
||||
|
||||
m_defaultEditMenuItems << separator << dictationItem << emojiItem;
|
||||
}
|
||||
for (auto defaultEditMenuItem : qAsConst(m_defaultEditMenuItems)) {
|
||||
if (menu->items().contains(defaultEditMenuItem))
|
||||
menu->removeMenuItem(defaultEditMenuItem);
|
||||
menu->insertMenuItem(defaultEditMenuItem, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qcocoamenubar.cpp"
|
||||
|
Loading…
Reference in New Issue
Block a user