macOS: Don't treat null-key as potential shortcut key

When mapping virtual keys and modifiers to their corresponding characters
via a keyboard layout we may hit combinations that do not produce any
characters. This can happen if there's no <key> element defined for the
virtual key, or if the output attribute of the element is empty (despite
the spec saying there should always be one UTF-16 code point in the output).

 https://developer.apple.com/library/archive/technotes/tn2056/_index.html

When that happens QAppleKeyMapper::keyMapForKey() will map the combination
to a null-QChar, resulting in the "key" being 0. We do not want to propagate
this back to the QShortcutMap machinery, as QShortcutMap does not validate
the keys coming out of QKeyMapper::possibleKeys(). In particular, it doesn't
check the isEmpty() or count() of the QKeySequences it creates. And even if
it did, QKeySequence itself seems to treat Qt::Key(0) + Qt::SomeModifier
as a non-empty sequence, so passing on 0-keys would still give weird bugs.

The user-visible result of passing back 0-keys is that QShortcutMap will
treat it as a partial match for any incoming key combination (as long as
some modifier is pressed that triggers the QShortcutMap machinery), which
resulting in eating the key press. This compounded the issue in QTBUG-95471.

Regression after fab3dfff7d53d496a31c5d2df972ddacfe861a4d.

Task-number: QTBUG-95471
Change-Id: I2e51ec86f4df2a708e1757be827ab74859be3c8b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit 99a4419647df14bf81d1837d22c9636957fd6257)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Tor Arne Vestbø 2021-08-15 18:24:59 +02:00 committed by Qt Cherry-pick Bot
parent 225105185d
commit f4fc178316

View File

@ -581,6 +581,8 @@ QList<int> QAppleKeyMapper::possibleKeys(const QKeyEvent *event) const
auto keyAfterApplyingModifiers = keyMap[i];
if (keyAfterApplyingModifiers == unmodifiedKey)
continue;
if (!keyAfterApplyingModifiers)
continue;
// Include key if event modifiers includes, or matches
// perfectly, the current candidate modifiers.