summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoamenubar.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoamenubar.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm130
1 files changed, 38 insertions, 92 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 61ac5eb7f0..30bff78a36 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@@ -67,7 +68,7 @@ QCocoaMenuBar::~QCocoaMenuBar()
#ifdef QT_COCOA_ENABLE_MENU_DEBUG
qDebug() << "~QCocoaMenuBar" << this;
#endif
- foreach (QCocoaMenu *menu, m_menus) {
+ for (auto menu : qAsConst(m_menus)) {
if (!menu)
continue;
NSMenuItem *item = nativeItemForMenu(menu);
@@ -79,14 +80,13 @@ QCocoaMenuBar::~QCocoaMenuBar()
static_menubars.removeOne(this);
if (!m_window.isNull() && m_window->menubar() == this) {
- m_window->setMenubar(0);
+ m_window->setMenubar(nullptr);
// Delete the children first so they do not cause
// the native menu items to be hidden after
// the menu bar was updated
qDeleteAll(children());
updateMenuBarImmediately();
- resetKnownMenuItemsToQt();
}
}
@@ -199,8 +199,8 @@ void QCocoaMenuBar::syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate)
// If the NSMenu has no visble items, or only separators, we should hide it
// on the menubar. This can happen after syncing the menu items since they
// can be moved to other menus.
- for (NSMenuItem *item in [cocoaMenu->nsMenu() itemArray])
- if (![item isSeparatorItem] && ![item isHidden]) {
+ for (NSMenuItem *item in cocoaMenu->nsMenu().itemArray)
+ if (!item.separatorItem && !item.hidden) {
shouldHide = NO;
break;
}
@@ -230,7 +230,7 @@ void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
if (!m_window.isNull())
m_window->setMenubar(nullptr);
- if (newParentWindow == nullptr) {
+ if (!newParentWindow) {
m_window.clear();
} else {
newParentWindow->create();
@@ -241,82 +241,28 @@ void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
updateMenuBarImmediately();
}
+QWindow *QCocoaMenuBar::parentWindow() const
+{
+ return m_window ? m_window->window() : nullptr;
+}
+
+
QCocoaWindow *QCocoaMenuBar::findWindowForMenubar()
{
if (qApp->focusWindow())
return static_cast<QCocoaWindow*>(qApp->focusWindow()->handle());
- return NULL;
+ return nullptr;
}
QCocoaMenuBar *QCocoaMenuBar::findGlobalMenubar()
{
- foreach (QCocoaMenuBar *mb, static_menubars) {
- if (mb->m_window.isNull())
- return mb;
+ for (auto *menubar : qAsConst(static_menubars)) {
+ if (menubar->m_window.isNull())
+ return menubar;
}
- return NULL;
-}
-
-void QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder()
-{
- // QTBUG-17291: http://forums.macrumors.com/showthread.php?t=1249452
- // When a dialog is opened, shortcuts for actions inside the dialog (cut, paste, ...)
- // continue to go through the same menu items which claimed those shortcuts.
- // They are not keystrokes which we can intercept in any other way; the OS intercepts them.
- // The menu items had to be created by the application. That's why we need roles
- // to identify those "special" menu items which can be useful even when non-Qt
- // native widgets are in focus. When the native widget is focused it will be the
- // first responder, so the menu item needs to have its target be the first responder;
- // this is done by setting it to nil.
-
- // This function will find all menu items on all menus which have
- // "special" roles, set the target and also set the standard actions which
- // apply to those roles. But afterwards it is necessary to call
- // resetKnownMenuItemsToQt() to put back the target and action so that
- // those menu items will go back to invoking their associated QActions.
- foreach (QCocoaMenuBar *mb, static_menubars)
- foreach (QCocoaMenu *m, mb->m_menus)
- foreach (QCocoaMenuItem *i, m->items()) {
- bool known = true;
- switch (i->effectiveRole()) {
- case QPlatformMenuItem::CutRole:
- [i->nsItem() setAction:@selector(cut:)];
- break;
- case QPlatformMenuItem::CopyRole:
- [i->nsItem() setAction:@selector(copy:)];
- break;
- case QPlatformMenuItem::PasteRole:
- [i->nsItem() setAction:@selector(paste:)];
- break;
- case QPlatformMenuItem::SelectAllRole:
- [i->nsItem() setAction:@selector(selectAll:)];
- break;
- // We may discover later that there are other roles/actions which
- // are meaningful to standard native widgets; they can be added.
- default:
- known = false;
- break;
- }
- if (known)
- [i->nsItem() setTarget:nil];
- }
-}
-
-void QCocoaMenuBar::resetKnownMenuItemsToQt()
-{
- // Undo the effect of redirectKnownMenuItemsToFirstResponder():
- // reset the menu items' target/action.
- foreach (QCocoaMenuBar *mb, static_menubars) {
- foreach (QCocoaMenu *m, mb->m_menus) {
- foreach (QCocoaMenuItem *i, m->items()) {
- if (i->effectiveRole() >= QPlatformMenuItem::ApplicationSpecificRole) {
- m->setItemTargetAction(i);
- }
- }
- }
- }
+ return nullptr;
}
void QCocoaMenuBar::updateMenuBarImmediately()
@@ -325,7 +271,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
QCocoaMenuBar *mb = findGlobalMenubar();
QCocoaWindow *cw = findWindowForMenubar();
- QWindow *win = cw ? cw->window() : 0;
+ QWindow *win = cw ? cw->window() : nullptr;
if (win && (win->flags() & Qt::Popup) == Qt::Popup) {
// context menus, comboboxes, etc. don't need to update the menubar,
// but if an application has only Qt::Tool window(s) on start,
@@ -353,7 +299,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
#endif
bool disableForModal = mb->shouldDisable(cw);
- foreach (QCocoaMenu *menu, mb->m_menus) {
+ for (auto menu : qAsConst(mb->m_menus)) {
if (!menu)
continue;
NSMenuItem *item = mb->nativeItemForMenu(menu);
@@ -368,16 +314,16 @@ void QCocoaMenuBar::updateMenuBarImmediately()
[loader ensureAppMenuInMenu:mb->nsMenu()];
NSMutableSet *mergedItems = [[NSMutableSet setWithCapacity:mb->merged().count()] retain];
- foreach (QCocoaMenuItem *m, mb->merged()) {
- [mergedItems addObject:m->nsItem()];
- m->syncMerged();
+ for (auto mergedItem : mb->merged()) {
+ [mergedItems addObject:mergedItem->nsItem()];
+ mergedItem->syncMerged();
}
// hide+disable all mergeable items we're not currently using
for (NSMenuItem *mergeable in [loader mergeable]) {
if (![mergedItems containsObject:mergeable]) {
- [mergeable setHidden:YES];
- [mergeable setEnabled:NO];
+ mergeable.hidden = YES;
+ mergeable.enabled = NO;
}
}
@@ -389,7 +335,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
QList<QCocoaMenuItem*> QCocoaMenuBar::merged() const
{
QList<QCocoaMenuItem*> r;
- foreach (QCocoaMenu* menu, m_menus)
+ for (auto menu : qAsConst(m_menus))
r.append(menu->merged());
return r;
@@ -409,11 +355,11 @@ bool QCocoaMenuBar::shouldDisable(QCocoaWindow *active) const
// When there is an application modal window on screen, the entries of
// the menubar should be disabled. The exception in Qt is that if the
// modal window is the only window on screen, then we enable the menu bar.
- foreach (QWindow *w, topWindows) {
- if (w->isVisible() && w->modality() == Qt::ApplicationModal) {
+ for (auto *window : qAsConst(topWindows)) {
+ if (window->isVisible() && window->modality() == Qt::ApplicationModal) {
// check for other visible windows
- foreach (QWindow *other, topWindows) {
- if ((w != other) && (other->isVisible())) {
+ for (auto *other : qAsConst(topWindows)) {
+ if ((window != other) && (other->isVisible())) {
// INVARIANT: we found another visible window
// on screen other than our modalWidget. We therefore
// disable the menu bar to follow normal modality logic:
@@ -433,21 +379,21 @@ bool QCocoaMenuBar::shouldDisable(QCocoaWindow *active) const
QPlatformMenu *QCocoaMenuBar::menuForTag(quintptr tag) const
{
- foreach (QCocoaMenu *menu, m_menus) {
+ for (auto menu : qAsConst(m_menus))
if (menu->tag() == tag)
return menu;
- }
- return 0;
+ return nullptr;
}
-NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r)
+NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole role)
{
- foreach (QCocoaMenu *m, m_menus)
- foreach (QCocoaMenuItem *i, m->items())
- if (i->effectiveRole() == r)
- return i->nsItem();
- return nullptr;
+ for (auto menu : qAsConst(m_menus))
+ for (auto *item : menu->items())
+ if (item->effectiveRole() == role)
+ return item->nsItem();
+
+ return nil;
}
QCocoaWindow *QCocoaMenuBar::cocoaWindow() const