summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmevent.h
diff options
context:
space:
mode:
authorMikolaj Boc <mikolaj.boc@qt.io>2022-07-15 09:11:11 +0200
committerMikolaj Boc <mikolaj.boc@qt.io>2022-07-25 14:40:40 +0200
commit5a4e5c62af0d462e0c26d691d3971e82f3241f4b (patch)
tree863487079e4e8f7903652bb4e5b80f9149fa4fe8 /src/plugins/platforms/wasm/qwasmevent.h
parent57b4e30ff8841da682cc5e27c2b4abf571838e32 (diff)
Improve window dragging on WASM
Window dragging has been considerably improved by replacing the mouse events by pointer events and placing a pointer lock on WASM canvas, so that off-browser window events are delivered to us. Translation of the drag origin has been limited to inside the canvas, so that a window cannot be dragged so far that it becomes offscreen and is unreachable. Change-Id: Id177c630a6466f04464a513371d6b97d3a098b6a Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmevent.h')
-rw-r--r--src/plugins/platforms/wasm/qwasmevent.h145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/plugins/platforms/wasm/qwasmevent.h b/src/plugins/platforms/wasm/qwasmevent.h
new file mode 100644
index 0000000000..784591fb95
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmevent.h
@@ -0,0 +1,145 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef QWASMEVENT_H
+#define QWASMEVENT_H
+
+#include "qwasmplatform.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qnamespace.h>
+
+#include <QPoint>
+
+#include <emscripten/html5.h>
+#include <emscripten/val.h>
+
+QT_BEGIN_NAMESPACE
+
+enum class EventType {
+ PointerDown,
+ PointerMove,
+ PointerUp,
+ PointerEnter,
+ PointerLeave,
+};
+
+enum class PointerType {
+ Mouse,
+ Other,
+};
+
+namespace KeyboardModifier {
+namespace internal
+{
+ // Check for the existence of shiftKey, ctrlKey, altKey and metaKey in a type.
+ // Based on that, we can safely assume we are dealing with an emscripten event type.
+ template<typename T>
+ struct IsEmscriptenEvent
+ {
+ template<typename U, EM_BOOL U::*, EM_BOOL U::*, EM_BOOL U::*, EM_BOOL U::*>
+ struct SFINAE {};
+ template<typename U> static char Test(
+ SFINAE<U, &U::shiftKey, &U::ctrlKey, &U::altKey, &U::metaKey>*);
+ template<typename U> static int Test(...);
+ static const bool value = sizeof(Test<T>(0)) == sizeof(char);
+ };
+
+ template<class T, typename Enable = void>
+ struct Helper;
+
+ template<class T>
+ struct Helper<T, std::enable_if_t<IsEmscriptenEvent<T>::value>>
+ {
+ static QFlags<Qt::KeyboardModifier> getModifierForEvent(const T& event) {
+ QFlags<Qt::KeyboardModifier> keyModifier = Qt::NoModifier;
+ if (event.shiftKey)
+ keyModifier |= Qt::ShiftModifier;
+ if (event.ctrlKey)
+ keyModifier |= platform() == Platform::MacOS ? Qt::MetaModifier : Qt::ControlModifier;
+ if (event.altKey)
+ keyModifier |= Qt::AltModifier;
+ if (event.metaKey)
+ keyModifier |= platform() == Platform::MacOS ? Qt::ControlModifier : Qt::MetaModifier;
+
+ return keyModifier;
+ }
+ };
+
+ template<>
+ struct Helper<emscripten::val>
+ {
+ static QFlags<Qt::KeyboardModifier> getModifierForEvent(const emscripten::val& event) {
+ QFlags<Qt::KeyboardModifier> keyModifier = Qt::NoModifier;
+ if (event["shiftKey"].as<bool>())
+ keyModifier |= Qt::ShiftModifier;
+ if (event["ctrlKey"].as<bool>())
+ keyModifier |= platform() == Platform::MacOS ? Qt::MetaModifier : Qt::ControlModifier;
+ if (event["altKey"].as<bool>())
+ keyModifier |= Qt::AltModifier;
+ if (event["metaKey"].as<bool>())
+ keyModifier |= platform() == Platform::MacOS ? Qt::ControlModifier : Qt::MetaModifier;
+ if (event["constructor"]["name"].as<std::string>() == "KeyboardEvent" &&
+ event["location"].as<unsigned int>() == DOM_KEY_LOCATION_NUMPAD) {
+ keyModifier |= Qt::KeypadModifier;
+ }
+
+ return keyModifier;
+ }
+ };
+} // namespace internal
+
+template <typename Event>
+QFlags<Qt::KeyboardModifier> getForEvent(const Event& event)
+{
+ return internal::Helper<Event>::getModifierForEvent(event);
+}
+
+template <>
+QFlags<Qt::KeyboardModifier> getForEvent<EmscriptenKeyboardEvent>(
+ const EmscriptenKeyboardEvent& event);
+
+} // namespace KeyboardModifier
+
+struct Q_CORE_EXPORT Event
+{
+ EventType type;
+};
+
+struct Q_CORE_EXPORT MouseEvent : public Event
+{
+ QPoint point;
+ Qt::MouseButton mouseButton;
+ Qt::MouseButtons mouseButtons;
+ QFlags<Qt::KeyboardModifier> modifiers;
+
+ static constexpr Qt::MouseButton buttonFromWeb(int webButton) {
+ switch (webButton) {
+ case 0:
+ return Qt::LeftButton;
+ case 1:
+ return Qt::MiddleButton;
+ case 2:
+ return Qt::RightButton;
+ default:
+ return Qt::NoButton;
+ }
+ }
+
+ static constexpr Qt::MouseButtons buttonsFromWeb(unsigned short webButtons) {
+ // Coincidentally, Qt and web bitfields match.
+ return Qt::MouseButtons::fromInt(webButtons);
+}
+};
+
+struct Q_CORE_EXPORT PointerEvent : public MouseEvent
+{
+ static std::optional<PointerEvent> fromWeb(emscripten::val webEvent);
+
+ PointerType pointerType;
+ int pointerId;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWASMEVENT_H