Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qwasmevent.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qwasmevent.h"
5
7
8#include <QtCore/private/qmakearray_p.h>
9#include <QtCore/private/qstringiterator_p.h>
10#include <QtCore/qregularexpression.h>
11
13
14namespace {
15constexpr std::string_view WebDeadKeyValue = "Dead";
16
17bool isDeadKeyEvent(const char *key)
18{
19 return qstrncmp(key, WebDeadKeyValue.data(), WebDeadKeyValue.size()) == 0;
20}
21
22Qt::Key getKeyFromCode(const std::string &code)
23{
25 return *mapping;
26
27 static QRegularExpression regex(QString(QStringLiteral(R"re((?:Key|Digit)(\w))re")));
28 const auto codeQString = QString::fromStdString(code);
29 const auto match = regex.match(codeQString);
30
31 if (!match.hasMatch())
32 return Qt::Key_unknown;
33
34 constexpr size_t CharacterIndex = 1;
35 return static_cast<Qt::Key>(match.capturedView(CharacterIndex).at(0).toLatin1());
36}
37
38Qt::Key webKeyToQtKey(const std::string &code, const std::string &key, bool isDeadKey,
40{
41 if (isDeadKey) {
42 auto mapped = getKeyFromCode(code);
43 switch (mapped) {
44 case Qt::Key_U:
46 case Qt::Key_E:
47 return Qt::Key_Dead_Acute;
48 case Qt::Key_I:
50 case Qt::Key_N:
51 return Qt::Key_Dead_Tilde;
54 case Qt::Key_6:
60 return Qt::Key_Dead_Tilde;
61 default:
62 return Qt::Key_unknown;
63 }
64 } else if (auto mapping = QWasmKeyTranslator::mapWebKeyTextToQtKey(key.c_str())) {
65 return *mapping;
66 }
67
68 // cast to unicode key
70 if (str.length() > 1)
71 return Qt::Key_unknown;
72
74 return static_cast<Qt::Key>(i.next(0));
75}
76} // namespace
77
79{
80template <>
82 const EmscriptenKeyboardEvent& event)
83{
85 (event.location == DOM_KEY_LOCATION_NUMPAD ? Qt::KeypadModifier : Qt::NoModifier);
86}
87} // namespace KeyboardModifier
88
90
91Event::~Event() = default;
92
93Event::Event(const Event &other) = default;
94
95Event::Event(Event &&other) = default;
96
97Event &Event::operator=(const Event &other) = default;
98
99Event &Event::operator=(Event &&other) = default;
100
101KeyEvent::KeyEvent(EventType type, emscripten::val event) : Event(type, event["target"])
102{
103 const auto code = event["code"].as<std::string>();
104 const auto webKey = event["key"].as<std::string>();
105 deadKey = isDeadKeyEvent(webKey.c_str());
106
108 key = webKeyToQtKey(code, webKey, deadKey, modifiers);
109
110 text = QString::fromUtf8(webKey);
111 if (text.size() > 1)
112 text.clear();
113}
114
115KeyEvent::~KeyEvent() = default;
116
117KeyEvent::KeyEvent(const KeyEvent &other) = default;
118
120
121KeyEvent &KeyEvent::operator=(const KeyEvent &other) = default;
122
124
125std::optional<KeyEvent> KeyEvent::fromWebWithDeadKeyTranslation(emscripten::val event,
126 QWasmDeadKeySupport *deadKeySupport)
127{
128 const auto eventType = ([&event]() -> std::optional<EventType> {
129 const auto eventTypeString = event["type"].as<std::string>();
130
131 if (eventTypeString == "keydown")
132 return EventType::KeyDown;
133 else if (eventTypeString == "keyup")
134 return EventType::KeyUp;
135 return std::nullopt;
136 })();
137 if (!eventType)
138 return std::nullopt;
139
140 auto result = KeyEvent(*eventType, event);
141 deadKeySupport->applyDeadKeyTranslations(&result);
142
143 return result;
144}
145
147{
148 mouseButton = MouseEvent::buttonFromWeb(event["button"].as<int>());
149 mouseButtons = MouseEvent::buttonsFromWeb(event["buttons"].as<unsigned short>());
150 // The current button state (event.buttons) may be out of sync for some PointerDown
151 // events where the "down" state is very brief, for example taps on Apple trackpads.
152 // Qt expects that the current button state is in sync with the event, so we sync
153 // it up here.
156 localPoint = QPointF(event["offsetX"].as<qreal>(), event["offsetY"].as<qreal>());
157 pointInPage = QPointF(event["pageX"].as<qreal>(), event["pageY"].as<qreal>());
158 pointInViewport = QPointF(event["clientX"].as<qreal>(), event["clientY"].as<qreal>());
160}
161
162MouseEvent::~MouseEvent() = default;
163
164MouseEvent::MouseEvent(const MouseEvent &other) = default;
165
167
169
171
173{
174 pointerId = event["pointerId"].as<int>();
175 pointerType = ([type = event["pointerType"].as<std::string>()]() {
176 if (type == "mouse")
177 return PointerType::Mouse;
178 if (type == "touch")
179 return PointerType::Touch;
180 return PointerType::Other;
181 })();
182 width = event["width"].as<qreal>();
183 height = event["height"].as<qreal>();
184 pressure = event["pressure"].as<qreal>();
185 isPrimary = event["isPrimary"].as<bool>();
186}
187
189
191
193
195
197
198std::optional<PointerEvent> PointerEvent::fromWeb(emscripten::val event)
199{
200 const auto eventType = ([&event]() -> std::optional<EventType> {
201 const auto eventTypeString = event["type"].as<std::string>();
202
203 if (eventTypeString == "pointermove")
205 else if (eventTypeString == "pointerup")
207 else if (eventTypeString == "pointerdown")
209 else if (eventTypeString == "pointerenter")
211 else if (eventTypeString == "pointerleave")
213 return std::nullopt;
214 })();
215 if (!eventType)
216 return std::nullopt;
217
218 return PointerEvent(*eventType, event);
219}
220
222 : MouseEvent(type, event), dataTransfer(event["dataTransfer"])
223{
224 dropAction = ([event]() {
225 const std::string effect = event["dataTransfer"]["dropEffect"].as<std::string>();
226
227 if (effect == "copy")
228 return Qt::CopyAction;
229 else if (effect == "move")
230 return Qt::MoveAction;
231 else if (effect == "link")
232 return Qt::LinkAction;
233 return Qt::IgnoreAction;
234 })();
235}
236
237DragEvent::~DragEvent() = default;
238
239DragEvent::DragEvent(const DragEvent &other) = default;
240
242
244
246
247std::optional<DragEvent> DragEvent::fromWeb(emscripten::val event)
248{
249 const auto eventType = ([&event]() -> std::optional<EventType> {
250 const auto eventTypeString = event["type"].as<std::string>();
251
252 if (eventTypeString == "drop")
253 return EventType::Drop;
254 return std::nullopt;
255 })();
256 if (!eventType)
257 return std::nullopt;
258 return DragEvent(*eventType, event);
259}
260
262{
263 deltaMode = ([event]() {
264 const int deltaMode = event["deltaMode"].as<int>();
265 const auto jsWheelEventType = emscripten::val::global("WheelEvent");
266 if (deltaMode == jsWheelEventType["DOM_DELTA_PIXEL"].as<int>())
267 return DeltaMode::Pixel;
268 else if (deltaMode == jsWheelEventType["DOM_DELTA_LINE"].as<int>())
269 return DeltaMode::Line;
270 return DeltaMode::Page;
271 })();
272
273 delta = QPointF(event["deltaX"].as<qreal>(), event["deltaY"].as<qreal>());
274
275 webkitDirectionInvertedFromDevice = event["webkitDirectionInvertedFromDevice"].as<bool>();
276}
277
278WheelEvent::~WheelEvent() = default;
279
280WheelEvent::WheelEvent(const WheelEvent &other) = default;
281
283
285
287
288std::optional<WheelEvent> WheelEvent::fromWeb(emscripten::val event)
289{
290 const auto eventType = ([&event]() -> std::optional<EventType> {
291 const auto eventTypeString = event["type"].as<std::string>();
292
293 if (eventTypeString == "wheel")
294 return EventType::Wheel;
295 return std::nullopt;
296 })();
297 if (!eventType)
298 return std::nullopt;
299 return WheelEvent(*eventType, event);
300}
301
\inmodule QtCore\reentrant
Definition qpoint.h:214
\inmodule QtCore \reentrant
QRegularExpressionMatch match(const QString &subject, qsizetype offset=0, MatchType matchType=NormalMatch, MatchOptions matchOptions=NoMatchOption) const
Attempts to match the regular expression against the given subject string, starting at the position o...
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromStdString(const std::string &s)
Definition qstring.h:1322
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
QString toUpper() const &
Definition qstring.h:372
qsizetype length() const
Returns the number of characters in this string.
Definition qstring.h:187
void applyDeadKeyTranslations(KeyEvent *event)
EGLImageKHR int int EGLuint64KHR * modifiers
QString str
[2]
QFlags< Qt::KeyboardModifier > getForEvent< EmscriptenKeyboardEvent >(const EmscriptenKeyboardEvent &event)
QFlags< Qt::KeyboardModifier > getForEvent(const Event &event)
Definition qwasmevent.h:109
Combined button and popup list for selecting options.
constexpr std::string_view WebDeadKeyValue
bool isDeadKeyEvent(const char *key)
Qt::Key getKeyFromCode(const std::string &code)
std::optional< Qt::Key > mapWebKeyTextToQtKey(const char *toFind)
@ Key_QuoteLeft
Definition qnamespace.h:577
@ Key_I
Definition qnamespace.h:554
@ Key_U
Definition qnamespace.h:566
@ Key_Dead_Circumflex
Definition qnamespace.h:792
@ Key_Dead_Grave
Definition qnamespace.h:790
@ Key_Dead_Acute
Definition qnamespace.h:791
@ Key_6
Definition qnamespace.h:535
@ Key_AsciiTilde
Definition qnamespace.h:581
@ Key_N
Definition qnamespace.h:559
@ Key_Dead_Tilde
Definition qnamespace.h:793
@ Key_E
Definition qnamespace.h:550
@ Key_Apostrophe
Definition qnamespace.h:520
@ Key_unknown
@ Key_Dead_Diaeresis
Definition qnamespace.h:797
@ ShiftModifier
@ KeypadModifier
@ NoModifier
@ CopyAction
@ IgnoreAction
@ MoveAction
@ LinkAction
int qstrncmp(const char *str1, const char *str2, size_t len)
GLuint64 key
GLint GLsizei GLsizei height
GLint GLsizei width
GLenum type
GLenum target
struct _cl_event * event
GLuint64EXT * result
[6]
GLenum GLenum GLenum GLenum mapping
#define QStringLiteral(str)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
double qreal
Definition qtypes.h:92
EventType
Definition qwasmevent.h:22
QSharedPointer< T > other(t)
[5]
QGraphicsOpacityEffect * effect
the effect attached to this item
DragEvent & operator=(const DragEvent &other)
static std::optional< DragEvent > fromWeb(emscripten::val webEvent)
DragEvent(EventType type, emscripten::val webEvent)
Qt::DropAction dropAction
Definition qwasmevent.h:233
Event(EventType type, emscripten::val target)
Event & operator=(const Event &other)
KeyEvent & operator=(const KeyEvent &other)
bool deadKey
Definition qwasmevent.h:147
QString text
Definition qwasmevent.h:148
static std::optional< KeyEvent > fromWebWithDeadKeyTranslation(emscripten::val webEvent, QWasmDeadKeySupport *deadKeySupport)
KeyEvent(EventType type, emscripten::val webEvent)
static constexpr Qt::MouseButton buttonFromWeb(int webButton)
Definition qwasmevent.h:160
QPointF localPoint
Definition qwasmevent.h:195
QPointF pointInViewport
Definition qwasmevent.h:197
Qt::MouseButton mouseButton
Definition qwasmevent.h:198
static constexpr Qt::MouseButtons buttonsFromWeb(unsigned short webButtons)
Definition qwasmevent.h:173
Qt::MouseButtons mouseButtons
Definition qwasmevent.h:199
QPointF pointInPage
Definition qwasmevent.h:196
MouseEvent(EventType type, emscripten::val webEvent)
MouseEvent & operator=(const MouseEvent &other)
PointerType pointerType
Definition qwasmevent.h:214
PointerEvent(EventType type, emscripten::val webEvent)
static std::optional< PointerEvent > fromWeb(emscripten::val webEvent)
PointerEvent & operator=(const PointerEvent &other)
static std::optional< WheelEvent > fromWeb(emscripten::val webEvent)
DeltaMode deltaMode
Definition qwasmevent.h:248
WheelEvent(EventType type, emscripten::val webEvent)
bool webkitDirectionInvertedFromDevice
Definition qwasmevent.h:249
WheelEvent & operator=(const WheelEvent &other)
QPointF delta
Definition qwasmevent.h:250