Fix the handling of dead keys and test the mechanism
An effort has been made to support more keyboard layouts that provide dead keys (US international, Mac-specific dead keys). The dead key is translated now at the event conversion phase, not when it is actually used for modifying keys, which simplifies the logic. Unittests have been created to check the translation mechanism. Fixes: QTBUG-86272 Change-Id: I07f7d63f5a37f8469c693b034b400da99379f519 Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
This commit is contained in:
parent
6d17697913
commit
3dc6fdc6d8
@ -7,6 +7,7 @@
|
||||
|
||||
#include <QtCore/private/qmakearray_p.h>
|
||||
#include <QtCore/private/qstringiterator_p.h>
|
||||
#include <QtCore/qregularexpression.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -18,19 +19,57 @@ bool isDeadKeyEvent(const char *key)
|
||||
return qstrncmp(key, WebDeadKeyValue.data(), WebDeadKeyValue.size()) == 0;
|
||||
}
|
||||
|
||||
Qt::Key webKeyToQtKey(const std::string &code, const std::string &key, bool isDeadKey)
|
||||
Qt::Key getKeyFromCode(const std::string &code)
|
||||
{
|
||||
if (auto mapping = QWasmKeyTranslator::mapWebKeyTextToQtKey(code.c_str()))
|
||||
return *mapping;
|
||||
|
||||
static QRegularExpression regex(QString(QStringLiteral(R"re((?:Key|Digit)(\w))re")));
|
||||
const auto codeQString = QString::fromStdString(code);
|
||||
const auto match = regex.match(codeQString);
|
||||
|
||||
if (!match.hasMatch())
|
||||
return Qt::Key_unknown;
|
||||
|
||||
constexpr size_t CharacterIndex = 1;
|
||||
return static_cast<Qt::Key>(match.capturedView(CharacterIndex).at(0).toLatin1());
|
||||
}
|
||||
|
||||
Qt::Key webKeyToQtKey(const std::string &code, const std::string &key, bool isDeadKey,
|
||||
QFlags<Qt::KeyboardModifier> modifiers)
|
||||
{
|
||||
if (isDeadKey) {
|
||||
if (auto mapping = QWasmKeyTranslator::mapWebKeyTextToQtKey(code.c_str()))
|
||||
return *mapping;
|
||||
}
|
||||
if (auto mapping = QWasmKeyTranslator::mapWebKeyTextToQtKey(key.c_str()))
|
||||
auto mapped = getKeyFromCode(code);
|
||||
switch (mapped) {
|
||||
case Qt::Key_U:
|
||||
return Qt::Key_Dead_Diaeresis;
|
||||
case Qt::Key_E:
|
||||
return Qt::Key_Dead_Acute;
|
||||
case Qt::Key_I:
|
||||
return Qt::Key_Dead_Circumflex;
|
||||
case Qt::Key_N:
|
||||
return Qt::Key_Dead_Tilde;
|
||||
case Qt::Key_QuoteLeft:
|
||||
return modifiers.testFlag(Qt::ShiftModifier) ? Qt::Key_Dead_Tilde : Qt::Key_Dead_Grave;
|
||||
case Qt::Key_6:
|
||||
return Qt::Key_Dead_Circumflex;
|
||||
case Qt::Key_Apostrophe:
|
||||
return modifiers.testFlag(Qt::ShiftModifier) ? Qt::Key_Dead_Diaeresis
|
||||
: Qt::Key_Dead_Acute;
|
||||
case Qt::Key_AsciiTilde:
|
||||
return Qt::Key_Dead_Tilde;
|
||||
default:
|
||||
return Qt::Key_unknown;
|
||||
}
|
||||
} else if (auto mapping = QWasmKeyTranslator::mapWebKeyTextToQtKey(key.c_str())) {
|
||||
return *mapping;
|
||||
if (isDeadKey)
|
||||
return Qt::Key_unknown;
|
||||
}
|
||||
|
||||
// cast to unicode key
|
||||
QString str = QString::fromUtf8(key.c_str()).toUpper();
|
||||
if (str.length() > 1)
|
||||
return Qt::Key_unknown;
|
||||
|
||||
QStringIterator i(str);
|
||||
return static_cast<Qt::Key>(i.next(0));
|
||||
}
|
||||
@ -65,9 +104,9 @@ KeyEvent::KeyEvent(EventType type, emscripten::val event) : Event(type, event["t
|
||||
const auto webKey = event["key"].as<std::string>();
|
||||
deadKey = isDeadKeyEvent(webKey.c_str());
|
||||
|
||||
key = webKeyToQtKey(code, webKey, deadKey);
|
||||
|
||||
modifiers = KeyboardModifier::getForEvent(event);
|
||||
key = webKeyToQtKey(code, webKey, deadKey, modifiers);
|
||||
|
||||
text = QString::fromUtf8(webKey);
|
||||
if (text.size() > 1)
|
||||
text.clear();
|
||||
|
@ -52,34 +52,17 @@ template<unsigned int Qt, char... WebChar>
|
||||
constexpr char Web2Qt<Qt, WebChar...>::storage[];
|
||||
|
||||
static constexpr const auto WebToQtKeyCodeMappings = qMakeArray(
|
||||
QSortedData<Web2Qt<Qt::Key_Escape, 'E', 's', 'c', 'a', 'p', 'e'>,
|
||||
Web2Qt<Qt::Key_Tab, 'T', 'a', 'b'>,
|
||||
Web2Qt<Qt::Key_Backspace, 'B', 'a', 'c', 'k', 's', 'p', 'a', 'c', 'e'>,
|
||||
Web2Qt<Qt::Key_Return, 'E', 'n', 't', 'e', 'r'>,
|
||||
Web2Qt<Qt::Key_Insert, 'I', 'n', 's', 'e', 'r', 't'>,
|
||||
Web2Qt<Qt::Key_Delete, 'D', 'e', 'l', 'e', 't', 'e'>,
|
||||
Web2Qt<Qt::Key_Pause, 'P', 'a', 'u', 's', 'e'>,
|
||||
Web2Qt<Qt::Key_Pause, 'C', 'l', 'e', 'a', 'r'>,
|
||||
Web2Qt<Qt::Key_Home, 'H', 'o', 'm', 'e'>, Web2Qt<Qt::Key_End, 'E', 'n', 'd'>,
|
||||
Web2Qt<Qt::Key_Left, 'A', 'r', 'r', 'o', 'w', 'L', 'e', 'f', 't'>,
|
||||
Web2Qt<Qt::Key_Up, 'A', 'r', 'r', 'o', 'w', 'U', 'p'>,
|
||||
Web2Qt<Qt::Key_Right, 'A', 'r', 'r', 'o', 'w', 'R', 'i', 'g', 'h', 't'>,
|
||||
Web2Qt<Qt::Key_Down, 'A', 'r', 'r', 'o', 'w', 'D', 'o', 'w', 'n'>,
|
||||
Web2Qt<Qt::Key_PageUp, 'P', 'a', 'g', 'e', 'U', 'p'>,
|
||||
Web2Qt<Qt::Key_PageDown, 'P', 'a', 'g', 'e', 'D', 'o', 'w', 'n'>,
|
||||
Web2Qt<Qt::Key_Shift, 'S', 'h', 'i', 'f', 't'>,
|
||||
Web2Qt<Qt::Key_Control, 'C', 'o', 'n', 't', 'r', 'o', 'l'>,
|
||||
Web2Qt<Qt::Key_Meta, 'M', 'e', 't', 'a'>, Web2Qt<Qt::Key_Meta, 'O', 'S'>,
|
||||
Web2Qt<Qt::Key_Alt, 'A', 'l', 't', 'L', 'e', 'f', 't'>,
|
||||
QSortedData<Web2Qt<Qt::Key_Alt, 'A', 'l', 't', 'L', 'e', 'f', 't'>,
|
||||
Web2Qt<Qt::Key_Alt, 'A', 'l', 't'>,
|
||||
Web2Qt<Qt::Key_AltGr, 'A', 'l', 't', 'R', 'i', 'g', 'h', 't'>,
|
||||
Web2Qt<Qt::Key_Apostrophe, 'Q', 'u', 'o', 't', 'e'>,
|
||||
Web2Qt<Qt::Key_Backspace, 'B', 'a', 'c', 'k', 's', 'p', 'a', 'c', 'e'>,
|
||||
Web2Qt<Qt::Key_CapsLock, 'C', 'a', 'p', 's', 'L', 'o', 'c', 'k'>,
|
||||
Web2Qt<Qt::Key_NumLock, 'N', 'u', 'm', 'L', 'o', 'c', 'k'>,
|
||||
Web2Qt<Qt::Key_ScrollLock, 'S', 'c', 'r', 'o', 'l', 'l', 'L', 'o', 'c', 'k'>,
|
||||
Web2Qt<Qt::Key_Control, 'C', 'o', 'n', 't', 'r', 'o', 'l'>,
|
||||
Web2Qt<Qt::Key_Delete, 'D', 'e', 'l', 'e', 't', 'e'>,
|
||||
Web2Qt<Qt::Key_Down, 'A', 'r', 'r', 'o', 'w', 'D', 'o', 'w', 'n'>,
|
||||
Web2Qt<Qt::Key_Escape, 'E', 's', 'c', 'a', 'p', 'e'>,
|
||||
Web2Qt<Qt::Key_F1, 'F', '1'>, Web2Qt<Qt::Key_F2, 'F', '2'>,
|
||||
Web2Qt<Qt::Key_F3, 'F', '3'>, Web2Qt<Qt::Key_F4, 'F', '4'>,
|
||||
Web2Qt<Qt::Key_F5, 'F', '5'>, Web2Qt<Qt::Key_F6, 'F', '6'>,
|
||||
Web2Qt<Qt::Key_F7, 'F', '7'>, Web2Qt<Qt::Key_F8, 'F', '8'>,
|
||||
Web2Qt<Qt::Key_F9, 'F', '9'>, Web2Qt<Qt::Key_F10, 'F', '1', '0'>,
|
||||
Web2Qt<Qt::Key_F11, 'F', '1', '1'>, Web2Qt<Qt::Key_F12, 'F', '1', '2'>,
|
||||
Web2Qt<Qt::Key_F13, 'F', '1', '3'>, Web2Qt<Qt::Key_F14, 'F', '1', '4'>,
|
||||
Web2Qt<Qt::Key_F15, 'F', '1', '5'>, Web2Qt<Qt::Key_F16, 'F', '1', '6'>,
|
||||
@ -87,34 +70,99 @@ static constexpr const auto WebToQtKeyCodeMappings = qMakeArray(
|
||||
Web2Qt<Qt::Key_F19, 'F', '1', '9'>, Web2Qt<Qt::Key_F20, 'F', '2', '0'>,
|
||||
Web2Qt<Qt::Key_F21, 'F', '2', '1'>, Web2Qt<Qt::Key_F22, 'F', '2', '2'>,
|
||||
Web2Qt<Qt::Key_F23, 'F', '2', '3'>,
|
||||
Web2Qt<Qt::Key_Paste, 'P', 'a', 's', 't', 'e'>,
|
||||
Web2Qt<Qt::Key_AltGr, 'A', 'l', 't', 'R', 'i', 'g', 'h', 't'>,
|
||||
Web2Qt<Qt::Key_F3, 'F', '3'>, Web2Qt<Qt::Key_F4, 'F', '4'>,
|
||||
Web2Qt<Qt::Key_F5, 'F', '5'>, Web2Qt<Qt::Key_F6, 'F', '6'>,
|
||||
Web2Qt<Qt::Key_F7, 'F', '7'>, Web2Qt<Qt::Key_F8, 'F', '8'>,
|
||||
Web2Qt<Qt::Key_F9, 'F', '9'>, Web2Qt<Qt::Key_F10, 'F', '1', '0'>,
|
||||
Web2Qt<Qt::Key_Help, 'H', 'e', 'l', 'p'>,
|
||||
Web2Qt<Qt::Key_yen, 'I', 'n', 't', 'l', 'Y', 'e', 'n'>,
|
||||
Web2Qt<Qt::Key_Menu, 'C', 'o', 'n', 't', 'e', 'x', 't', 'M', 'e', 'n',
|
||||
'u'>>::Data{});
|
||||
Web2Qt<Qt::Key_Home, 'H', 'o', 'm', 'e'>, Web2Qt<Qt::Key_End, 'E', 'n', 'd'>,
|
||||
Web2Qt<Qt::Key_Insert, 'I', 'n', 's', 'e', 'r', 't'>,
|
||||
Web2Qt<Qt::Key_Left, 'A', 'r', 'r', 'o', 'w', 'L', 'e', 'f', 't'>,
|
||||
Web2Qt<Qt::Key_Meta, 'M', 'e', 't', 'a'>, Web2Qt<Qt::Key_Meta, 'O', 'S'>,
|
||||
Web2Qt<Qt::Key_Menu, 'C', 'o', 'n', 't', 'e', 'x', 't', 'M', 'e', 'n', 'u'>,
|
||||
Web2Qt<Qt::Key_NumLock, 'N', 'u', 'm', 'L', 'o', 'c', 'k'>,
|
||||
Web2Qt<Qt::Key_PageDown, 'P', 'a', 'g', 'e', 'D', 'o', 'w', 'n'>,
|
||||
Web2Qt<Qt::Key_PageUp, 'P', 'a', 'g', 'e', 'U', 'p'>,
|
||||
Web2Qt<Qt::Key_Paste, 'P', 'a', 's', 't', 'e'>,
|
||||
Web2Qt<Qt::Key_Pause, 'C', 'l', 'e', 'a', 'r'>,
|
||||
Web2Qt<Qt::Key_Pause, 'P', 'a', 'u', 's', 'e'>,
|
||||
Web2Qt<Qt::Key_QuoteLeft, 'B', 'a', 'c', 'k', 'q', 'u', 'o', 't', 'e'>,
|
||||
Web2Qt<Qt::Key_QuoteLeft, 'I', 'n', 't', 'l', 'B', 'a', 'c', 'k', 's', 'l', 'a', 's', 'h'>,
|
||||
Web2Qt<Qt::Key_Return, 'E', 'n', 't', 'e', 'r'>,
|
||||
Web2Qt<Qt::Key_Right, 'A', 'r', 'r', 'o', 'w', 'R', 'i', 'g', 'h', 't'>,
|
||||
Web2Qt<Qt::Key_ScrollLock, 'S', 'c', 'r', 'o', 'l', 'l', 'L', 'o', 'c', 'k'>,
|
||||
Web2Qt<Qt::Key_Shift, 'S', 'h', 'i', 'f', 't'>,
|
||||
Web2Qt<Qt::Key_Tab, 'T', 'a', 'b'>,
|
||||
Web2Qt<Qt::Key_Up, 'A', 'r', 'r', 'o', 'w', 'U', 'p'>,
|
||||
Web2Qt<Qt::Key_yen, 'I', 'n', 't', 'l', 'Y', 'e', 'n'>>::Data{});
|
||||
|
||||
static constexpr const auto WebToQtKeyCodeMappingsWithShift = qMakeArray(
|
||||
static constexpr const auto DiacriticalCharsKeyToTextLowercase = qMakeArray(
|
||||
QSortedData<
|
||||
// shifted
|
||||
Web2Qt<Qt::Key_Agrave, '\xc3', '\x80'>, Web2Qt<Qt::Key_Aacute, '\xc3', '\x81'>,
|
||||
Web2Qt<Qt::Key_Aacute, '\xc3', '\xa1'>,
|
||||
Web2Qt<Qt::Key_Acircumflex, '\xc3', '\xa2'>,
|
||||
Web2Qt<Qt::Key_Adiaeresis, '\xc3', '\xa4'>,
|
||||
Web2Qt<Qt::Key_AE, '\xc3', '\xa6'>,
|
||||
Web2Qt<Qt::Key_Agrave, '\xc3', '\xa0'>,
|
||||
Web2Qt<Qt::Key_Aring, '\xc3', '\xa5'>,
|
||||
Web2Qt<Qt::Key_Atilde, '\xc3', '\xa3'>,
|
||||
Web2Qt<Qt::Key_Ccedilla, '\xc3', '\xa7'>,
|
||||
Web2Qt<Qt::Key_Eacute, '\xc3', '\xa9'>,
|
||||
Web2Qt<Qt::Key_Ecircumflex, '\xc3', '\xaa'>,
|
||||
Web2Qt<Qt::Key_Ediaeresis, '\xc3', '\xab'>,
|
||||
Web2Qt<Qt::Key_Egrave, '\xc3', '\xa8'>,
|
||||
Web2Qt<Qt::Key_Iacute, '\xc3', '\xad'>,
|
||||
Web2Qt<Qt::Key_Icircumflex, '\xc3', '\xae'>,
|
||||
Web2Qt<Qt::Key_Idiaeresis, '\xc3', '\xaf'>,
|
||||
Web2Qt<Qt::Key_Igrave, '\xc3', '\xac'>,
|
||||
Web2Qt<Qt::Key_Ntilde, '\xc3', '\xb1'>,
|
||||
Web2Qt<Qt::Key_Oacute, '\xc3', '\xb3'>,
|
||||
Web2Qt<Qt::Key_Ocircumflex, '\xc3', '\xb4'>,
|
||||
Web2Qt<Qt::Key_Odiaeresis, '\xc3', '\xb6'>,
|
||||
Web2Qt<Qt::Key_Ograve, '\xc3', '\xb2'>,
|
||||
Web2Qt<Qt::Key_Ooblique, '\xc3', '\xb8'>,
|
||||
Web2Qt<Qt::Key_Otilde, '\xc3', '\xb5'>,
|
||||
Web2Qt<Qt::Key_Uacute, '\xc3', '\xba'>,
|
||||
Web2Qt<Qt::Key_Ucircumflex, '\xc3', '\xbb'>,
|
||||
Web2Qt<Qt::Key_Udiaeresis, '\xc3', '\xbc'>,
|
||||
Web2Qt<Qt::Key_Ugrave, '\xc3', '\xb9'>,
|
||||
Web2Qt<Qt::Key_Yacute, '\xc3', '\xbd'>,
|
||||
Web2Qt<Qt::Key_ydiaeresis, '\xc3', '\xbf'>>::Data{});
|
||||
|
||||
static constexpr const auto DiacriticalCharsKeyToTextUppercase = qMakeArray(
|
||||
QSortedData<
|
||||
Web2Qt<Qt::Key_Aacute, '\xc3', '\x81'>,
|
||||
Web2Qt<Qt::Key_Acircumflex, '\xc3', '\x82'>,
|
||||
Web2Qt<Qt::Key_Adiaeresis, '\xc3', '\x84'>, Web2Qt<Qt::Key_AE, '\xc3', '\x86'>,
|
||||
Web2Qt<Qt::Key_Atilde, '\xc3', '\x83'>, Web2Qt<Qt::Key_Aring, '\xc3', '\x85'>,
|
||||
Web2Qt<Qt::Key_Egrave, '\xc3', '\x88'>, Web2Qt<Qt::Key_Eacute, '\xc3', '\x89'>,
|
||||
Web2Qt<Qt::Key_Ecircumflex, '\xc3', '\x8a'>,
|
||||
Web2Qt<Qt::Key_Ediaeresis, '\xc3', '\x8b'>, Web2Qt<Qt::Key_Iacute, '\xc3', '\x8d'>,
|
||||
Web2Qt<Qt::Key_Icircumflex, '\xc3', '\x8e'>,
|
||||
Web2Qt<Qt::Key_Idiaeresis, '\xc3', '\x8f'>, Web2Qt<Qt::Key_Igrave, '\xc3', '\x8c'>,
|
||||
Web2Qt<Qt::Key_Ocircumflex, '\xc3', '\x94'>,
|
||||
Web2Qt<Qt::Key_Odiaeresis, '\xc3', '\x96'>, Web2Qt<Qt::Key_Ograve, '\xc3', '\x92'>,
|
||||
Web2Qt<Qt::Key_Oacute, '\xc3', '\x93'>, Web2Qt<Qt::Key_Ooblique, '\xc3', '\x98'>,
|
||||
Web2Qt<Qt::Key_Otilde, '\xc3', '\x95'>, Web2Qt<Qt::Key_Ucircumflex, '\xc3', '\x9b'>,
|
||||
Web2Qt<Qt::Key_Udiaeresis, '\xc3', '\x9c'>, Web2Qt<Qt::Key_Ugrave, '\xc3', '\x99'>,
|
||||
Web2Qt<Qt::Key_Uacute, '\xc3', '\x9a'>, Web2Qt<Qt::Key_Ntilde, '\xc3', '\x91'>,
|
||||
Web2Qt<Qt::Key_Adiaeresis, '\xc3', '\x84'>,
|
||||
Web2Qt<Qt::Key_AE, '\xc3', '\x86'>,
|
||||
Web2Qt<Qt::Key_Agrave, '\xc3', '\x80'>,
|
||||
Web2Qt<Qt::Key_Aring, '\xc3', '\x85'>,
|
||||
Web2Qt<Qt::Key_Atilde, '\xc3', '\x83'>,
|
||||
Web2Qt<Qt::Key_Ccedilla, '\xc3', '\x87'>,
|
||||
Web2Qt<Qt::Key_ydiaeresis, '\xc3', '\x8f'>,
|
||||
Web2Qt<Qt::Key_Yacute, '\xc3', '\x9d'>>::Data{});
|
||||
Web2Qt<Qt::Key_Eacute, '\xc3', '\x89'>,
|
||||
Web2Qt<Qt::Key_Ecircumflex, '\xc3', '\x8a'>,
|
||||
Web2Qt<Qt::Key_Ediaeresis, '\xc3', '\x8b'>,
|
||||
Web2Qt<Qt::Key_Egrave, '\xc3', '\x88'>,
|
||||
Web2Qt<Qt::Key_Iacute, '\xc3', '\x8d'>,
|
||||
Web2Qt<Qt::Key_Icircumflex, '\xc3', '\x8e'>,
|
||||
Web2Qt<Qt::Key_Idiaeresis, '\xc3', '\x8f'>,
|
||||
Web2Qt<Qt::Key_Igrave, '\xc3', '\x8c'>,
|
||||
Web2Qt<Qt::Key_Ntilde, '\xc3', '\x91'>,
|
||||
Web2Qt<Qt::Key_Oacute, '\xc3', '\x93'>,
|
||||
Web2Qt<Qt::Key_Ocircumflex, '\xc3', '\x94'>,
|
||||
Web2Qt<Qt::Key_Odiaeresis, '\xc3', '\x96'>,
|
||||
Web2Qt<Qt::Key_Ograve, '\xc3', '\x92'>,
|
||||
Web2Qt<Qt::Key_Ooblique, '\xc3', '\x98'>,
|
||||
Web2Qt<Qt::Key_Otilde, '\xc3', '\x95'>,
|
||||
Web2Qt<Qt::Key_Uacute, '\xc3', '\x9a'>,
|
||||
Web2Qt<Qt::Key_Ucircumflex, '\xc3', '\x9b'>,
|
||||
Web2Qt<Qt::Key_Udiaeresis, '\xc3', '\x9c'>,
|
||||
Web2Qt<Qt::Key_Ugrave, '\xc3', '\x99'>,
|
||||
Web2Qt<Qt::Key_Yacute, '\xc3', '\x9d'>,
|
||||
Web2Qt<Qt::Key_ydiaeresis, '\xc5', '\xb8'>>::Data{});
|
||||
|
||||
static_assert(DiacriticalCharsKeyToTextLowercase.size()
|
||||
== DiacriticalCharsKeyToTextUppercase.size(),
|
||||
"Add the new key to both arrays");
|
||||
|
||||
struct KeyMapping
|
||||
{
|
||||
@ -169,23 +217,15 @@ static Qt::Key find(const KeyMapping (&map)[N], Qt::Key key) noexcept
|
||||
Qt::Key translateBaseKeyUsingDeadKey(Qt::Key accentBaseKey, Qt::Key deadKey)
|
||||
{
|
||||
switch (deadKey) {
|
||||
case Qt::Key_QuoteLeft: {
|
||||
// ` macOS: Key_Dead_Grave
|
||||
return platform() == Platform::MacOS ? find(graveKeyTable, accentBaseKey)
|
||||
: find(diaeresisKeyTable, accentBaseKey);
|
||||
}
|
||||
case Qt::Key_O: // ´ Key_Dead_Grave
|
||||
case Qt::Key_Dead_Grave:
|
||||
return find(graveKeyTable, accentBaseKey);
|
||||
case Qt::Key_E: // ´ Key_Dead_Acute
|
||||
case Qt::Key_Dead_Acute:
|
||||
return find(acuteKeyTable, accentBaseKey);
|
||||
case Qt::Key_AsciiTilde:
|
||||
case Qt::Key_N: // Key_Dead_Tilde
|
||||
case Qt::Key_Dead_Tilde:
|
||||
return find(tildeKeyTable, accentBaseKey);
|
||||
case Qt::Key_U: // ¨ Key_Dead_Diaeresis
|
||||
case Qt::Key_Dead_Diaeresis:
|
||||
return find(diaeresisKeyTable, accentBaseKey);
|
||||
case Qt::Key_I: // macOS Key_Dead_Circumflex
|
||||
case Qt::Key_6: // linux
|
||||
case Qt::Key_Apostrophe: // linux
|
||||
case Qt::Key_Dead_Circumflex:
|
||||
return find(circumflexKeyTable, accentBaseKey);
|
||||
default:
|
||||
return Qt::Key_unknown;
|
||||
@ -216,32 +256,38 @@ QWasmDeadKeySupport::~QWasmDeadKeySupport() = default;
|
||||
|
||||
void QWasmDeadKeySupport::applyDeadKeyTranslations(KeyEvent *event)
|
||||
{
|
||||
if (event->deadKey || event->key == Qt::Key_AltGr) {
|
||||
if (event->modifiers.testFlag(Qt::ShiftModifier) && event->key == Qt::Key_QuoteLeft)
|
||||
event->key = Qt::Key_AsciiTilde;
|
||||
if (event->deadKey) {
|
||||
m_activeDeadKey = event->key;
|
||||
} else if (m_activeDeadKey != Qt::Key_unknown
|
||||
&& (m_keyModifiedByDeadKeyOnPress == Qt::Key_unknown
|
||||
|| m_keyModifiedByDeadKeyOnPress == event->key)) {
|
||||
&& (((m_keyModifiedByDeadKeyOnPress == Qt::Key_unknown
|
||||
&& event->type == EventType::KeyDown))
|
||||
|| (m_keyModifiedByDeadKeyOnPress == event->key
|
||||
&& event->type == EventType::KeyUp))) {
|
||||
const Qt::Key baseKey = event->key;
|
||||
const Qt::Key translatedKey = translateBaseKeyUsingDeadKey(baseKey, m_activeDeadKey);
|
||||
if (translatedKey != Qt::Key_unknown)
|
||||
if (translatedKey != Qt::Key_unknown) {
|
||||
event->key = translatedKey;
|
||||
|
||||
if (auto foundText = event->modifiers.testFlag(Qt::ShiftModifier)
|
||||
? findKeyTextByKeyId(WebToQtKeyCodeMappingsWithShift, event->key)
|
||||
: findKeyTextByKeyId(WebToQtKeyCodeMappings, event->key)) {
|
||||
auto foundText = event->modifiers.testFlag(Qt::ShiftModifier)
|
||||
? findKeyTextByKeyId(DiacriticalCharsKeyToTextUppercase, event->key)
|
||||
: findKeyTextByKeyId(DiacriticalCharsKeyToTextLowercase, event->key);
|
||||
Q_ASSERT(foundText.has_value());
|
||||
event->text = foundText->size() == 1 ? *foundText : QString();
|
||||
}
|
||||
|
||||
if (!event->text.isEmpty()) {
|
||||
if (event->type == EventType::KeyDown) {
|
||||
Q_ASSERT(m_keyModifiedByDeadKeyOnPress == Qt::Key_unknown);
|
||||
m_activeDeadKey = Qt::Key_unknown;
|
||||
// Assume the first keypress with an active dead key is treated as modified,
|
||||
// regardless of whether it has actually been modified or not. Take into account
|
||||
// only events that produce actual key text.
|
||||
if (!event->text.isEmpty())
|
||||
m_keyModifiedByDeadKeyOnPress = baseKey;
|
||||
} else {
|
||||
Q_ASSERT(event->type == EventType::KeyUp);
|
||||
Q_ASSERT(m_keyModifiedByDeadKeyOnPress == baseKey);
|
||||
m_activeDeadKey = Qt::Key_unknown;
|
||||
m_keyModifiedByDeadKeyOnPress = Qt::Key_unknown;
|
||||
m_activeDeadKey = Qt::Key_unknown;
|
||||
}
|
||||
event->text = foundText->size() == 1 ? *foundText : QString();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,3 +29,14 @@ qt_internal_add_test(tst_qwasmwindowstack
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
||||
|
||||
qt_internal_add_test(tst_qwasmkeytranslator
|
||||
SOURCES
|
||||
tst_qwasmkeytranslator.cpp
|
||||
DEFINES
|
||||
QT_NO_FOREACH
|
||||
LIBRARIES
|
||||
Qt::GuiPrivate
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
)
|
||||
|
425
tests/auto/wasm/tst_qwasmkeytranslator.cpp
Normal file
425
tests/auto/wasm/tst_qwasmkeytranslator.cpp
Normal file
@ -0,0 +1,425 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "../../../src/plugins/platforms/wasm/qwasmkeytranslator.h"
|
||||
|
||||
#include "../../../src/plugins/platforms/wasm/qwasmevent.h"
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <emscripten/val.h>
|
||||
|
||||
namespace {
|
||||
emscripten::val makeDeadKeyJsEvent(QString code, Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
auto jsEvent = emscripten::val::object();
|
||||
jsEvent.set("code", emscripten::val(code.toStdString()));
|
||||
jsEvent.set("key", emscripten::val("Dead"));
|
||||
jsEvent.set("shiftKey", emscripten::val(modifiers.testFlag(Qt::ShiftModifier)));
|
||||
jsEvent.set("ctrlKey", emscripten::val(false));
|
||||
jsEvent.set("altKey", emscripten::val(false));
|
||||
jsEvent.set("metaKey", emscripten::val(false));
|
||||
|
||||
return jsEvent;
|
||||
}
|
||||
|
||||
emscripten::val makeKeyJsEvent(QString code, QString key, Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
auto jsEvent = emscripten::val::object();
|
||||
jsEvent.set("code", emscripten::val(code.toStdString()));
|
||||
jsEvent.set("key", emscripten::val(key.toStdString()));
|
||||
jsEvent.set("shiftKey", emscripten::val(modifiers.testFlag(Qt::ShiftModifier)));
|
||||
jsEvent.set("ctrlKey", emscripten::val(modifiers.testFlag(Qt::ControlModifier)));
|
||||
jsEvent.set("altKey", emscripten::val(modifiers.testFlag(Qt::AltModifier)));
|
||||
jsEvent.set("metaKey", emscripten::val(modifiers.testFlag(Qt::MetaModifier)));
|
||||
|
||||
return jsEvent;
|
||||
}
|
||||
} // unnamed namespace
|
||||
|
||||
class tst_QWasmKeyTranslator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QWasmKeyTranslator() = default;
|
||||
|
||||
private slots:
|
||||
void init();
|
||||
|
||||
void modifyByDeadKey_data();
|
||||
void modifyByDeadKey();
|
||||
void deadKeyModifiesOnlyOneKeyPressAndUp();
|
||||
void deadKeyIgnoresKeyUpPrecedingKeyDown();
|
||||
void onlyKeysProducingTextAreModifiedByDeadKeys();
|
||||
};
|
||||
|
||||
void tst_QWasmKeyTranslator::init() { }
|
||||
|
||||
void tst_QWasmKeyTranslator::modifyByDeadKey_data()
|
||||
{
|
||||
QTest::addColumn<QString>("deadKeyCode");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("deadKeyModifiers");
|
||||
QTest::addColumn<QString>("targetKeyCode");
|
||||
QTest::addColumn<QString>("targetKey");
|
||||
QTest::addColumn<Qt::Key>("targetQtKey");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
|
||||
QTest::addColumn<QString>("expectedModifiedKey");
|
||||
|
||||
QTest::newRow("à (Backquote)") << "Backquote" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "a" << Qt::Key_Agrave << Qt::KeyboardModifiers() << "à";
|
||||
QTest::newRow("À (Backquote)")
|
||||
<< "Backquote" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "A" << Qt::Key_Agrave << Qt::KeyboardModifiers(Qt::ShiftModifier) << "À";
|
||||
QTest::newRow("à (IntlBackslash)") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "a" << Qt::Key_Agrave << Qt::KeyboardModifiers() << "à";
|
||||
QTest::newRow("À (IntlBackslash)")
|
||||
<< "IntlBackslash" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "A" << Qt::Key_Agrave << Qt::KeyboardModifiers(Qt::ShiftModifier) << "À";
|
||||
QTest::newRow("á (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "a" << Qt::Key_Aacute << Qt::KeyboardModifiers() << "á";
|
||||
QTest::newRow("Á (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "A" << Qt::Key_Aacute << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Á";
|
||||
QTest::newRow("á") << "KeyE" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "a" << Qt::Key_Aacute << Qt::KeyboardModifiers() << "á";
|
||||
QTest::newRow("Á") << "KeyE" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "A" << Qt::Key_Aacute << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Á";
|
||||
QTest::newRow("ä (Mac Umlaut)") << "KeyU" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "a" << Qt::Key_Adiaeresis << Qt::KeyboardModifiers() << "ä";
|
||||
QTest::newRow("Ä (Mac Umlaut)")
|
||||
<< "KeyU" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "A" << Qt::Key_Adiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ä";
|
||||
QTest::newRow("ä (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyA"
|
||||
<< "a" << Qt::Key_Adiaeresis << Qt::KeyboardModifiers() << "ä";
|
||||
QTest::newRow("Ä (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyA"
|
||||
<< "A" << Qt::Key_Adiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ä";
|
||||
QTest::newRow("â") << "KeyI" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "a" << Qt::Key_Acircumflex << Qt::KeyboardModifiers() << "â";
|
||||
QTest::newRow("Â") << "KeyI" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "A" << Qt::Key_Acircumflex << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Â";
|
||||
QTest::newRow("â (^ key)") << "Digit6" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyA"
|
||||
<< "a" << Qt::Key_Acircumflex << Qt::KeyboardModifiers() << "â";
|
||||
QTest::newRow("Â (^ key)") << "Digit6" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyA"
|
||||
<< "A" << Qt::Key_Acircumflex
|
||||
<< Qt::KeyboardModifiers(Qt::ShiftModifier) << "Â";
|
||||
QTest::newRow("ã") << "KeyN" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "a" << Qt::Key_Atilde << Qt::KeyboardModifiers() << "ã";
|
||||
QTest::newRow("Ã") << "KeyN" << Qt::KeyboardModifiers() << "KeyA"
|
||||
<< "A" << Qt::Key_Atilde << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ã";
|
||||
|
||||
QTest::newRow("è (Backquote)") << "Backquote" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "e" << Qt::Key_Egrave << Qt::KeyboardModifiers() << "è";
|
||||
QTest::newRow("È (Backquote)")
|
||||
<< "Backquote" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "E" << Qt::Key_Egrave << Qt::KeyboardModifiers(Qt::ShiftModifier) << "È";
|
||||
QTest::newRow("è") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "e" << Qt::Key_Egrave << Qt::KeyboardModifiers() << "è";
|
||||
QTest::newRow("È") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "E" << Qt::Key_Egrave << Qt::KeyboardModifiers(Qt::ShiftModifier) << "È";
|
||||
QTest::newRow("é") << "KeyE" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "e" << Qt::Key_Eacute << Qt::KeyboardModifiers() << "é";
|
||||
QTest::newRow("É") << "KeyE" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "E" << Qt::Key_Eacute << Qt::KeyboardModifiers(Qt::ShiftModifier) << "É";
|
||||
QTest::newRow("é (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "e" << Qt::Key_Eacute << Qt::KeyboardModifiers() << "é";
|
||||
QTest::newRow("É (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "E" << Qt::Key_Eacute << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "É";
|
||||
QTest::newRow("ë (Mac Umlaut)") << "KeyU" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "e" << Qt::Key_Ediaeresis << Qt::KeyboardModifiers() << "ë";
|
||||
QTest::newRow("Ë (Mac Umlaut)")
|
||||
<< "KeyU" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "E" << Qt::Key_Ediaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ë";
|
||||
QTest::newRow("ë (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyE"
|
||||
<< "e" << Qt::Key_Ediaeresis << Qt::KeyboardModifiers() << "ë";
|
||||
QTest::newRow("Ë (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyE"
|
||||
<< "E" << Qt::Key_Ediaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ë";
|
||||
QTest::newRow("ê") << "KeyI" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "e" << Qt::Key_Ecircumflex << Qt::KeyboardModifiers() << "ê";
|
||||
QTest::newRow("Ê") << "KeyI" << Qt::KeyboardModifiers() << "KeyE"
|
||||
<< "E" << Qt::Key_Ecircumflex << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Ê";
|
||||
QTest::newRow("ê (^ key)") << "Digit6" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyE"
|
||||
<< "e" << Qt::Key_Ecircumflex << Qt::KeyboardModifiers() << "ê";
|
||||
QTest::newRow("Ê (^ key)") << "Digit6" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyE"
|
||||
<< "E" << Qt::Key_Ecircumflex
|
||||
<< Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ê";
|
||||
|
||||
QTest::newRow("ì (Backquote)") << "Backquote" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "i" << Qt::Key_Igrave << Qt::KeyboardModifiers() << "ì";
|
||||
QTest::newRow("Ì (Backquote)")
|
||||
<< "Backquote" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "I" << Qt::Key_Igrave << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ì";
|
||||
QTest::newRow("ì") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "i" << Qt::Key_Igrave << Qt::KeyboardModifiers() << "ì";
|
||||
QTest::newRow("Ì") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "I" << Qt::Key_Igrave << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ì";
|
||||
QTest::newRow("í") << "KeyE" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "i" << Qt::Key_Iacute << Qt::KeyboardModifiers() << "í";
|
||||
QTest::newRow("Í") << "KeyE" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "I" << Qt::Key_Iacute << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Í";
|
||||
QTest::newRow("í (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "i" << Qt::Key_Iacute << Qt::KeyboardModifiers() << "í";
|
||||
QTest::newRow("Í (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "I" << Qt::Key_Iacute << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Í";
|
||||
QTest::newRow("ï (Mac Umlaut)") << "KeyU" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "i" << Qt::Key_Idiaeresis << Qt::KeyboardModifiers() << "ï";
|
||||
QTest::newRow("Ï (Mac Umlaut)")
|
||||
<< "KeyU" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "I" << Qt::Key_Idiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ï";
|
||||
QTest::newRow("ï (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyI"
|
||||
<< "i" << Qt::Key_Idiaeresis << Qt::KeyboardModifiers() << "ï";
|
||||
QTest::newRow("Ï (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyI"
|
||||
<< "I" << Qt::Key_Idiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ï";
|
||||
QTest::newRow("î") << "KeyI" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "i" << Qt::Key_Icircumflex << Qt::KeyboardModifiers() << "î";
|
||||
QTest::newRow("Î") << "KeyI" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "I" << Qt::Key_Icircumflex << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Î";
|
||||
QTest::newRow("î (^ key)") << "Digit6" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "i" << Qt::Key_Icircumflex << Qt::KeyboardModifiers() << "î";
|
||||
QTest::newRow("Î (^ key)") << "Digit6" << Qt::KeyboardModifiers() << "KeyI"
|
||||
<< "I" << Qt::Key_Icircumflex
|
||||
<< Qt::KeyboardModifiers(Qt::ShiftModifier) << "Î";
|
||||
|
||||
QTest::newRow("ñ") << "KeyN" << Qt::KeyboardModifiers() << "KeyN"
|
||||
<< "n" << Qt::Key_Ntilde << Qt::KeyboardModifiers() << "ñ";
|
||||
QTest::newRow("Ñ") << "KeyN" << Qt::KeyboardModifiers() << "KeyN"
|
||||
<< "N" << Qt::Key_Ntilde << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ñ";
|
||||
|
||||
QTest::newRow("ò (Backquote)") << "Backquote" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "o" << Qt::Key_Ograve << Qt::KeyboardModifiers() << "ò";
|
||||
QTest::newRow("Ò (Backquote)")
|
||||
<< "Backquote" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "O" << Qt::Key_Ograve << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ò";
|
||||
QTest::newRow("ò") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "o" << Qt::Key_Ograve << Qt::KeyboardModifiers() << "ò";
|
||||
QTest::newRow("Ò") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "O" << Qt::Key_Ograve << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ò";
|
||||
QTest::newRow("ó") << "KeyE" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "o" << Qt::Key_Oacute << Qt::KeyboardModifiers() << "ó";
|
||||
QTest::newRow("Ó") << "KeyE" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "O" << Qt::Key_Oacute << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ó";
|
||||
QTest::newRow("ó (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "o" << Qt::Key_Oacute << Qt::KeyboardModifiers() << "ó";
|
||||
QTest::newRow("Ó (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "O" << Qt::Key_Oacute << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Ó";
|
||||
QTest::newRow("ö (Mac Umlaut)") << "KeyU" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "o" << Qt::Key_Odiaeresis << Qt::KeyboardModifiers() << "ö";
|
||||
QTest::newRow("Ö (Mac Umlaut)")
|
||||
<< "KeyU" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "O" << Qt::Key_Odiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ö";
|
||||
QTest::newRow("ö (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyO"
|
||||
<< "o" << Qt::Key_Odiaeresis << Qt::KeyboardModifiers() << "ö";
|
||||
QTest::newRow("Ö (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyO"
|
||||
<< "O" << Qt::Key_Odiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ö";
|
||||
QTest::newRow("ô") << "KeyI" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "o" << Qt::Key_Ocircumflex << Qt::KeyboardModifiers() << "ô";
|
||||
QTest::newRow("Ô") << "KeyI" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "O" << Qt::Key_Ocircumflex << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Ô";
|
||||
QTest::newRow("ô (^ key)") << "Digit6" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyO"
|
||||
<< "o" << Qt::Key_Ocircumflex << Qt::KeyboardModifiers() << "ô";
|
||||
QTest::newRow("Ô (^ key)") << "Digit6" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyO"
|
||||
<< "O" << Qt::Key_Ocircumflex
|
||||
<< Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ô";
|
||||
QTest::newRow("õ") << "KeyN" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "o" << Qt::Key_Otilde << Qt::KeyboardModifiers() << "õ";
|
||||
QTest::newRow("Õ") << "KeyN" << Qt::KeyboardModifiers() << "KeyO"
|
||||
<< "O" << Qt::Key_Otilde << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Õ";
|
||||
|
||||
QTest::newRow("ù (Backquote)") << "Backquote" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "u" << Qt::Key_Ugrave << Qt::KeyboardModifiers() << "ù";
|
||||
QTest::newRow("Ù (Backquote)")
|
||||
<< "Backquote" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "U" << Qt::Key_Ugrave << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ù";
|
||||
QTest::newRow("ù") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "u" << Qt::Key_Ugrave << Qt::KeyboardModifiers() << "ù";
|
||||
QTest::newRow("Ù") << "IntlBackslash" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "U" << Qt::Key_Ugrave << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ù";
|
||||
QTest::newRow("ú") << "KeyE" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "u" << Qt::Key_Uacute << Qt::KeyboardModifiers() << "ú";
|
||||
QTest::newRow("Ú") << "KeyE" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "U" << Qt::Key_Uacute << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ú";
|
||||
QTest::newRow("ú (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "u" << Qt::Key_Uacute << Qt::KeyboardModifiers() << "ú";
|
||||
QTest::newRow("Ú (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "U" << Qt::Key_Uacute << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Ú";
|
||||
QTest::newRow("ü (Mac Umlaut)") << "KeyU" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "u" << Qt::Key_Udiaeresis << Qt::KeyboardModifiers() << "ü";
|
||||
QTest::newRow("Ü (Mac Umlaut)")
|
||||
<< "KeyU" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "U" << Qt::Key_Udiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ü";
|
||||
QTest::newRow("ü (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyU"
|
||||
<< "u" << Qt::Key_Udiaeresis << Qt::KeyboardModifiers() << "ü";
|
||||
QTest::newRow("Ü (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyU"
|
||||
<< "U" << Qt::Key_Udiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ü";
|
||||
QTest::newRow("û") << "KeyI" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "û" << Qt::Key_Ucircumflex << Qt::KeyboardModifiers() << "û";
|
||||
QTest::newRow("Û") << "KeyI" << Qt::KeyboardModifiers() << "KeyU"
|
||||
<< "U" << Qt::Key_Ucircumflex << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Û";
|
||||
QTest::newRow("û (^ key)") << "Digit6" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyU"
|
||||
<< "û" << Qt::Key_Ucircumflex << Qt::KeyboardModifiers() << "û";
|
||||
QTest::newRow("Û (^ key)") << "Digit6" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyU"
|
||||
<< "U" << Qt::Key_Ucircumflex
|
||||
<< Qt::KeyboardModifiers(Qt::ShiftModifier) << "Û";
|
||||
|
||||
QTest::newRow("ý") << "KeyE" << Qt::KeyboardModifiers() << "KeyY"
|
||||
<< "y" << Qt::Key_Yacute << Qt::KeyboardModifiers() << "ý";
|
||||
QTest::newRow("Ý") << "KeyE" << Qt::KeyboardModifiers() << "KeyY"
|
||||
<< "Y" << Qt::Key_Yacute << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ý";
|
||||
QTest::newRow("ý (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyY"
|
||||
<< "y" << Qt::Key_Yacute << Qt::KeyboardModifiers() << "ý";
|
||||
QTest::newRow("Ý (Quote)") << "Quote" << Qt::KeyboardModifiers() << "KeyY"
|
||||
<< "Y" << Qt::Key_Yacute << Qt::KeyboardModifiers(Qt::ShiftModifier)
|
||||
<< "Ý";
|
||||
QTest::newRow("ÿ (Mac Umlaut)") << "KeyU" << Qt::KeyboardModifiers() << "KeyY"
|
||||
<< "y" << Qt::Key_ydiaeresis << Qt::KeyboardModifiers() << "ÿ";
|
||||
QTest::newRow("Ÿ (Mac Umlaut)")
|
||||
<< "KeyU" << Qt::KeyboardModifiers() << "KeyY"
|
||||
<< "Y" << Qt::Key_ydiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ÿ";
|
||||
QTest::newRow("ÿ (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyY"
|
||||
<< "y" << Qt::Key_ydiaeresis << Qt::KeyboardModifiers() << "ÿ";
|
||||
QTest::newRow("Ÿ (Shift+Quote)")
|
||||
<< "Quote" << Qt::KeyboardModifiers(Qt::ShiftModifier) << "KeyY"
|
||||
<< "Y" << Qt::Key_ydiaeresis << Qt::KeyboardModifiers(Qt::ShiftModifier) << "Ÿ";
|
||||
}
|
||||
|
||||
void tst_QWasmKeyTranslator::modifyByDeadKey()
|
||||
{
|
||||
QFETCH(QString, deadKeyCode);
|
||||
QFETCH(Qt::KeyboardModifiers, deadKeyModifiers);
|
||||
QFETCH(QString, targetKeyCode);
|
||||
QFETCH(QString, targetKey);
|
||||
QFETCH(Qt::Key, targetQtKey);
|
||||
QFETCH(Qt::KeyboardModifiers, modifiers);
|
||||
QFETCH(QString, expectedModifiedKey);
|
||||
|
||||
QWasmDeadKeySupport deadKeySupport;
|
||||
|
||||
KeyEvent event(EventType::KeyDown, makeDeadKeyJsEvent(deadKeyCode, deadKeyModifiers));
|
||||
QCOMPARE(event.deadKey, true);
|
||||
|
||||
deadKeySupport.applyDeadKeyTranslations(&event);
|
||||
|
||||
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent(targetKeyCode, targetKey, modifiers));
|
||||
QCOMPARE(eDown.deadKey, false);
|
||||
deadKeySupport.applyDeadKeyTranslations(&eDown);
|
||||
QCOMPARE(eDown.deadKey, false);
|
||||
QCOMPARE(eDown.text, expectedModifiedKey);
|
||||
QCOMPARE(eDown.key, targetQtKey);
|
||||
|
||||
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent(targetKeyCode, targetKey, modifiers));
|
||||
QCOMPARE(eUp.deadKey, false);
|
||||
deadKeySupport.applyDeadKeyTranslations(&eUp);
|
||||
QCOMPARE(eUp.text, expectedModifiedKey);
|
||||
QCOMPARE(eUp.key, targetQtKey);
|
||||
}
|
||||
|
||||
void tst_QWasmKeyTranslator::deadKeyModifiesOnlyOneKeyPressAndUp()
|
||||
{
|
||||
QWasmDeadKeySupport deadKeySupport;
|
||||
KeyEvent event(EventType::KeyDown, makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&event);
|
||||
|
||||
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&eDown);
|
||||
QCOMPARE(eDown.text, "ü");
|
||||
QCOMPARE(eDown.key, Qt::Key_Udiaeresis);
|
||||
|
||||
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&eUp);
|
||||
QCOMPARE(eUp.text, "ü");
|
||||
QCOMPARE(eUp.key, Qt::Key_Udiaeresis);
|
||||
|
||||
KeyEvent eDown2(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&eDown2);
|
||||
QCOMPARE(eDown2.text, "u");
|
||||
QCOMPARE(eDown2.key, Qt::Key_U);
|
||||
|
||||
KeyEvent eUp2(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&eUp2);
|
||||
QCOMPARE(eUp2.text, "u");
|
||||
QCOMPARE(eUp2.key, Qt::Key_U);
|
||||
}
|
||||
|
||||
void tst_QWasmKeyTranslator::deadKeyIgnoresKeyUpPrecedingKeyDown()
|
||||
{
|
||||
QWasmDeadKeySupport deadKeySupport;
|
||||
|
||||
KeyEvent deadKeyDownEvent(EventType::KeyDown,
|
||||
makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&deadKeyDownEvent);
|
||||
|
||||
KeyEvent deadKeyUpEvent(EventType::KeyUp, makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&deadKeyUpEvent);
|
||||
|
||||
KeyEvent otherKeyUpEvent(EventType::KeyUp,
|
||||
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&otherKeyUpEvent);
|
||||
|
||||
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&eDown);
|
||||
QCOMPARE(eDown.text, "ü");
|
||||
QCOMPARE(eDown.key, Qt::Key_Udiaeresis);
|
||||
|
||||
KeyEvent yetAnotherKeyUpEvent(
|
||||
EventType::KeyUp, makeKeyJsEvent("ControlLeft", "Control", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&yetAnotherKeyUpEvent);
|
||||
|
||||
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&eUp);
|
||||
QCOMPARE(eUp.text, "ü");
|
||||
QCOMPARE(eUp.key, Qt::Key_Udiaeresis);
|
||||
}
|
||||
|
||||
void tst_QWasmKeyTranslator::onlyKeysProducingTextAreModifiedByDeadKeys()
|
||||
{
|
||||
QWasmDeadKeySupport deadKeySupport;
|
||||
|
||||
KeyEvent deadKeyDownEvent(EventType::KeyDown,
|
||||
makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&deadKeyDownEvent);
|
||||
|
||||
KeyEvent noTextKeyDown(EventType::KeyDown,
|
||||
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&noTextKeyDown);
|
||||
QCOMPARE(noTextKeyDown.text, "");
|
||||
QCOMPARE(noTextKeyDown.key, Qt::Key_Alt);
|
||||
|
||||
KeyEvent noTextKeyUp(EventType::KeyUp,
|
||||
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&noTextKeyUp);
|
||||
QCOMPARE(noTextKeyDown.text, "");
|
||||
QCOMPARE(noTextKeyDown.key, Qt::Key_Alt);
|
||||
|
||||
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&eDown);
|
||||
QCOMPARE(eDown.text, "ü");
|
||||
QCOMPARE(eDown.key, Qt::Key_Udiaeresis);
|
||||
|
||||
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
|
||||
deadKeySupport.applyDeadKeyTranslations(&eUp);
|
||||
QCOMPARE(eUp.text, "ü");
|
||||
QCOMPARE(eUp.key, Qt::Key_Udiaeresis);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QWasmKeyTranslator)
|
||||
#include "tst_qwasmkeytranslator.moc"
|
Loading…
Reference in New Issue
Block a user