Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwasmwindowclientarea.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
5
6#include "qwasmdom.h"
7#include "qwasmevent.h"
8#include "qwasmscreen.h"
9#include "qwasmwindow.h"
10#include "qwasmdrag.h"
11
12#include <QtGui/private/qguiapplication_p.h>
13#include <QtGui/qpointingdevice.h>
14
15#include <QtCore/qassert.h>
16
18
20 : m_screen(screen), m_window(window), m_element(element)
21{
22 const auto callback = std::function([this](emscripten::val event) {
23 processPointer(*PointerEvent::fromWeb(event));
24 event.call<void>("preventDefault");
25 event.call<void>("stopPropagation");
26 });
27
28 m_pointerDownCallback =
29 std::make_unique<qstdweb::EventCallback>(element, "pointerdown", callback);
30 m_pointerMoveCallback =
31 std::make_unique<qstdweb::EventCallback>(element, "pointermove", callback);
32 m_pointerUpCallback = std::make_unique<qstdweb::EventCallback>(element, "pointerup", callback);
33 m_pointerCancelCallback =
34 std::make_unique<qstdweb::EventCallback>(element, "pointercancel", callback);
35
36 element.call<void>("setAttribute", emscripten::val("draggable"), emscripten::val("true"));
37
38 m_dragStartCallback = std::make_unique<qstdweb::EventCallback>(
39 element, "dragstart", [this](emscripten::val webEvent) {
40 webEvent.call<void>("preventDefault");
41 auto event = *DragEvent::fromWeb(webEvent, m_window->window());
42 QWasmDrag::instance()->onNativeDragStarted(&event);
43 });
44 m_dragOverCallback = std::make_unique<qstdweb::EventCallback>(
45 element, "dragover", [this](emscripten::val webEvent) {
46 webEvent.call<void>("preventDefault");
47 auto event = *DragEvent::fromWeb(webEvent, m_window->window());
48 QWasmDrag::instance()->onNativeDragOver(&event);
49 });
50 m_dropCallback = std::make_unique<qstdweb::EventCallback>(
51 element, "drop", [this](emscripten::val webEvent) {
52 webEvent.call<void>("preventDefault");
53 auto event = *DragEvent::fromWeb(webEvent, m_window->window());
54 QWasmDrag::instance()->onNativeDrop(&event);
55 });
56 m_dragEndCallback = std::make_unique<qstdweb::EventCallback>(
57 element, "dragend", [this](emscripten::val webEvent) {
58 webEvent.call<void>("preventDefault");
59 auto event = *DragEvent::fromWeb(webEvent, m_window->window());
60 QWasmDrag::instance()->onNativeDragFinished(&event);
61 });
62
63}
64
65bool ClientArea::processPointer(const PointerEvent &event)
66{
67
68 switch (event.type) {
70 m_element.call<void>("setPointerCapture", event.pointerId);
71 if ((m_window->window()->flags() & Qt::WindowDoesNotAcceptFocus)
73 && m_window->window()->isTopLevel())
74 m_window->window()->requestActivate();
75 break;
77 m_element.call<void>("releasePointerCapture", event.pointerId);
78 break;
79 default:
80 break;
81 };
82
83 const bool eventAccepted = deliverEvent(event);
84 if (!eventAccepted && event.type == EventType::PointerDown)
85 QGuiApplicationPrivate::instance()->closeAllPopups();
86 return eventAccepted;
87}
88
89bool ClientArea::deliverEvent(const PointerEvent &event)
90{
91 const auto pointInScreen = m_screen->mapFromLocal(
92 dom::mapPoint(event.target(), m_screen->element(), event.localPoint));
93
94 const auto geometryF = m_screen->geometry().toRectF();
95 const QPointF targetPointClippedToScreen(
96 qBound(geometryF.left(), pointInScreen.x(), geometryF.right()),
97 qBound(geometryF.top(), pointInScreen.y(), geometryF.bottom()));
98
99 if (event.pointerType == PointerType::Mouse) {
100 const QEvent::Type eventType =
102
103 return eventType != QEvent::None
106 m_window->window()->mapFromGlobal(targetPointClippedToScreen),
107 targetPointClippedToScreen, event.mouseButtons, event.mouseButton,
108 eventType, event.modifiers);
109 }
110
111 if (event.pointerType == PointerType::Pen) {
112 qreal pressure;
113 switch (event.type) {
116 pressure = event.pressure;
117 break;
119 pressure = 0.0;
120 break;
121 default:
122 return false;
123 }
124 // Tilt in the browser is in the range +-90, but QTabletEvent only goes to +-60.
125 qreal xTilt = qBound(-60.0, event.tiltX, 60.0);
126 qreal yTilt = qBound(-60.0, event.tiltY, 60.0);
127 // Barrel rotation is reported as 0 to 359, but QTabletEvent wants a signed value.
128 qreal rotation = event.twist > 180.0 ? 360.0 - event.twist : event.twist;
130 m_window->window(), QWasmIntegration::getTimestamp(), m_screen->tabletDevice(),
131 m_window->window()->mapFromGlobal(targetPointClippedToScreen),
132 targetPointClippedToScreen, event.mouseButtons, pressure, xTilt, yTilt,
133 event.tangentialPressure, rotation, event.modifiers);
134 }
135
137
138 QPointF pointInTargetWindowCoords =
139 QPointF(m_window->window()->mapFromGlobal(targetPointClippedToScreen));
140 QPointF normalPosition(pointInTargetWindowCoords.x() / m_window->window()->width(),
141 pointInTargetWindowCoords.y() / m_window->window()->height());
142
143 const auto tp = m_pointerIdToTouchPoints.find(event.pointerId);
144 if (event.pointerType != PointerType::Pen && tp != m_pointerIdToTouchPoints.end()) {
145 touchPoint = &tp.value();
146 } else {
147 touchPoint = &m_pointerIdToTouchPoints
149 .value();
150
151 // Assign touch point id. TouchPoint::id is int, but QGuiApplicationPrivate::processTouchEvent()
152 // will not synthesize mouse events for touch points with negative id; use the absolute value for
153 // the touch point id.
154 touchPoint->id = qAbs(event.pointerId);
155
157 }
158
159 const bool stationaryTouchPoint = (normalPosition == touchPoint->normalPosition);
160 touchPoint->normalPosition = normalPosition;
161 touchPoint->area = QRectF(targetPointClippedToScreen, QSizeF(event.width, event.height))
162 .translated(-event.width / 2, -event.height / 2);
163 touchPoint->pressure = event.pressure;
164
165 switch (event.type) {
168 break;
170 touchPoint->state = (stationaryTouchPoint ? QEventPoint::State::Stationary
172 break;
173 default:
174 break;
175 }
176
177 QList<QWindowSystemInterface::TouchPoint> touchPointList;
178 touchPointList.reserve(m_pointerIdToTouchPoints.size());
179 std::transform(m_pointerIdToTouchPoints.begin(), m_pointerIdToTouchPoints.end(),
180 std::back_inserter(touchPointList),
181 [](const QWindowSystemInterface::TouchPoint &val) { return val; });
182
183 if (event.type == EventType::PointerUp)
184 m_pointerIdToTouchPoints.remove(event.pointerId);
185
186 return event.type == EventType::PointerCancel
188 m_window->window(), QWasmIntegration::getTimestamp(), m_screen->touchDevice(),
189 event.modifiers)
190 : QWindowSystemInterface::handleTouchEvent(
191 m_window->window(), QWasmIntegration::getTimestamp(), m_screen->touchDevice(),
192 touchPointList, event.modifiers);
193}
194
ClientArea(QWasmWindow *window, QWasmScreen *screen, emscripten::val element)
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
static QGuiApplicationPrivate * instance()
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
size_type remove(const Key &key)
Definition qmap.h:300
iterator find(const Key &key)
Definition qmap.h:641
iterator begin()
Definition qmap.h:598
iterator end()
Definition qmap.h:602
size_type size() const
Definition qmap.h:267
\inmodule QtCore\reentrant
Definition qpoint.h:217
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr QRectF translated(qreal dx, qreal dy) const noexcept
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis,...
Definition qrect.h:762
constexpr QRectF toRectF() const noexcept
Definition qrect.h:857
\inmodule QtCore
Definition qsize.h:208
static QWasmDrag * instance()
Definition qwasmdrag.cpp:80
static quint64 getTimestamp()
emscripten::val element() const
QPointF mapFromLocal(const QPointF &p) const
QPointingDevice * touchDevice()
Definition qwasmscreen.h:41
QPointingDevice * tabletDevice()
Definition qwasmscreen.h:42
QRect geometry() const override
Reimplement in subclass to return the pixel geometry of the screen.
QWindow * window() const
Definition qwasmwindow.h:90
The QWindowSystemInterface provides an event queue for the QPA platform.
static bool handleTabletEvent(QWindow *window, ulong timestamp, const QPointingDevice *device, const QPointF &local, const QPointF &global, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, Qt::KeyboardModifiers modifiers=Qt::NoModifier)
static bool handleTouchCancelEvent(QWindow *window, const QPointingDevice *device, Qt::KeyboardModifiers mods=Qt::NoModifier)
static bool handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons state, Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
int width
the width of the window's geometry
Definition qwindow.h:82
Qt::WindowFlags flags
the window flags of the window
Definition qwindow.h:79
int height
the height of the window's geometry
Definition qwindow.h:83
EGLImageKHR int int EGLuint64KHR * modifiers
Combined button and popup list for selecting options.
@ WindowDoesNotAcceptFocus
Definition qnamespace.h:236
QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point)
Definition qwasmdom.cpp:250
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
struct _cl_event * event
GLuint GLfloat * val
QScreen * screen
[1]
Definition main.cpp:29
double qreal
Definition qtypes.h:187
aWidget window() -> setWindowTitle("New Window Title")
[2]
static std::optional< DragEvent > fromWeb(emscripten::val webEvent, QWindow *targetQWindow)
static constexpr QEvent::Type mouseEventTypeFromEventType(EventType eventType, WindowArea windowArea)
Definition qwasmevent.h:185
static std::optional< PointerEvent > fromWeb(emscripten::val webEvent)