wasm: streamline key events

Set the event type from the event handler instead of
determining the event type at run-time based on string
comparison.

QWasmDeadKeySupport adds a complication. This can't be
easily simplified or removed since it maintains state.

Change-Id: Iad6f02ee7e2dc22817d7ac606514a2b4022f8fb0
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Even Oscar Andersen <even.oscar.andersen@qt.io>
This commit is contained in:
Morten Sørvig 2024-11-14 23:02:35 +01:00
parent 8f762b546f
commit 59e057ef42
5 changed files with 34 additions and 77 deletions

View File

@ -101,7 +101,7 @@ Event::Event(EventType type, emscripten::val webEvent)
{
}
KeyEvent::KeyEvent(EventType type, emscripten::val event) : Event(type, event)
KeyEvent::KeyEvent(EventType type, emscripten::val event, QWasmDeadKeySupport *deadKeySupport) : Event(type, event)
{
const auto code = event["code"].as<std::string>();
const auto webKey = event["key"].as<std::string>();
@ -116,27 +116,8 @@ KeyEvent::KeyEvent(EventType type, emscripten::val event) : Event(type, event)
if (key == Qt::Key_Tab)
text = "\t";
}
std::optional<KeyEvent> KeyEvent::fromWebWithDeadKeyTranslation(emscripten::val event,
QWasmDeadKeySupport *deadKeySupport)
{
const auto eventType = ([&event]() -> std::optional<EventType> {
const auto eventTypeString = event["type"].as<std::string>();
if (eventTypeString == "keydown")
return EventType::KeyDown;
else if (eventTypeString == "keyup")
return EventType::KeyUp;
return std::nullopt;
})();
if (!eventType)
return std::nullopt;
auto result = KeyEvent(*eventType, event);
deadKeySupport->applyDeadKeyTranslations(&result);
return result;
deadKeySupport->applyDeadKeyTranslations(this);
}
MouseEvent::MouseEvent(EventType type, emscripten::val event) : Event(type, event)

View File

@ -63,10 +63,7 @@ struct Event
struct KeyEvent : public Event
{
static std::optional<KeyEvent>
fromWebWithDeadKeyTranslation(emscripten::val webEvent, QWasmDeadKeySupport *deadKeySupport);
KeyEvent(EventType type, emscripten::val webEvent);
KeyEvent(EventType type, emscripten::val webEvent, QWasmDeadKeySupport *deadKeySupport);
Qt::Key key;
QFlags<Qt::KeyboardModifier> modifiers;

View File

@ -113,16 +113,16 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
if (wasmInput) {
m_keyDownCallbackForInputContext =
std::make_unique<qstdweb::EventCallback>(wasmInput->m_inputElement, "keydown",
[this](emscripten::val event) { this->handleKeyForInputContextEvent(event); });
[this](emscripten::val event) { this->handleKeyForInputContextEvent(EventType::KeyDown, event); });
m_keyUpCallbackForInputContext =
std::make_unique<qstdweb::EventCallback>(wasmInput->m_inputElement, "keyup",
[this](emscripten::val event) { this->handleKeyForInputContextEvent(event); });
[this](emscripten::val event) { this->handleKeyForInputContextEvent(EventType::KeyUp, event); });
}
m_keyDownCallback = std::make_unique<qstdweb::EventCallback>(m_window, "keydown",
[this](emscripten::val event) { this->handleKeyEvent(event); });
[this](emscripten::val event) { this->handleKeyEvent(KeyEvent(EventType::KeyDown, event, m_deadKeySupport)); });
m_keyUpCallback =std::make_unique<qstdweb::EventCallback>(m_window, "keyup",
[this](emscripten::val event) { this->handleKeyEvent(event); });
[this](emscripten::val event) {this->handleKeyEvent(KeyEvent(EventType::KeyUp, event, m_deadKeySupport)); });
setParent(parent());
}
@ -489,12 +489,12 @@ void QWasmWindow::commitParent(QWasmWindowTreeNode *parent)
m_commitedParent = parent;
}
void QWasmWindow::handleKeyEvent(const emscripten::val &event)
void QWasmWindow::handleKeyEvent(const KeyEvent &event)
{
qCDebug(qLcQpaWasmInputContext) << "processKey as KeyEvent";
if (processKey(*KeyEvent::fromWebWithDeadKeyTranslation(event, m_deadKeySupport)))
event.call<void>("preventDefault");
event.call<void>("stopPropagation");
if (processKey(event))
event.webEvent.call<void>("preventDefault");
event.webEvent.call<void>("stopPropagation");
}
bool QWasmWindow::processKey(const KeyEvent &event)
@ -517,7 +517,7 @@ bool QWasmWindow::processKey(const KeyEvent &event)
: result;
}
void QWasmWindow::handleKeyForInputContextEvent(const emscripten::val &event)
void QWasmWindow::handleKeyForInputContextEvent(EventType eventType, const emscripten::val &event)
{
//
// Things to consider:
@ -558,7 +558,7 @@ void QWasmWindow::handleKeyForInputContextEvent(const emscripten::val &event)
}
qCDebug(qLcQpaWasmInputContext) << "processKey as KeyEvent";
if (processKeyForInputContext(*KeyEvent::fromWebWithDeadKeyTranslation(event, m_deadKeySupport)))
if (processKeyForInputContext(KeyEvent(eventType, event, m_deadKeySupport)))
event.call<void>("preventDefault");
event.call<void>("stopImmediatePropagation");
}

View File

