From 5a2c0b364a3a5830dd6d5069b5f8d3921aeac73a Mon Sep 17 00:00:00 2001 From: Andreas Buhr Date: Wed, 13 Jan 2021 15:29:32 +0100 Subject: Change QQuickShortcut::setSequences to bind to all sequences When binding a Shortcut to a standard key sequence like QKeySequence::FullScreen, it binds only to one key sequence, even though there might be multiple key sequences associated. This patch changes the code to emit a warning in this case and allows to bind to multiple key sequences using 'sequences: [ ]'. Fixes: QTBUG-88682 Change-Id: I88998aa8858d8f2c0c86e46bae94afd7ceb15b66 Reviewed-by: Fabian Kosmale (cherry picked from commit 6511b17038627ac30cb6622b13c7d46d9877bac5) Reviewed-by: Qt Cherry-pick Bot --- src/quick/util/qquickshortcut.cpp | 83 ++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 23 deletions(-) (limited to 'src/quick') diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index 2905e36d00..fdd846adb6 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -44,6 +44,7 @@ #include #include #include +#include /*! \qmltype Shortcut @@ -124,13 +125,35 @@ Q_QUICK_PRIVATE_EXPORT void qt_quick_set_shortcut_context_matcher(ContextMatcher QT_BEGIN_NAMESPACE -static QKeySequence valueToKeySequence(const QVariant &value) +static QKeySequence valueToKeySequence(const QVariant &value, const QQuickShortcut *const shortcut) { - if (value.userType() == QMetaType::Int) - return QKeySequence(static_cast(value.toInt())); + if (value.userType() == QMetaType::Int) { + const QVector s = + QKeySequence::keyBindings(static_cast(value.toInt())); + if (s.size() > 1) { + const QString templateString = QString::fromUtf16( + u"Shortcut: Only binding to one of multiple key bindings associated with %1. " + u"Use 'sequences: [ ]' to bind to all of them."); + qmlWarning(shortcut) + << templateString.arg(static_cast(value.toInt())); + } + return s.size() > 0 ? s[0] : QKeySequence {}; + } + return QKeySequence::fromString(value.toString()); } +static QList valueToKeySequences(const QVariant &value) +{ + if (value.userType() == QMetaType::Int) { + return QKeySequence::keyBindings(static_cast(value.toInt())); + } else { + QList result; + result.push_back(QKeySequence::fromString(value.toString())); + return result; + } +} + QQuickShortcut::QQuickShortcut(QObject *parent) : QObject(parent), m_enabled(true), m_completed(false), m_autorepeat(true), m_context(Qt::WindowShortcut) { @@ -172,7 +195,7 @@ void QQuickShortcut::setSequence(const QVariant &value) if (value == m_shortcut.userValue) return; - QKeySequence keySequence = valueToKeySequence(value); + QKeySequence keySequence = valueToKeySequence(value, this); ungrabShortcut(m_shortcut); m_shortcut.userValue = value; @@ -207,28 +230,42 @@ QVariantList QQuickShortcut::sequences() const void QQuickShortcut::setSequences(const QVariantList &values) { - QVector remainder = m_shortcuts.mid(values.count()); - m_shortcuts.resize(values.count()); - - bool changed = !remainder.isEmpty(); - for (int i = 0; i < values.count(); ++i) { - const QVariant &value = values.at(i); - Shortcut& shortcut = m_shortcuts[i]; - if (value == shortcut.userValue) - continue; - - QKeySequence keySequence = valueToKeySequence(value); - - ungrabShortcut(shortcut); - shortcut.userValue = value; - shortcut.keySequence = keySequence; - grabShortcut(shortcut, m_context); + // convert QVariantList to QVector + QVector requestedShortcuts; + for (const QVariant &v : values) { + const QVector list = valueToKeySequences(v); + for (const QKeySequence &s : list) { + Shortcut sc; + sc.userValue = v; + sc.keySequence = s; + requestedShortcuts.push_back(sc); + } + } - changed = true; + // if nothing has changed, just return: + if (m_shortcuts.size() == requestedShortcuts.size()) { + bool changed = false; + for (int i = 0; i < requestedShortcuts.count(); ++i) { + const Shortcut &requestedShortcut = requestedShortcuts[i]; + const Shortcut &shortcut = m_shortcuts[i]; + if (!(requestedShortcut.userValue == shortcut.userValue + && requestedShortcut.keySequence == shortcut.keySequence)) { + changed = true; + break; + } + } + if (!changed) { + return; + } } - if (changed) - emit sequencesChanged(); + for (Shortcut &s : m_shortcuts) + ungrabShortcut(s); + m_shortcuts = requestedShortcuts; + for (Shortcut &s : m_shortcuts) + grabShortcut(s, m_context); + + emit sequencesChanged(); } /*! -- cgit v1.2.3