1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qwasmwindowclientarea.h"
#include "qwasmdom.h"
#include "qwasmevent.h"
#include "qwasmscreen.h"
#include "qwasmwindow.h"
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/qassert.h>
QT_BEGIN_NAMESPACE
ClientArea::ClientArea(QWasmWindow *window, QWasmScreen *screen, emscripten::val element)
: m_screen(screen), m_window(window), m_element(element)
{
const auto callback = std::function([this](emscripten::val event) {
if (processPointer(*PointerEvent::fromWeb(event)))
event.call<void>("preventDefault");
});
m_pointerDownCallback =
std::make_unique<qstdweb::EventCallback>(element, "pointerdown", callback);
m_pointerMoveCallback =
std::make_unique<qstdweb::EventCallback>(element, "pointermove", callback);
m_pointerUpCallback = std::make_unique<qstdweb::EventCallback>(element, "pointerup", callback);
}
bool ClientArea::processPointer(const PointerEvent &event)
{
if (event.pointerType != PointerType::Mouse)
return false;
const auto localScreenPoint =
dom::mapPoint(event.target, m_screen->element(), event.localPoint);
const auto pointInScreen = m_screen->mapFromLocal(localScreenPoint);
const QPointF pointInTargetWindowCoords = m_window->window()->mapFromGlobal(pointInScreen);
switch (event.type) {
case EventType::PointerDown: {
m_element.call<void>("setPointerCapture", event.pointerId);
m_window->window()->requestActivate();
break;
}
case EventType::PointerUp: {
m_element.call<void>("releasePointerCapture", event.pointerId);
break;
}
case EventType::PointerEnter:;
QWindowSystemInterface::handleEnterEvent(
m_window->window(), pointInTargetWindowCoords, pointInScreen);
break;
case EventType::PointerLeave:
QWindowSystemInterface::handleLeaveEvent(m_window->window());
break;
default:
break;
};
const bool eventAccepted = deliverEvent(event);
if (!eventAccepted && event.type == EventType::PointerDown)
QGuiApplicationPrivate::instance()->closeAllPopups();
return eventAccepted;
}
bool ClientArea::deliverEvent(const PointerEvent &event)
{
const auto pointInScreen = m_screen->mapFromLocal(
dom::mapPoint(event.target, m_screen->element(), event.localPoint));
const auto geometryF = m_screen->geometry().toRectF();
const QPointF targetPointClippedToScreen(
qBound(geometryF.left(), pointInScreen.x(), geometryF.right()),
qBound(geometryF.top(), pointInScreen.y(), geometryF.bottom()));
const QEvent::Type eventType =
MouseEvent::mouseEventTypeFromEventType(event.type, WindowArea::Client);
return eventType != QEvent::None
&& QWindowSystemInterface::handleMouseEvent(
m_window->window(), QWasmIntegration::getTimestamp(),
m_window->window()->mapFromGlobal(targetPointClippedToScreen),
targetPointClippedToScreen, event.mouseButtons, event.mouseButton, eventType,
event.modifiers);
}
QT_END_NAMESPACE
|