@ -122,9 +122,9 @@ private:
void applyWindowState();
void commitParent(QWasmWindowTreeNode *parent);
void handleKeyEvent(const emscripten::val &event);
void handleKeyEvent(const KeyEvent &event);
bool processKey(const KeyEvent &event);
void handleKeyForInputContextEvent(const emscripten::val &event);
void handleKeyForInputContextEvent(EventType eventType, const emscripten::val &event);
bool processKeyForInputContext(const KeyEvent &event);
void handlePointerEvent(const PointerEvent &event);
bool processPointer(const PointerEvent &event);

View File

@ -314,21 +314,16 @@ void tst_QWasmKeyTranslator::modifyByDeadKey()
QWasmDeadKeySupport deadKeySupport;
KeyEvent event(EventType::KeyDown, makeDeadKeyJsEvent(deadKeyCode, deadKeyModifiers));
KeyEvent event(EventType::KeyDown, makeDeadKeyJsEvent(deadKeyCode, deadKeyModifiers), &deadKeySupport);
QCOMPARE(event.deadKey, true);
deadKeySupport.applyDeadKeyTranslations(&event);
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent(targetKeyCode, targetKey, modifiers));
QCOMPARE(eDown.deadKey, false);
deadKeySupport.applyDeadKeyTranslations(&eDown);
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent(targetKeyCode, targetKey, modifiers), &deadKeySupport);
QCOMPARE(eDown.deadKey, false);
QCOMPARE(eDown.text, expectedModifiedKey);
QCOMPARE(eDown.key, targetQtKey);
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent(targetKeyCode, targetKey, modifiers));
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent(targetKeyCode, targetKey, modifiers), &deadKeySupport);
QCOMPARE(eUp.deadKey, false);
deadKeySupport.applyDeadKeyTranslations(&eUp);
QCOMPARE(eUp.text, expectedModifiedKey);
QCOMPARE(eUp.key, targetQtKey);
}
@ -336,26 +331,21 @@ void tst_QWasmKeyTranslator::modifyByDeadKey()
void tst_QWasmKeyTranslator::deadKeyModifiesOnlyOneKeyPressAndUp()
{
QWasmDeadKeySupport deadKeySupport;
KeyEvent event(EventType::KeyDown, makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&event);
KeyEvent event(EventType::KeyDown, makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()), &deadKeySupport);
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&eDown);
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(eDown.text, "ü");
QCOMPARE(eDown.key, Qt::Key_Udiaeresis);
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&eUp);
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(eUp.text, "ü");
QCOMPARE(eUp.key, Qt::Key_Udiaeresis);
KeyEvent eDown2(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&eDown2);
KeyEvent eDown2(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(eDown2.text, "u");
QCOMPARE(eDown2.key, Qt::Key_U);
KeyEvent eUp2(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&eUp2);
KeyEvent eUp2(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(eUp2.text, "u");
QCOMPARE(eUp2.key, Qt::Key_U);
}
@ -365,27 +355,21 @@ void tst_QWasmKeyTranslator::deadKeyIgnoresKeyUpPrecedingKeyDown()
QWasmDeadKeySupport deadKeySupport;
KeyEvent deadKeyDownEvent(EventType::KeyDown,
makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&deadKeyDownEvent);
makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()), &deadKeySupport);
KeyEvent deadKeyUpEvent(EventType::KeyUp, makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&deadKeyUpEvent);
KeyEvent deadKeyUpEvent(EventType::KeyUp, makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()), &deadKeySupport);
KeyEvent otherKeyUpEvent(EventType::KeyUp,
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&otherKeyUpEvent);
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()), &deadKeySupport);
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&eDown);
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(eDown.text, "ü");
QCOMPARE(eDown.key, Qt::Key_Udiaeresis);
KeyEvent yetAnotherKeyUpEvent(
EventType::KeyUp, makeKeyJsEvent("ControlLeft", "Control", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&yetAnotherKeyUpEvent);
EventType::KeyUp, makeKeyJsEvent("ControlLeft", "Control", Qt::KeyboardModifiers()), &deadKeySupport);
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&eUp);
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(eUp.text, "ü");
QCOMPARE(eUp.key, Qt::Key_Udiaeresis);
}
@ -395,28 +379,23 @@ void tst_QWasmKeyTranslator::onlyKeysProducingTextAreModifiedByDeadKeys()
QWasmDeadKeySupport deadKeySupport;
KeyEvent deadKeyDownEvent(EventType::KeyDown,
makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&deadKeyDownEvent);
makeDeadKeyJsEvent("KeyU", Qt::KeyboardModifiers()), &deadKeySupport);
KeyEvent noTextKeyDown(EventType::KeyDown,
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&noTextKeyDown);
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(noTextKeyDown.text, "");
QCOMPARE(noTextKeyDown.key, Qt::Key_Alt);
KeyEvent noTextKeyUp(EventType::KeyUp,
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&noTextKeyUp);
makeKeyJsEvent("AltLeft", "Alt", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(noTextKeyDown.text, "");
QCOMPARE(noTextKeyDown.key, Qt::Key_Alt);
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&eDown);
KeyEvent eDown(EventType::KeyDown, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(eDown.text, "ü");
QCOMPARE(eDown.key, Qt::Key_Udiaeresis);
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()));
deadKeySupport.applyDeadKeyTranslations(&eUp);
KeyEvent eUp(EventType::KeyUp, makeKeyJsEvent("KeyU", "u", Qt::KeyboardModifiers()), &deadKeySupport);
QCOMPARE(eUp.text, "ü");
QCOMPARE(eUp.key, Qt::Key_Udiaeresis);
}