QShortCut: Check whether the menu is QPA-disabled

When climbing the menu hierarchy, it's sounder to
check whether the actual QPA menu is enabled. This
way we can trigger modifier-less shortcuts even in
submenus.

Task-number: QTBUG-38256
Task-number: QTBUG-42584
Change-Id: I13a27027306bce0f0732b05bf9469f3b77028f73
Reviewed-by: Liang Qi <liang.qi@theqtcompany.com>
bb10
Gabriel de Dietrich 2015-03-10 16:22:58 +01:00
parent a4c2e95ce1
commit 22afbc1536
4 changed files with 15 additions and 3 deletions

View File

@ -103,6 +103,7 @@ public:
virtual void setText(const QString &text) = 0;
virtual void setIcon(const QIcon &icon) = 0;
virtual void setEnabled(bool enabled) = 0;
virtual bool isEnabled() const { return true; }
virtual void setVisible(bool visible) = 0;
virtual void setMinimumWidth(int width) { Q_UNUSED(width); }
virtual void setFont(const QFont &font) { Q_UNUSED(font); }

View File

@ -58,6 +58,7 @@ public:
void removeMenuItem(QPlatformMenuItem *menuItem);
void syncMenuItem(QPlatformMenuItem *menuItem);
void setEnabled(bool enabled);
bool isEnabled() const;
void setVisible(bool visible);
void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item);
void dismiss();

View File

@ -426,6 +426,11 @@ void QCocoaMenu::setEnabled(bool enabled)
syncModalState(!m_enabled);
}
bool QCocoaMenu::isEnabled() const
{
return [m_nativeItem isEnabled];
}
void QCocoaMenu::setVisible(bool visible)
{
[m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)];

View File

@ -44,6 +44,7 @@
#include <private/qshortcutmap_p.h>
#include <private/qaction_p.h>
#include <private/qwidgetwindow_p.h>
#include <qpa/qplatformmenu.h>
QT_BEGIN_NAMESPACE
@ -269,9 +270,13 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge
// On Mac, menu item shortcuts are processed before reaching any window.
// That means that if a menu action shortcut has not been already processed
// (and reaches this point), then the menu item itself has been disabled.
// This occurs at the QPA level on Mac, were we disable all the Cocoa menus
// when showing a modal window.
if (a->shortcut().count() < 1 || (a->shortcut().count() == 1 && (a->shortcut()[0] & Qt::MODIFIER_MASK) != 0))
// This occurs at the QPA level on Mac, where we disable all the Cocoa menus
// when showing a modal window. (Notice that only the QPA menu is disabled,
// not the QMenu.) Since we can also reach this code by climbing the menu
// hierarchy (see below), or when the shortcut is not a key-equivalent, we
// need to check whether the QPA menu is actually disabled.
QPlatformMenu *pm = menu->platformMenu();
if (!pm || !pm->isEnabled())
continue;
#endif
QAction *a = menu->menuAction();