Add new API to control whether shortcuts are shown in context menus
Shortcuts are universally not shown on macOS or mobile platforms, making applications look very obviously out of place. Windows and GNOME desktop environments almost never use them. Only KDE appears to do so commonly; default accordingly. Task-number: QTBUG-49435 Change-Id: Ieac4cee57b15a02be5258f3d07749af6316af62b Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
This commit is contained in:
parent
b6e3fd8ced
commit
c2c3452ba5
@ -508,6 +508,7 @@ public:
|
||||
AA_CompressHighFrequencyEvents = 25,
|
||||
AA_DontCheckOpenGLContextThreadAffinity = 26,
|
||||
AA_DisableShaderDiskCache = 27,
|
||||
AA_DontShowShortcutsInContextMenus = 28,
|
||||
|
||||
// Add new attributes before this line
|
||||
AA_AttributeCount
|
||||
|
@ -114,6 +114,11 @@
|
||||
\macos menubar \e{may not} pick up a change in this attribute. Changes
|
||||
in the QAction::iconVisibleInMenu property will always be picked up.
|
||||
|
||||
\value AA_DontShowShortcutsInContextMenus Actions with the Shortcut property
|
||||
won't be shown in any shortcut menus unless specifically set by the
|
||||
QAction::shortcutVisibleInContextMenu property. This value has
|
||||
been added in Qt 5.10.
|
||||
|
||||
\value AA_NativeWindows Ensures that widgets have native windows.
|
||||
|
||||
\value AA_DontCreateNativeWidgetSiblings Ensures that siblings of native
|
||||
|
@ -392,6 +392,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
|
||||
return false;
|
||||
case ShowIsMaximized:
|
||||
return false;
|
||||
case ShowShortcutsInContextMenus:
|
||||
return QPlatformTheme::defaultThemeHint(QPlatformTheme::ShowShortcutsInContextMenus);
|
||||
case PasswordMaskDelay:
|
||||
return QPlatformTheme::defaultThemeHint(QPlatformTheme::PasswordMaskDelay);
|
||||
case PasswordMaskCharacter:
|
||||
|
@ -161,6 +161,7 @@ public:
|
||||
ItemViewActivateItemOnSingleClick,
|
||||
UiEffects,
|
||||
WheelScrollLines,
|
||||
ShowShortcutsInContextMenus,
|
||||
};
|
||||
|
||||
virtual QVariant styleHint(StyleHint hint) const;
|
||||
|
@ -161,6 +161,8 @@ QT_BEGIN_NAMESPACE
|
||||
The default value is double the MouseDoubleClickDistance, or 10 logical pixels
|
||||
if that is not specified.
|
||||
|
||||
\value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
|
||||
|
||||
\sa themeHint(), QStyle::pixelMetric()
|
||||
*/
|
||||
|
||||
@ -516,6 +518,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
|
||||
return QVariant(QStringList());
|
||||
case QPlatformTheme::StyleNames:
|
||||
return QVariant(QStringList());
|
||||
case QPlatformTheme::ShowShortcutsInContextMenus:
|
||||
return QVariant(false);
|
||||
case TextCursorWidth:
|
||||
return QVariant(1);
|
||||
case DropShadow:
|
||||
|
@ -115,7 +115,8 @@ public:
|
||||
MousePressAndHoldInterval,
|
||||
MouseDoubleClickDistance,
|
||||
WheelScrollLines,
|
||||
TouchDoubleTapDistance
|
||||
TouchDoubleTapDistance,
|
||||
ShowShortcutsInContextMenus
|
||||
};
|
||||
|
||||
enum DialogType {
|
||||
|
@ -364,6 +364,17 @@ bool QStyleHints::showIsMaximized() const
|
||||
return hint(QPlatformIntegration::ShowIsMaximized).toBool();
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QStyleHints::showShortcutsInContextMenus
|
||||
\since 5.10
|
||||
\brief \c true if the platform normally shows shortcut key sequences in
|
||||
context menus, otherwise \c false.
|
||||
*/
|
||||
bool QStyleHints::showShortcutsInContextMenus() const
|
||||
{
|
||||
return themeableHint(QPlatformTheme::ShowShortcutsInContextMenus, QPlatformIntegration::ShowShortcutsInContextMenus).toBool();
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QStyleHints::passwordMaskDelay
|
||||
\brief the time, in milliseconds, a typed letter is displayed unshrouded
|
||||
|
@ -90,6 +90,7 @@ public:
|
||||
int cursorFlashTime() const;
|
||||
bool showIsFullScreen() const;
|
||||
bool showIsMaximized() const;
|
||||
bool showShortcutsInContextMenus() const;
|
||||
int passwordMaskDelay() const;
|
||||
QChar passwordMaskCharacter() const;
|
||||
qreal fontSmoothingGamma() const;
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "qapplication.h"
|
||||
#include "qevent.h"
|
||||
#include "qlist.h"
|
||||
#include "qstylehints.h"
|
||||
#include <private/qshortcutmap_p.h>
|
||||
#include <private/qapplication_p.h>
|
||||
#include <private/qmenu_p.h>
|
||||
@ -75,6 +76,7 @@ static QString qt_strippedText(QString s)
|
||||
QActionPrivate::QActionPrivate() : group(0), enabled(1), forceDisabled(0),
|
||||
visible(1), forceInvisible(0), checkable(0), checked(0), separator(0), fontSet(false),
|
||||
iconVisibleInMenu(-1),
|
||||
shortcutVisibleInContextMenu(-1),
|
||||
menuRole(QAction::TextHeuristicRole),
|
||||
priority(QAction::NormalPriority)
|
||||
{
|
||||
@ -1292,6 +1294,46 @@ bool QAction::isIconVisibleInMenu() const
|
||||
return d->iconVisibleInMenu;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QAction::shortcutVisibleInContextMenu
|
||||
\brief Whether or not an action should show a shortcut in a context menu
|
||||
\since 5.10
|
||||
|
||||
In some applications, it may make sense to have actions with shortcuts in
|
||||
context menus. If true, the shortcut (if valid) is shown when the action is
|
||||
shown via a context menu, when it is false, it is not shown.
|
||||
|
||||
The default is to follow whether the Qt::AA_DontShowShortcutsInContextMenus attribute
|
||||
is set for the application, falling back to the widget style hint.
|
||||
Explicitly setting this property overrides the presence (or abscence) of the attribute.
|
||||
|
||||
\sa QAction::shortcut, QCoreApplication::setAttribute()
|
||||
*/
|
||||
void QAction::setShortcutVisibleInContextMenu(bool visible)
|
||||
{
|
||||
Q_D(QAction);
|
||||
if (d->shortcutVisibleInContextMenu == -1 || visible != bool(d->shortcutVisibleInContextMenu)) {
|
||||
int oldValue = d->shortcutVisibleInContextMenu;
|
||||
d->shortcutVisibleInContextMenu = visible;
|
||||
// Only send data changed if we really need to.
|
||||
if (oldValue != -1
|
||||
|| visible == !QApplication::instance()->testAttribute(Qt::AA_DontShowShortcutsInContextMenus)) {
|
||||
d->sendDataChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QAction::isShortcutVisibleInContextMenu() const
|
||||
{
|
||||
Q_D(const QAction);
|
||||
if (d->shortcutVisibleInContextMenu == -1) {
|
||||
if (QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus))
|
||||
return false;
|
||||
return qApp->styleHints()->showShortcutsInContextMenus();
|
||||
}
|
||||
return d->shortcutVisibleInContextMenu;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QAction *action)
|
||||
{
|
||||
|
@ -80,6 +80,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject
|
||||
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY changed)
|
||||
Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
|
||||
Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
|
||||
Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed)
|
||||
Q_PROPERTY(Priority priority READ priority WRITE setPriority)
|
||||
|
||||
public:
|
||||
@ -168,6 +169,8 @@ public:
|
||||
void setIconVisibleInMenu(bool visible);
|
||||
bool isIconVisibleInMenu() const;
|
||||
|
||||
void setShortcutVisibleInContextMenu(bool show);
|
||||
bool isShortcutVisibleInContextMenu() const;
|
||||
|
||||
QWidget *parentWidget() const;
|
||||
|
||||
|
@ -106,6 +106,7 @@ public:
|
||||
uint fontSet : 1;
|
||||
|
||||
int iconVisibleInMenu : 3; // Only has values -1, 0, and 1
|
||||
int shortcutVisibleInContextMenu : 2; // Only has values -1, 0, and 1
|
||||
|
||||
QAction::MenuRole menuRole;
|
||||
QAction::Priority priority;
|
||||
|
@ -74,7 +74,10 @@
|
||||
#include "private/qapplication_p.h"
|
||||
#include "private/qshortcutmap_p.h"
|
||||
#include "qkeysequence.h"
|
||||
#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \
|
||||
#define ACCEL_KEY(k) ((qApp->testAttribute(Qt::AA_DontShowIconsInMenus) \
|
||||
? false \
|
||||
: qApp->styleHints()->showShortcutsInContextMenus()) \
|
||||
&& !qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \
|
||||
QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
|
||||
#else
|
||||
#define ACCEL_KEY(k) QString()
|
||||
|
@ -332,7 +332,7 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const
|
||||
tabWidth = qMax(int(tabWidth), qfm.width(s.mid(t+1)));
|
||||
s = s.left(t);
|
||||
#ifndef QT_NO_SHORTCUT
|
||||
} else {
|
||||
} else if (action->isShortcutVisibleInContextMenu()) {
|
||||
QKeySequence seq = action->shortcut();
|
||||
if (!seq.isEmpty())
|
||||
tabWidth = qMax(int(tabWidth), qfm.width(seq.toString(QKeySequence::NativeText)));
|
||||
@ -1447,7 +1447,8 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
|
||||
option->icon = action->icon();
|
||||
QString textAndAccel = action->text();
|
||||
#ifndef QT_NO_SHORTCUT
|
||||
if (textAndAccel.indexOf(QLatin1Char('\t')) == -1) {
|
||||
if (action->isShortcutVisibleInContextMenu()
|
||||
&& textAndAccel.indexOf(QLatin1Char('\t')) == -1) {
|
||||
QKeySequence seq = action->shortcut();
|
||||
if (!seq.isEmpty())
|
||||
textAndAccel += QLatin1Char('\t') + seq.toString(QKeySequence::NativeText);
|
||||
|
@ -85,7 +85,10 @@
|
||||
#include "private/qapplication_p.h"
|
||||
#include "private/qshortcutmap_p.h"
|
||||
#include <qkeysequence.h>
|
||||
#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \
|
||||
#define ACCEL_KEY(k) ((qApp->testAttribute(Qt::AA_DontShowIconsInMenus) \
|
||||
? false \
|
||||
: qApp->styleHints()->showShortcutsInContextMenus()) \
|
||||
&& !qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \
|
||||
QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
|
||||
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user