summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmevent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmevent.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmevent.cpp130
1 files changed, 107 insertions, 23 deletions
diff --git a/src/plugins/platforms/wasm/qwasmevent.cpp b/src/plugins/platforms/wasm/qwasmevent.cpp
index 8caea84053..e418263655 100644
--- a/src/plugins/platforms/wasm/qwasmevent.cpp
+++ b/src/plugins/platforms/wasm/qwasmevent.cpp
@@ -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 (isDeadKey) {
- if (auto mapping = QWasmKeyTranslator::mapWebKeyTextToQtKey(code.c_str()))
- return *mapping;
- }
- if (auto mapping = QWasmKeyTranslator::mapWebKeyTextToQtKey(key.c_str()))
+ if (auto mapping = QWasmKeyTranslator::mapWebKeyTextToQtKey(code.c_str()))
return *mapping;
- if (isDeadKey)
+
+ 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) {
+ 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;
+ }
+
// 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));
}
@@ -47,7 +86,10 @@ QFlags<Qt::KeyboardModifier> getForEvent<EmscriptenKeyboardEvent>(
}
} // namespace KeyboardModifier
-Event::Event(EventType type, emscripten::val target) : type(type), target(target) { }
+Event::Event(EventType type, emscripten::val webEvent)
+ : webEvent(webEvent), type(type)
+{
+}
Event::~Event() = default;
@@ -59,18 +101,21 @@ Event &Event::operator=(const Event &other) = default;
Event &Event::operator=(Event &&other) = default;
-KeyEvent::KeyEvent(EventType type, emscripten::val event) : Event(type, event["target"])
+KeyEvent::KeyEvent(EventType type, emscripten::val event) : Event(type, event)
{
const auto code = event["code"].as<std::string>();
const auto webKey = event["key"].as<std::string>();
deadKey = isDeadKeyEvent(webKey.c_str());
-
- key = webKeyToQtKey(code, webKey, deadKey);
-
+ autoRepeat = event["repeat"].as<bool>();
modifiers = KeyboardModifier::getForEvent(event);
+ key = webKeyToQtKey(code, webKey, deadKey, modifiers);
+
text = QString::fromUtf8(webKey);
if (text.size() > 1)
text.clear();
+
+ if (key == Qt::Key_Tab)
+ text = "\t";
}
KeyEvent::~KeyEvent() = default;
@@ -104,7 +149,7 @@ std::optional<KeyEvent> KeyEvent::fromWebWithDeadKeyTranslation(emscripten::val
return result;
}
-MouseEvent::MouseEvent(EventType type, emscripten::val event) : Event(type, event["target"])
+MouseEvent::MouseEvent(EventType type, emscripten::val event) : Event(type, event)
{
mouseButton = MouseEvent::buttonFromWeb(event["button"].as<int>());
mouseButtons = MouseEvent::buttonsFromWeb(event["buttons"].as<unsigned short>());
@@ -114,9 +159,9 @@ MouseEvent::MouseEvent(EventType type, emscripten::val event) : Event(type, even
// it up here.
if (type == EventType::PointerDown)
mouseButtons |= mouseButton;
- localPoint = QPoint(event["offsetX"].as<int>(), event["offsetY"].as<int>());
- pointInPage = QPoint(event["pageX"].as<int>(), event["pageY"].as<int>());
- pointInViewport = QPoint(event["clientX"].as<int>(), event["clientY"].as<int>());
+ localPoint = QPointF(event["offsetX"].as<qreal>(), event["offsetY"].as<qreal>());
+ pointInPage = QPointF(event["pageX"].as<qreal>(), event["pageY"].as<qreal>());
+ pointInViewport = QPointF(event["clientX"].as<qreal>(), event["clientY"].as<qreal>());
modifiers = KeyboardModifier::getForEvent(event);
}
@@ -133,8 +178,23 @@ MouseEvent &MouseEvent::operator=(MouseEvent &&other) = default;
PointerEvent::PointerEvent(EventType type, emscripten::val event) : MouseEvent(type, event)
{
pointerId = event["pointerId"].as<int>();
- pointerType = event["pointerType"].as<std::string>() == "mouse" ? PointerType::Mouse
- : PointerType::Other;
+ pointerType = ([type = event["pointerType"].as<std::string>()]() {
+ if (type == "mouse")
+ return PointerType::Mouse;
+ if (type == "touch")
+ return PointerType::Touch;
+ if (type == "pen")
+ return PointerType::Pen;
+ return PointerType::Other;
+ })();
+ width = event["width"].as<qreal>();
+ height = event["height"].as<qreal>();
+ pressure = event["pressure"].as<qreal>();
+ tiltX = event["tiltX"].as<qreal>();
+ tiltY = event["tiltY"].as<qreal>();
+ tangentialPressure = event["tangentialPressure"].as<qreal>();
+ twist = event["twist"].as<qreal>();
+ isPrimary = event["isPrimary"].as<bool>();
}
PointerEvent::~PointerEvent() = default;
@@ -170,8 +230,8 @@ std::optional<PointerEvent> PointerEvent::fromWeb(emscripten::val event)
return PointerEvent(*eventType, event);
}
-DragEvent::DragEvent(EventType type, emscripten::val event)
- : MouseEvent(type, event), dataTransfer(event["dataTransfer"])
+DragEvent::DragEvent(EventType type, emscripten::val event, QWindow *window)
+ : MouseEvent(type, event), dataTransfer(event["dataTransfer"]), targetWindow(window)
{
dropAction = ([event]() {
const std::string effect = event["dataTransfer"]["dropEffect"].as<std::string>();
@@ -196,18 +256,42 @@ DragEvent &DragEvent::operator=(const DragEvent &other) = default;
DragEvent &DragEvent::operator=(DragEvent &&other) = default;
-std::optional<DragEvent> DragEvent::fromWeb(emscripten::val event)
+std::optional<DragEvent> DragEvent::fromWeb(emscripten::val event, QWindow *targetWindow)
{
const auto eventType = ([&event]() -> std::optional<EventType> {
const auto eventTypeString = event["type"].as<std::string>();
+ if (eventTypeString == "dragend")
+ return EventType::DragEnd;
+ if (eventTypeString == "dragover")
+ return EventType::DragOver;
+ if (eventTypeString == "dragstart")
+ return EventType::DragStart;
if (eventTypeString == "drop")
return EventType::Drop;
return std::nullopt;
})();
if (!eventType)
return std::nullopt;
- return DragEvent(*eventType, event);
+ return DragEvent(*eventType, event, targetWindow);
+}
+
+void DragEvent::cancelDragStart()
+{
+ Q_ASSERT_X(type == EventType::DragStart, Q_FUNC_INFO, "Only supported for DragStart");
+ webEvent.call<void>("preventDefault");
+}
+
+void DragEvent::acceptDragOver()
+{
+ Q_ASSERT_X(type == EventType::DragOver, Q_FUNC_INFO, "Only supported for DragOver");
+ webEvent.call<void>("preventDefault");
+}
+
+void DragEvent::acceptDrop()
+{
+ Q_ASSERT_X(type == EventType::Drop, Q_FUNC_INFO, "Only supported for Drop");
+ webEvent.call<void>("preventDefault");
}
WheelEvent::WheelEvent(EventType type, emscripten::val event) : MouseEvent(type, event)
@@ -222,7 +306,7 @@ WheelEvent::WheelEvent(EventType type, emscripten::val event) : MouseEvent(type,
return DeltaMode::Page;
})();
- delta = QPoint(event["deltaX"].as<int>(), event["deltaY"].as<int>());
+ delta = QPointF(event["deltaX"].as<qreal>(), event["deltaY"].as<qreal>());
webkitDirectionInvertedFromDevice = event["webkitDirectionInvertedFromDevice"].as<bool>();
}