summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@qt.io>2017-03-10 16:55:04 -0800
committerJake Petroules <jake.petroules@qt.io>2017-03-14 05:29:22 +0000
commitc2c3452ba5b4c32d0c2d5df9193bf89986623ab5 (patch)
tree66b567681989e166bc429f477ae7f13f9c844f75
parentb6e3fd8ced2ae3629b73b78bf436d1a3ac4bccda (diff)
downloadqtbase-c2c3452ba5b4c32d0c2d5df9193bf89986623ab5.tar.gz
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>
-rw-r--r--src/corelib/global/qnamespace.h1
-rw-r--r--src/corelib/global/qnamespace.qdoc5
-rw-r--r--src/gui/kernel/qplatformintegration.cpp2
-rw-r--r--src/gui/kernel/qplatformintegration.h1
-rw-r--r--src/gui/kernel/qplatformtheme.cpp4
-rw-r--r--src/gui/kernel/qplatformtheme.h3
-rw-r--r--src/gui/kernel/qstylehints.cpp11
-rw-r--r--src/gui/kernel/qstylehints.h1
-rw-r--r--src/widgets/kernel/qaction.cpp42
-rw-r--r--src/widgets/kernel/qaction.h3
-rw-r--r--src/widgets/kernel/qaction_p.h1
-rw-r--r--src/widgets/widgets/qlineedit.cpp5
-rw-r--r--src/widgets/widgets/qmenu.cpp5
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp5
14 files changed, 84 insertions, 5 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index da44c01594..dbc8b368b3 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -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
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index b8588b3f98..c44e95a84b 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -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
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 0af3295430..9673ad673a 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -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:
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 54904ef60d..49d41dd576 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -161,6 +161,7 @@ public:
ItemViewActivateItemOnSingleClick,
UiEffects,
WheelScrollLines,
+ ShowShortcutsInContextMenus,
};
virtual QVariant styleHint(StyleHint hint) const;
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 878f656f2e..ebf65eda12 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -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:
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 2ba2f8669f..f4ff418db6 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -115,7 +115,8 @@ public:
MousePressAndHoldInterval,
MouseDoubleClickDistance,
WheelScrollLines,
- TouchDoubleTapDistance
+ TouchDoubleTapDistance,
+ ShowShortcutsInContextMenus
};
enum DialogType {
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 85c0768e35..0850228ee5 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -365,6 +365,17 @@ bool QStyleHints::showIsMaximized() const
}
/*!
+ \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
in a text input field in password mode.
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index b9bf428edd..3230149247 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -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;
diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp
index 4582a55394..ec7dc34d4d 100644
--- a/src/widgets/kernel/qaction.cpp
+++ b/src/widgets/kernel/qaction.cpp
@@ -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)
{
diff --git a/src/widgets/kernel/qaction.h b/src/widgets/kernel/qaction.h
index 97948a2457..d211016931 100644
--- a/src/widgets/kernel/qaction.h
+++ b/src/widgets/kernel/qaction.h
@@ -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;
diff --git a/src/widgets/kernel/qaction_p.h b/src/widgets/kernel/qaction_p.h
index 8ee71a5ff0..5f4c9a35a3 100644
--- a/src/widgets/kernel/qaction_p.h
+++ b/src/widgets/kernel/qaction_p.h
@@ -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;
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index fb0ffd6083..419968db75 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -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()
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 2917083415..295fb7d89c 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -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);
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index f5672bd87a..9aec94d47f 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -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