summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikolaj Boc <mikolaj.boc@qt.io>2022-07-29 08:57:16 +0200
committerMikolaj Boc <mikolaj.boc@qt.io>2022-08-10 12:25:36 +0200
commit784555cc2fa9d1625a4cac458c15d28cf0c1f4d7 (patch)
treee15072f2e48c4186ec04ea5cd50dd0686d2058bb
parent595526e44623b950acd2bae1e958d21d55df0333 (diff)
Refactor QWasmEventTranslator for added readability
Change listing: - change names of abbreviated structures/variables (e.g. KeyTbl -> WebToQtKeyCodeMappings) - add constants for commonly used magic strings ("Dead", StringTerminator) - use common idioms for common tasks (find_if, std::optional) - use binary search as facilitated by the sorted array instead of a full search - this optimizes the code at no cost - remove dead code (double translateEmscriptKey in QWasmEventTranslator::getKey, remove sticky dead key support as it was write-only, remove the dead setIsMac and g_usePlatformMacSpecifics, remove the dead getWindowAt). - cull the public interface on QWasmEventTranslator as some functions are only used internally (translateEmscriptKey) - simplify / shorten functions by short-circuiting - modernize definitions (= default) - auto-format the changes using clang-format The file is now much easier to read and understand. Change-Id: I5ea2bdafd9b9abc009feeb5516ddd87fb0ca212e Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.cpp1
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.cpp197
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.h12
3 files changed, 83 insertions, 127 deletions
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp
index f7545b855c..5547fac2ad 100644
--- a/src/plugins/platforms/wasm/qwasmcompositor.cpp
+++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp
@@ -1145,7 +1145,6 @@ bool QWasmCompositor::processKeyboard(int eventType, const EmscriptenKeyboardEve
break;
case EMSCRIPTEN_EVENT_KEYUP: // up
keyType = QEvent::KeyRelease;
- m_eventTranslator->setStickyDeadKey(keyEvent);
break;
default:
break;
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
index d99d9f7d9a..fdf3eede03 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
@@ -28,41 +28,47 @@ QT_BEGIN_NAMESPACE
using namespace emscripten;
-typedef struct emkb2qt {
+namespace {
+constexpr std::string_view WebDeadKeyValue = "Dead";
+
+struct Emkb2QtData
+{
+ static constexpr char StringTerminator = '\0';
+
const char *em;
unsigned int qt;
- constexpr bool operator <=(const emkb2qt &that) const noexcept
+ constexpr bool operator<=(const Emkb2QtData &that) const noexcept
{
return !(strcmp(that) > 0);
}
- bool operator <(const emkb2qt &that) const noexcept
+ bool operator<(const Emkb2QtData &that) const noexcept { return ::strcmp(em, that.em) < 0; }
+
+ constexpr bool operator==(const Emkb2QtData &that) const noexcept { return strcmp(that) == 0; }
+
+ constexpr int strcmp(const Emkb2QtData &that, const int i = 0) const
{
- return ::strcmp(em, that.em) < 0;
+ return em[i] == StringTerminator && that.em[i] == StringTerminator ? 0
+ : em[i] == StringTerminator ? -1
+ : that.em[i] == StringTerminator ? 1
+ : em[i] < that.em[i] ? -1
+ : em[i] > that.em[i] ? 1
+ : strcmp(that, i + 1);
}
- constexpr int strcmp(const emkb2qt &that, const int i = 0) const
- {
- return em[i] == 0 && that.em[i] == 0 ? 0
- : em[i] == 0 ? -1
- : that.em[i] == 0 ? 1
- : em[i] < that.em[i] ? -1
- : em[i] > that.em[i] ? 1
- : strcmp(that, i + 1);
- }
-} emkb2qt_t;
+};
template<unsigned int Qt, char ... EmChar>
struct Emkb2Qt
{
static constexpr const char storage[sizeof ... (EmChar) + 1] = {EmChar..., '\0'};
- using Type = emkb2qt_t;
+ using Type = Emkb2QtData;
static constexpr Type data() noexcept { return Type{storage, Qt}; }
};
template<unsigned int Qt, char ... EmChar> constexpr char Emkb2Qt<Qt, EmChar...>::storage[];
-static constexpr const auto KeyTbl = qMakeArray(
+static constexpr const auto WebToQtKeyCodeMappings = qMakeArray(
QSortedData<
Emkb2Qt< Qt::Key_Escape, 'E','s','c','a','p','e' >,
Emkb2Qt< Qt::Key_Tab, 'T','a','b' >,
@@ -120,7 +126,7 @@ static constexpr const auto KeyTbl = qMakeArray(
>::Data{}
);
-static constexpr const auto DeadKeyShiftTbl = qMakeArray(
+static constexpr const auto WebToQtKeyCodeMappingsWithShift = qMakeArray(
QSortedData<
// shifted
Emkb2Qt< Qt::Key_Agrave, '\xc3','\x80' >,
@@ -155,42 +161,33 @@ static constexpr const auto DeadKeyShiftTbl = qMakeArray(
>::Data{}
);
-QWasmEventTranslator::QWasmEventTranslator() : QObject()
+std::optional<Qt::Key> findMappingByBisection(const char *toFind)
{
+ const Emkb2QtData searchKey{ toFind, 0 };
+ const auto it = std::lower_bound(WebToQtKeyCodeMappings.cbegin(), WebToQtKeyCodeMappings.cend(),
+ searchKey);
+ return it != WebToQtKeyCodeMappings.cend() && searchKey == *it ? static_cast<Qt::Key>(it->qt)
+ : std::optional<Qt::Key>();
}
-QWasmEventTranslator::~QWasmEventTranslator()
+bool isDeadKeyEvent(const EmscriptenKeyboardEvent *emKeyEvent)
{
+ return qstrncmp(emKeyEvent->key, WebDeadKeyValue.data(), WebDeadKeyValue.size()) == 0;
}
-Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey)
+Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey)
{
- Qt::Key qtKey = Qt::Key_unknown;
-
- if (qstrncmp(emscriptKey->key, "Dead", 4) == 0 ) {
- emkb2qt_t searchKey1{emscriptKey->code, 0};
- for (auto it1 = KeyTbl.cbegin(); it1 != KeyTbl.end(); ++it1)
- if (it1 != KeyTbl.end() && (qstrcmp(searchKey1.em, it1->em) == 0)) {
- qtKey = static_cast<Qt::Key>(it1->qt);
- }
- }
- if (qtKey == Qt::Key_unknown) {
- emkb2qt_t searchKey{emscriptKey->key, 0};
- // search key
- auto it1 = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
- if (it1 != KeyTbl.end() && !(searchKey < *it1)) {
- qtKey = static_cast<Qt::Key>(it1->qt);
- }
+ if (isDeadKeyEvent(emscriptKey)) {
+ if (auto mapping = findMappingByBisection(emscriptKey->code))
+ return *mapping;
}
+ if (auto mapping = findMappingByBisection(emscriptKey->key))
+ return *mapping;
- if (qtKey == Qt::Key_unknown) {
- // cast to unicode key
- QString str = QString::fromUtf8(emscriptKey->key).toUpper();
- QStringIterator i(str);
- qtKey = static_cast<Qt::Key>(i.next(0));
- }
-
- return qtKey;
+ // cast to unicode key
+ QString str = QString::fromUtf8(emscriptKey->key).toUpper();
+ QStringIterator i(str);
+ return static_cast<Qt::Key>(i.next(0));
}
struct KeyMapping { Qt::Key from, to; };
@@ -247,46 +244,45 @@ static Qt::Key find(const KeyMapping (&map)[N], Qt::Key key) noexcept
return find_impl(map, map + N, key);
}
-Qt::Key QWasmEventTranslator::translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey)
+Qt::Key translateBaseKeyUsingDeadKey(Qt::Key accentBaseKey, Qt::Key deadKey)
{
- Qt::Key wasmKey = Qt::Key_unknown;
-
- if (deadKey == Qt::Key_QuoteLeft ) {
- if (platform() == Platform::MacOS) { // ` macOS: Key_Dead_Grave
- wasmKey = find(graveKeyTable, accentBaseKey);
- } else {
- wasmKey = find(diaeresisKeyTable, accentBaseKey);
- }
- return wasmKey;
- }
-
switch (deadKey) {
- // case Qt::Key_QuoteLeft:
+ 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
- wasmKey = find(graveKeyTable, accentBaseKey);
- break;
+ return find(graveKeyTable, accentBaseKey);
case Qt::Key_E: // ´ Key_Dead_Acute
- wasmKey = find(acuteKeyTable, accentBaseKey);
- break;
+ return find(acuteKeyTable, accentBaseKey);
case Qt::Key_AsciiTilde:
- case Qt::Key_N:// Key_Dead_Tilde
- wasmKey = find(tildeKeyTable, accentBaseKey);
- break;
- case Qt::Key_U:// ¨ Key_Dead_Diaeresis
- wasmKey = find(diaeresisKeyTable, accentBaseKey);
- break;
- case Qt::Key_I:// macOS Key_Dead_Circumflex
- case Qt::Key_6:// linux
- case Qt::Key_Apostrophe:// linux
- wasmKey = find(circumflexKeyTable, accentBaseKey);
- break;
+ case Qt::Key_N: // Key_Dead_Tilde
+ return find(tildeKeyTable, accentBaseKey);
+ case Qt::Key_U: // ¨ 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
+ return find(circumflexKeyTable, accentBaseKey);
default:
- break;
-
+ return Qt::Key_unknown;
};
- return wasmKey;
}
+template<class T>
+std::optional<QString> findKeyTextByKeyId(const T &mappingArray, Qt::Key qtKey)
+{
+ const auto it = std::find_if(mappingArray.cbegin(), mappingArray.cend(),
+ [qtKey](const Emkb2QtData &data) { return data.qt == qtKey; });
+ return it != mappingArray.cend() ? it->em : std::optional<QString>();
+}
+} // namespace
+
+QWasmEventTranslator::QWasmEventTranslator() = default;
+
+QWasmEventTranslator::~QWasmEventTranslator() = default;
+
QCursor QWasmEventTranslator::cursorForMode(QWasmCompositor::ResizeMode m)
{
switch (m) {
@@ -310,45 +306,27 @@ QCursor QWasmEventTranslator::cursorForMode(QWasmCompositor::ResizeMode m)
QString QWasmEventTranslator::getKeyText(const EmscriptenKeyboardEvent *keyEvent, Qt::Key qtKey)
{
- QString keyText;
-
if (m_emDeadKey != Qt::Key_unknown) {
- Qt::Key transformedKey = translateDeadKey(m_emDeadKey, qtKey);
-
- if (transformedKey != Qt::Key_unknown)
- qtKey = transformedKey;
-
- if (keyEvent->shiftKey == 0) {
- for (auto it = KeyTbl.cbegin(); it != KeyTbl.end(); ++it) {
- if (it != KeyTbl.end() && (qtKey == static_cast<Qt::Key>(it->qt))) {
- keyText = it->em;
- m_emDeadKey = Qt::Key_unknown;
- break;
- }
- }
- } else {
- for (auto it = DeadKeyShiftTbl.cbegin(); it != DeadKeyShiftTbl.end(); ++it) {
- if (it != DeadKeyShiftTbl.end() && (qtKey == static_cast<Qt::Key>(it->qt))) {
- keyText = it->em;
- m_emDeadKey = Qt::Key_unknown;
- break;
- }
- }
+ const Qt::Key translatedKey = translateBaseKeyUsingDeadKey(qtKey, m_emDeadKey);
+ if (translatedKey != Qt::Key_unknown)
+ qtKey = translatedKey;
+
+ if (auto text = keyEvent->shiftKey
+ ? findKeyTextByKeyId(WebToQtKeyCodeMappingsWithShift, qtKey)
+ : findKeyTextByKeyId(WebToQtKeyCodeMappings, qtKey)) {
+ m_emDeadKey = Qt::Key_unknown;
+ return *text;
}
}
- if (keyText.isEmpty())
- keyText = QString::fromUtf8(keyEvent->key);
- return keyText;
+ return QString::fromUtf8(keyEvent->key);
}
Qt::Key QWasmEventTranslator::getKey(const EmscriptenKeyboardEvent *keyEvent)
{
Qt::Key qtKey = translateEmscriptKey(keyEvent);
- if (qstrncmp(keyEvent->key, "Dead", 4) == 0 || qtKey == Qt::Key_AltGr) {
- qtKey = translateEmscriptKey(keyEvent);
- m_emStickyDeadKey = true;
- if (keyEvent->shiftKey == 1 && qtKey == Qt::Key_QuoteLeft)
+ if (isDeadKeyEvent(keyEvent) || qtKey == Qt::Key_AltGr) {
+ if (keyEvent->shiftKey && qtKey == Qt::Key_QuoteLeft)
qtKey = Qt::Key_AsciiTilde;
m_emDeadKey = qtKey;
}
@@ -356,13 +334,4 @@ Qt::Key QWasmEventTranslator::getKey(const EmscriptenKeyboardEvent *keyEvent)
return qtKey;
}
-void QWasmEventTranslator::setStickyDeadKey(const EmscriptenKeyboardEvent *keyEvent)
-{
- Qt::Key qtKey = translateEmscriptKey(keyEvent);
-
- if (m_emStickyDeadKey && qtKey != Qt::Key_Alt) {
- m_emStickyDeadKey = false;
- }
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h
index c076ba38bc..5bde30ab91 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.h
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h
@@ -24,30 +24,18 @@ class QWasmEventTranslator : public QObject
Q_OBJECT
public:
-
explicit QWasmEventTranslator();
~QWasmEventTranslator();
- static Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey);
static QCursor cursorForMode(QWasmCompositor::ResizeMode mode);
QString getKeyText(const EmscriptenKeyboardEvent *keyEvent, Qt::Key key);
Qt::Key getKey(const EmscriptenKeyboardEvent *keyEvent);
- void setStickyDeadKey(const EmscriptenKeyboardEvent *keyEvent);
-
- void setIsMac(bool is_mac) {g_usePlatformMacSpecifics = is_mac;};
- bool g_usePlatformMacSpecifics = false;
-
-Q_SIGNALS:
- void getWindowAt(const QPoint &point, QWindow **window);
-private:
- static Qt::Key translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey);
private:
static quint64 getTimestamp();
Qt::Key m_emDeadKey = Qt::Key_unknown;
- bool m_emStickyDeadKey = false;
};