wasm: move qwasmwindowclientarea content to qwasmwindow
This allows us to keep all event handlers in one place. Move event handler registration to registerEventHandlers(), which is called from the QWasmWindow constructor. Change-Id: I31f22d6eb876b92bb15d4a140e0569f0288a5915 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
59e057ef42
commit
adce1fe9b5
@ -30,7 +30,6 @@ qt_internal_add_plugin(QWasmIntegrationPlugin
|
|||||||
qwasmservices.cpp qwasmservices.h
|
qwasmservices.cpp qwasmservices.h
|
||||||
qwasmtheme.cpp qwasmtheme.h
|
qwasmtheme.cpp qwasmtheme.h
|
||||||
qwasmwindow.cpp qwasmwindow.h
|
qwasmwindow.cpp qwasmwindow.h
|
||||||
qwasmwindowclientarea.cpp qwasmwindowclientarea.h
|
|
||||||
qwasmwindowtreenode.cpp qwasmwindowtreenode.h
|
qwasmwindowtreenode.cpp qwasmwindowtreenode.h
|
||||||
qwasmwindownonclientarea.cpp qwasmwindownonclientarea.h
|
qwasmwindownonclientarea.cpp qwasmwindownonclientarea.h
|
||||||
qwasminputcontext.cpp qwasminputcontext.h
|
qwasminputcontext.cpp qwasminputcontext.h
|
||||||
|
@ -16,13 +16,13 @@
|
|||||||
#include "qwasmintegration.h"
|
#include "qwasmintegration.h"
|
||||||
#include "qwasmkeytranslator.h"
|
#include "qwasmkeytranslator.h"
|
||||||
#include "qwasmwindow.h"
|
#include "qwasmwindow.h"
|
||||||
#include "qwasmwindowclientarea.h"
|
|
||||||
#include "qwasmscreen.h"
|
#include "qwasmscreen.h"
|
||||||
#include "qwasmcompositor.h"
|
#include "qwasmcompositor.h"
|
||||||
#include "qwasmevent.h"
|
#include "qwasmevent.h"
|
||||||
#include "qwasmeventdispatcher.h"
|
#include "qwasmeventdispatcher.h"
|
||||||
#include "qwasmaccessibility.h"
|
#include "qwasmaccessibility.h"
|
||||||
#include "qwasmclipboard.h"
|
#include "qwasmclipboard.h"
|
||||||
|
#include "qwasmdrag.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -65,8 +65,6 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
|
|||||||
m_nonClientArea = std::make_unique<NonClientArea>(this, m_decoratedWindow);
|
m_nonClientArea = std::make_unique<NonClientArea>(this, m_decoratedWindow);
|
||||||
m_nonClientArea->titleBar()->setTitle(window()->title());
|
m_nonClientArea->titleBar()->setTitle(window()->title());
|
||||||
|
|
||||||
m_clientArea = std::make_unique<ClientArea>(this, compositor->screen(), m_window);
|
|
||||||
|
|
||||||
m_window.set("className", "qt-window");
|
m_window.set("className", "qt-window");
|
||||||
m_decoratedWindow.call<void>("appendChild", m_window);
|
m_decoratedWindow.call<void>("appendChild", m_window);
|
||||||
|
|
||||||
@ -100,12 +98,64 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
|
|||||||
|
|
||||||
m_flags = window()->flags();
|
m_flags = window()->flags();
|
||||||
|
|
||||||
|
registerEventHandlers();
|
||||||
|
|
||||||
|
setParent(parent());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWasmWindow::registerEventHandlers()
|
||||||
|
{
|
||||||
|
m_pointerDownCallback = std::make_unique<qstdweb::EventCallback>(m_window, "pointerdown",
|
||||||
|
[this](emscripten::val event){ processPointer(PointerEvent(EventType::PointerDown, event)); }
|
||||||
|
);
|
||||||
|
m_pointerMoveCallback = std::make_unique<qstdweb::EventCallback>(m_window, "pointermove",
|
||||||
|
[this](emscripten::val event){ processPointer(PointerEvent(EventType::PointerMove, event)); }
|
||||||
|
);
|
||||||
|
m_pointerUpCallback = std::make_unique<qstdweb::EventCallback>(m_window, "pointerup",
|
||||||
|
[this](emscripten::val event){ processPointer(PointerEvent(EventType::PointerUp, event)); }
|
||||||
|
);
|
||||||
|
m_pointerCancelCallback = std::make_unique<qstdweb::EventCallback>(m_window, "pointercancel",
|
||||||
|
[this](emscripten::val event){ processPointer(PointerEvent(EventType::PointerCancel, event)); }
|
||||||
|
);
|
||||||
m_pointerEnterCallback = std::make_unique<qstdweb::EventCallback>(m_window, "pointerenter",
|
m_pointerEnterCallback = std::make_unique<qstdweb::EventCallback>(m_window, "pointerenter",
|
||||||
[this](emscripten::val event) { this->handlePointerEvent(PointerEvent(EventType::PointerEnter, event)); }
|
[this](emscripten::val event) { this->handlePointerEnterLeaveEvent(PointerEvent(EventType::PointerEnter, event)); }
|
||||||
);
|
);
|
||||||
m_pointerLeaveCallback = std::make_unique<qstdweb::EventCallback>(m_window, "pointerleave",
|
m_pointerLeaveCallback = std::make_unique<qstdweb::EventCallback>(m_window, "pointerleave",
|
||||||
[this](emscripten::val event) { this->handlePointerEvent(PointerEvent(EventType::PointerLeave, event)); }
|
[this](emscripten::val event) { this->handlePointerEnterLeaveEvent(PointerEvent(EventType::PointerLeave, event)); }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
m_window.call<void>("setAttribute", emscripten::val("draggable"), emscripten::val("true"));
|
||||||
|
m_dragStartCallback = std::make_unique<qstdweb::EventCallback>(m_window, "dragstart",
|
||||||
|
[this](emscripten::val event) {
|
||||||
|
DragEvent dragEvent(EventType::DragStart, event, window());
|
||||||
|
QWasmDrag::instance()->onNativeDragStarted(&dragEvent);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
m_dragOverCallback = std::make_unique<qstdweb::EventCallback>(m_window, "dragover",
|
||||||
|
[this](emscripten::val event) {
|
||||||
|
DragEvent dragEvent(EventType::DragOver, event, window());
|
||||||
|
QWasmDrag::instance()->onNativeDragOver(&dragEvent);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
m_dropCallback = std::make_unique<qstdweb::EventCallback>(m_window, "drop",
|
||||||
|
[this](emscripten::val event) {
|
||||||
|
DragEvent dragEvent(EventType::Drop, event, window());
|
||||||
|
QWasmDrag::instance()->onNativeDrop(&dragEvent);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
m_dragEndCallback = std::make_unique<qstdweb::EventCallback>(m_window, "dragend",
|
||||||
|
[this](emscripten::val event) {
|
||||||
|
DragEvent dragEvent(EventType::DragEnd, event, window());
|
||||||
|
QWasmDrag::instance()->onNativeDragFinished(&dragEvent);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
m_dragLeaveCallback = std::make_unique<qstdweb::EventCallback>(m_window, "dragleave",
|
||||||
|
[this](emscripten::val event) {
|
||||||
|
DragEvent dragEvent(EventType::DragLeave, event, window());
|
||||||
|
QWasmDrag::instance()->onNativeDragLeave(&dragEvent);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
m_wheelEventCallback = std::make_unique<qstdweb::EventCallback>( m_window, "wheel",
|
m_wheelEventCallback = std::make_unique<qstdweb::EventCallback>( m_window, "wheel",
|
||||||
[this](emscripten::val event) { this->handleWheelEvent(event); });
|
[this](emscripten::val event) { this->handleWheelEvent(event); });
|
||||||
|
|
||||||
@ -123,8 +173,6 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
|
|||||||
[this](emscripten::val event) { this->handleKeyEvent(KeyEvent(EventType::KeyDown, event, m_deadKeySupport)); });
|
[this](emscripten::val event) { this->handleKeyEvent(KeyEvent(EventType::KeyDown, event, m_deadKeySupport)); });
|
||||||
m_keyUpCallback =std::make_unique<qstdweb::EventCallback>(m_window, "keyup",
|
m_keyUpCallback =std::make_unique<qstdweb::EventCallback>(m_window, "keyup",
|
||||||
[this](emscripten::val event) {this->handleKeyEvent(KeyEvent(EventType::KeyUp, event, m_deadKeySupport)); });
|
[this](emscripten::val event) {this->handleKeyEvent(KeyEvent(EventType::KeyUp, event, m_deadKeySupport)); });
|
||||||
|
|
||||||
setParent(parent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWasmWindow::~QWasmWindow()
|
QWasmWindow::~QWasmWindow()
|
||||||
@ -586,13 +634,13 @@ bool QWasmWindow::processKeyForInputContext(const KeyEvent &event)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmWindow::handlePointerEvent(const PointerEvent &event)
|
void QWasmWindow::handlePointerEnterLeaveEvent(const PointerEvent &event)
|
||||||
{
|
{
|
||||||
if (processPointer(event))
|
if (processPointerEnterLeave(event))
|
||||||
event.webEvent.call<void>("preventDefault");
|
event.webEvent.call<void>("preventDefault");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWasmWindow::processPointer(const PointerEvent &event)
|
bool QWasmWindow::processPointerEnterLeave(const PointerEvent &event)
|
||||||
{
|
{
|
||||||
if (event.pointerType != PointerType::Mouse && event.pointerType != PointerType::Pen)
|
if (event.pointerType != PointerType::Mouse && event.pointerType != PointerType::Pen)
|
||||||
return false;
|
return false;
|
||||||
@ -615,6 +663,136 @@ bool QWasmWindow::processPointer(const PointerEvent &event)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWasmWindow::processPointer(const PointerEvent &event)
|
||||||
|
{
|
||||||
|
switch (event.type) {
|
||||||
|
case EventType::PointerDown:
|
||||||
|
m_window.call<void>("setPointerCapture", event.pointerId);
|
||||||
|
if ((window()->flags() & Qt::WindowDoesNotAcceptFocus)
|
||||||
|
!= Qt::WindowDoesNotAcceptFocus
|
||||||
|
&& window()->isTopLevel())
|
||||||
|
window()->requestActivate();
|
||||||
|
break;
|
||||||
|
case EventType::PointerUp:
|
||||||
|
m_window.call<void>("releasePointerCapture", event.pointerId);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
const bool eventAccepted = deliverPointerEvent(event);
|
||||||
|
if (!eventAccepted && event.type == EventType::PointerDown)
|
||||||
|
QGuiApplicationPrivate::instance()->closeAllPopups();
|
||||||
|
event.webEvent.call<void>("preventDefault");
|
||||||
|
event.webEvent.call<void>("stopPropagation");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QWasmWindow::deliverPointerEvent(const PointerEvent &event)
|
||||||
|
{
|
||||||
|
const auto pointInScreen = platformScreen()->mapFromLocal(
|
||||||
|
dom::mapPoint(event.target(), platformScreen()->element(), event.localPoint));
|
||||||
|
|
||||||
|
const auto geometryF = platformScreen()->geometry().toRectF();
|
||||||
|
const QPointF targetPointClippedToScreen(
|
||||||
|
qBound(geometryF.left(), pointInScreen.x(), geometryF.right()),
|
||||||
|
qBound(geometryF.top(), pointInScreen.y(), geometryF.bottom()));
|
||||||
|
|
||||||
|
if (event.pointerType == PointerType::Mouse) {
|
||||||
|
const QEvent::Type eventType =
|
||||||
|
MouseEvent::mouseEventTypeFromEventType(event.type, WindowArea::Client);
|
||||||
|
|
||||||
|
return eventType != QEvent::None
|
||||||
|
&& QWindowSystemInterface::handleMouseEvent(
|
||||||
|
window(), QWasmIntegration::getTimestamp(),
|
||||||
|
window()->mapFromGlobal(targetPointClippedToScreen),
|
||||||
|
targetPointClippedToScreen, event.mouseButtons, event.mouseButton,
|
||||||
|
eventType, event.modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.pointerType == PointerType::Pen) {
|
||||||
|
qreal pressure;
|
||||||
|
switch (event.type) {
|
||||||
|
case EventType::PointerDown :
|
||||||
|
case EventType::PointerMove :
|
||||||
|
pressure = event.pressure;
|
||||||
|
break;
|
||||||
|
case EventType::PointerUp :
|
||||||
|
pressure = 0.0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Tilt in the browser is in the range +-90, but QTabletEvent only goes to +-60.
|
||||||
|
qreal xTilt = qBound(-60.0, event.tiltX, 60.0);
|
||||||
|
qreal yTilt = qBound(-60.0, event.tiltY, 60.0);
|
||||||
|
// Barrel rotation is reported as 0 to 359, but QTabletEvent wants a signed value.
|
||||||
|
qreal rotation = event.twist > 180.0 ? 360.0 - event.twist : event.twist;
|
||||||
|
return QWindowSystemInterface::handleTabletEvent(
|
||||||
|
window(), QWasmIntegration::getTimestamp(), platformScreen()->tabletDevice(),
|
||||||
|
window()->mapFromGlobal(targetPointClippedToScreen),
|
||||||
|
targetPointClippedToScreen, event.mouseButtons, pressure, xTilt, yTilt,
|
||||||
|
event.tangentialPressure, rotation, event.modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWindowSystemInterface::TouchPoint *touchPoint;
|
||||||
|
|
||||||
|
QPointF pointInTargetWindowCoords =
|
||||||
|
QPointF(window()->mapFromGlobal(targetPointClippedToScreen));
|
||||||
|
QPointF normalPosition(pointInTargetWindowCoords.x() / window()->width(),
|
||||||
|
pointInTargetWindowCoords.y() / window()->height());
|
||||||
|
|
||||||
|
const auto tp = m_pointerIdToTouchPoints.find(event.pointerId);
|
||||||
|
if (event.pointerType != PointerType::Pen && tp != m_pointerIdToTouchPoints.end()) {
|
||||||
|
touchPoint = &tp.value();
|
||||||
|
} else {
|
||||||
|
touchPoint = &m_pointerIdToTouchPoints
|
||||||
|
.insert(event.pointerId, QWindowSystemInterface::TouchPoint())
|
||||||
|
.value();
|
||||||
|
|
||||||
|
// Assign touch point id. TouchPoint::id is int, but QGuiApplicationPrivate::processTouchEvent()
|
||||||
|
// will not synthesize mouse events for touch points with negative id; use the absolute value for
|
||||||
|
// the touch point id.
|
||||||
|
touchPoint->id = qAbs(event.pointerId);
|
||||||
|
|
||||||
|
touchPoint->state = QEventPoint::State::Pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool stationaryTouchPoint = (normalPosition == touchPoint->normalPosition);
|
||||||
|
touchPoint->normalPosition = normalPosition;
|
||||||
|
touchPoint->area = QRectF(targetPointClippedToScreen, QSizeF(event.width, event.height))
|
||||||
|
.translated(-event.width / 2, -event.height / 2);
|
||||||
|
touchPoint->pressure = event.pressure;
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case EventType::PointerUp:
|
||||||
|
touchPoint->state = QEventPoint::State::Released;
|
||||||
|
break;
|
||||||
|
case EventType::PointerMove:
|
||||||
|
touchPoint->state = (stationaryTouchPoint ? QEventPoint::State::Stationary
|
||||||
|
: QEventPoint::State::Updated);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QWindowSystemInterface::TouchPoint> touchPointList;
|
||||||
|
touchPointList.reserve(m_pointerIdToTouchPoints.size());
|
||||||
|
std::transform(m_pointerIdToTouchPoints.begin(), m_pointerIdToTouchPoints.end(),
|
||||||
|
std::back_inserter(touchPointList),
|
||||||
|
[](const QWindowSystemInterface::TouchPoint &val) { return val; });
|
||||||
|
|
||||||
|
if (event.type == EventType::PointerUp)
|
||||||
|
m_pointerIdToTouchPoints.remove(event.pointerId);
|
||||||
|
|
||||||
|
return event.type == EventType::PointerCancel
|
||||||
|
? QWindowSystemInterface::handleTouchCancelEvent(
|
||||||
|
window(), QWasmIntegration::getTimestamp(), platformScreen()->touchDevice(),
|
||||||
|
event.modifiers)
|
||||||
|
: QWindowSystemInterface::handleTouchEvent(
|
||||||
|
window(), QWasmIntegration::getTimestamp(), platformScreen()->touchDevice(),
|
||||||
|
touchPointList, event.modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
void QWasmWindow::handleWheelEvent(const emscripten::val &event)
|
void QWasmWindow::handleWheelEvent(const emscripten::val &event)
|
||||||
{
|
{
|
||||||
if (processWheel(WheelEvent(EventType::Wheel, event)))
|
if (processWheel(WheelEvent(EventType::Wheel, event)))
|
||||||
|
@ -5,21 +5,21 @@
|
|||||||
#define QWASMWINDOW_H
|
#define QWASMWINDOW_H
|
||||||
|
|
||||||
#include "qwasmintegration.h"
|
#include "qwasmintegration.h"
|
||||||
#include <qpa/qplatformwindow.h>
|
|
||||||
#include <qpa/qplatformwindow_p.h>
|
|
||||||
#include <emscripten/html5.h>
|
|
||||||
#include "qwasmbackingstore.h"
|
#include "qwasmbackingstore.h"
|
||||||
#include "qwasmscreen.h"
|
#include "qwasmscreen.h"
|
||||||
#include "qwasmcompositor.h"
|
#include "qwasmcompositor.h"
|
||||||
#include "qwasmwindownonclientarea.h"
|
#include "qwasmwindownonclientarea.h"
|
||||||
#include "qwasmwindowstack.h"
|
#include "qwasmwindowstack.h"
|
||||||
#include "qwasmwindowtreenode.h"
|
#include "qwasmwindowtreenode.h"
|
||||||
|
#include "qwasmevent.h"
|
||||||
|
|
||||||
#include <QtCore/private/qstdweb_p.h>
|
#include <QtCore/private/qstdweb_p.h>
|
||||||
#include "QtGui/qopenglcontext.h"
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
#include <QtOpenGL/qopengltextureblitter.h>
|
#include <qpa/qplatformwindow.h>
|
||||||
|
#include <qpa/qplatformwindow_p.h>
|
||||||
|
|
||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
||||||
|
#include <emscripten/html5.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -29,7 +29,6 @@ namespace qstdweb {
|
|||||||
class EventCallback;
|
class EventCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClientArea;
|
|
||||||
struct KeyEvent;
|
struct KeyEvent;
|
||||||
struct PointerEvent;
|
struct PointerEvent;
|
||||||
class QWasmDeadKeySupport;
|
class QWasmDeadKeySupport;
|
||||||
@ -49,6 +48,8 @@ public:
|
|||||||
static QWasmWindow *fromWindow(QWindow *window);
|
static QWasmWindow *fromWindow(QWindow *window);
|
||||||
QSurfaceFormat format() const override;
|
QSurfaceFormat format() const override;
|
||||||
|
|
||||||
|
void registerEventHandlers();
|
||||||
|
|
||||||
void paint();
|
void paint();
|
||||||
void setZOrder(int order);
|
void setZOrder(int order);
|
||||||
void setWindowCursor(QByteArray cssCursorName);
|
void setWindowCursor(QByteArray cssCursorName);
|
||||||
@ -126,8 +127,10 @@ private:
|
|||||||
bool processKey(const KeyEvent &event);
|
bool processKey(const KeyEvent &event);
|
||||||
void handleKeyForInputContextEvent(EventType eventType, const emscripten::val &event);
|
void handleKeyForInputContextEvent(EventType eventType, const emscripten::val &event);
|
||||||
bool processKeyForInputContext(const KeyEvent &event);
|
bool processKeyForInputContext(const KeyEvent &event);
|
||||||
void handlePointerEvent(const PointerEvent &event);
|
void handlePointerEnterLeaveEvent(const PointerEvent &event);
|
||||||
bool processPointer(const PointerEvent &event);
|
bool processPointerEnterLeave(const PointerEvent &event);
|
||||||
|
void processPointer(const PointerEvent &event);
|
||||||
|
bool deliverPointerEvent(const PointerEvent &event);
|
||||||
void handleWheelEvent(const emscripten::val &event);
|
void handleWheelEvent(const emscripten::val &event);
|
||||||
bool processWheel(const WheelEvent &event);
|
bool processWheel(const WheelEvent &event);
|
||||||
|
|
||||||
@ -144,7 +147,6 @@ private:
|
|||||||
emscripten::val m_context2d = emscripten::val::undefined();
|
emscripten::val m_context2d = emscripten::val::undefined();
|
||||||
|
|
||||||
std::unique_ptr<NonClientArea> m_nonClientArea;
|
std::unique_ptr<NonClientArea> m_nonClientArea;
|
||||||
std::unique_ptr<ClientArea> m_clientArea;
|
|
||||||
|
|
||||||
QWasmWindowTreeNode *m_commitedParent = nullptr;
|
QWasmWindowTreeNode *m_commitedParent = nullptr;
|
||||||
|
|
||||||
@ -153,13 +155,23 @@ private:
|
|||||||
std::unique_ptr<qstdweb::EventCallback> m_keyDownCallbackForInputContext;
|
std::unique_ptr<qstdweb::EventCallback> m_keyDownCallbackForInputContext;
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_keyUpCallbackForInputContext;
|
std::unique_ptr<qstdweb::EventCallback> m_keyUpCallbackForInputContext;
|
||||||
|
|
||||||
|
std::unique_ptr<qstdweb::EventCallback> m_pointerDownCallback;
|
||||||
|
std::unique_ptr<qstdweb::EventCallback> m_pointerMoveCallback;
|
||||||
|
std::unique_ptr<qstdweb::EventCallback> m_pointerUpCallback;
|
||||||
|
std::unique_ptr<qstdweb::EventCallback> m_pointerCancelCallback;
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_pointerLeaveCallback;
|
std::unique_ptr<qstdweb::EventCallback> m_pointerLeaveCallback;
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_pointerEnterCallback;
|
std::unique_ptr<qstdweb::EventCallback> m_pointerEnterCallback;
|
||||||
|
|
||||||
|
std::unique_ptr<qstdweb::EventCallback> m_dragOverCallback;
|
||||||
|
std::unique_ptr<qstdweb::EventCallback> m_dragStartCallback;
|
||||||
|
std::unique_ptr<qstdweb::EventCallback> m_dragEndCallback;
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_dropCallback;
|
std::unique_ptr<qstdweb::EventCallback> m_dropCallback;
|
||||||
|
std::unique_ptr<qstdweb::EventCallback> m_dragLeaveCallback;
|
||||||
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_wheelEventCallback;
|
std::unique_ptr<qstdweb::EventCallback> m_wheelEventCallback;
|
||||||
|
|
||||||
|
QMap<int, QWindowSystemInterface::TouchPoint> m_pointerIdToTouchPoints;
|
||||||
|
|
||||||
Qt::WindowStates m_state = Qt::WindowNoState;
|
Qt::WindowStates m_state = Qt::WindowNoState;
|
||||||
Qt::WindowStates m_previousWindowState = Qt::WindowNoState;
|
Qt::WindowStates m_previousWindowState = Qt::WindowNoState;
|
||||||
|
|
||||||
|
@ -1,198 +0,0 @@
|
|||||||
// 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 "qwasmdrag.h"
|
|
||||||
|
|
||||||
#include <QtGui/private/qguiapplication_p.h>
|
|
||||||
#include <QtGui/qpointingdevice.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)
|
|
||||||
{
|
|
||||||
m_pointerDownCallback = std::make_unique<qstdweb::EventCallback>(element, "pointerdown",
|
|
||||||
[this](emscripten::val event){ processPointer(PointerEvent(EventType::PointerDown, event)); }
|
|
||||||
);
|
|
||||||
m_pointerMoveCallback = std::make_unique<qstdweb::EventCallback>(element, "pointermove",
|
|
||||||
[this](emscripten::val event){ processPointer(PointerEvent(EventType::PointerMove, event)); }
|
|
||||||
);
|
|
||||||
m_pointerUpCallback = std::make_unique<qstdweb::EventCallback>(element, "pointerup",
|
|
||||||
[this](emscripten::val event){ processPointer(PointerEvent(EventType::PointerUp, event)); }
|
|
||||||
);
|
|
||||||
m_pointerCancelCallback = std::make_unique<qstdweb::EventCallback>(element, "pointercancel",
|
|
||||||
[this](emscripten::val event){ processPointer(PointerEvent(EventType::PointerCancel, event)); }
|
|
||||||
);
|
|
||||||
|
|
||||||
element.call<void>("setAttribute", emscripten::val("draggable"), emscripten::val("true"));
|
|
||||||
m_dragStartCallback = std::make_unique<qstdweb::EventCallback>(element, "dragstart",
|
|
||||||
[this](emscripten::val event) {
|
|
||||||
DragEvent dragEvent(EventType::DragStart, event, m_window->window());
|
|
||||||
QWasmDrag::instance()->onNativeDragStarted(&dragEvent);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
m_dragOverCallback = std::make_unique<qstdweb::EventCallback>(element, "dragover",
|
|
||||||
[this](emscripten::val event) {
|
|
||||||
DragEvent dragEvent(EventType::DragOver, event, m_window->window());
|
|
||||||
QWasmDrag::instance()->onNativeDragOver(&dragEvent);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
m_dropCallback = std::make_unique<qstdweb::EventCallback>(element, "drop",
|
|
||||||
[this](emscripten::val event) {
|
|
||||||
DragEvent dragEvent(EventType::Drop, event, m_window->window());
|
|
||||||
QWasmDrag::instance()->onNativeDrop(&dragEvent);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
m_dragEndCallback = std::make_unique<qstdweb::EventCallback>(element, "dragend",
|
|
||||||
[this](emscripten::val event) {
|
|
||||||
DragEvent dragEvent(EventType::DragEnd, event, m_window->window());
|
|
||||||
QWasmDrag::instance()->onNativeDragFinished(&dragEvent);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
m_dragLeaveCallback = std::make_unique<qstdweb::EventCallback>(element, "dragleave",
|
|
||||||
[this](emscripten::val event) {
|
|
||||||
DragEvent dragEvent(EventType::DragLeave, event, m_window->window());
|
|
||||||
QWasmDrag::instance()->onNativeDragLeave(&dragEvent);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientArea::processPointer(const PointerEvent &event)
|
|
||||||
{
|
|
||||||
switch (event.type) {
|
|
||||||
case EventType::PointerDown:
|
|
||||||
m_element.call<void>("setPointerCapture", event.pointerId);
|
|
||||||
if ((m_window->window()->flags() & Qt::WindowDoesNotAcceptFocus)
|
|
||||||
!= Qt::WindowDoesNotAcceptFocus
|
|
||||||
&& m_window->window()->isTopLevel())
|
|
||||||
m_window->window()->requestActivate();
|
|
||||||
break;
|
|
||||||
case EventType::PointerUp:
|
|
||||||
m_element.call<void>("releasePointerCapture", event.pointerId);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
const bool eventAccepted = deliverEvent(event);
|
|
||||||
if (!eventAccepted && event.type == EventType::PointerDown)
|
|
||||||
QGuiApplicationPrivate::instance()->closeAllPopups();
|
|
||||||
event.webEvent.call<void>("preventDefault");
|
|
||||||
event.webEvent.call<void>("stopPropagation");
|
|
||||||
}
|
|
||||||
|
|
||||||
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()));
|
|
||||||
|
|
||||||
if (event.pointerType == PointerType::Mouse) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.pointerType == PointerType::Pen) {
|
|
||||||
qreal pressure;
|
|
||||||
switch (event.type) {
|
|
||||||
case EventType::PointerDown :
|
|
||||||
case EventType::PointerMove :
|
|
||||||
pressure = event.pressure;
|
|
||||||
break;
|
|
||||||
case EventType::PointerUp :
|
|
||||||
pressure = 0.0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Tilt in the browser is in the range +-90, but QTabletEvent only goes to +-60.
|
|
||||||
qreal xTilt = qBound(-60.0, event.tiltX, 60.0);
|
|
||||||
qreal yTilt = qBound(-60.0, event.tiltY, 60.0);
|
|
||||||
// Barrel rotation is reported as 0 to 359, but QTabletEvent wants a signed value.
|
|
||||||
qreal rotation = event.twist > 180.0 ? 360.0 - event.twist : event.twist;
|
|
||||||
return QWindowSystemInterface::handleTabletEvent(
|
|
||||||
m_window->window(), QWasmIntegration::getTimestamp(), m_screen->tabletDevice(),
|
|
||||||
m_window->window()->mapFromGlobal(targetPointClippedToScreen),
|
|
||||||
targetPointClippedToScreen, event.mouseButtons, pressure, xTilt, yTilt,
|
|
||||||
event.tangentialPressure, rotation, event.modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
QWindowSystemInterface::TouchPoint *touchPoint;
|
|
||||||
|
|
||||||
QPointF pointInTargetWindowCoords =
|
|
||||||
QPointF(m_window->window()->mapFromGlobal(targetPointClippedToScreen));
|
|
||||||
QPointF normalPosition(pointInTargetWindowCoords.x() / m_window->window()->width(),
|
|
||||||
pointInTargetWindowCoords.y() / m_window->window()->height());
|
|
||||||
|
|
||||||
const auto tp = m_pointerIdToTouchPoints.find(event.pointerId);
|
|
||||||
if (event.pointerType != PointerType::Pen && tp != m_pointerIdToTouchPoints.end()) {
|
|
||||||
touchPoint = &tp.value();
|
|
||||||
} else {
|
|
||||||
touchPoint = &m_pointerIdToTouchPoints
|
|
||||||
.insert(event.pointerId, QWindowSystemInterface::TouchPoint())
|
|
||||||
.value();
|
|
||||||
|
|
||||||
// Assign touch point id. TouchPoint::id is int, but QGuiApplicationPrivate::processTouchEvent()
|
|
||||||
// will not synthesize mouse events for touch points with negative id; use the absolute value for
|
|
||||||
// the touch point id.
|
|
||||||
touchPoint->id = qAbs(event.pointerId);
|
|
||||||
|
|
||||||
touchPoint->state = QEventPoint::State::Pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool stationaryTouchPoint = (normalPosition == touchPoint->normalPosition);
|
|
||||||
touchPoint->normalPosition = normalPosition;
|
|
||||||
touchPoint->area = QRectF(targetPointClippedToScreen, QSizeF(event.width, event.height))
|
|
||||||
.translated(-event.width / 2, -event.height / 2);
|
|
||||||
touchPoint->pressure = event.pressure;
|
|
||||||
|
|
||||||
switch (event.type) {
|
|
||||||
case EventType::PointerUp:
|
|
||||||
touchPoint->state = QEventPoint::State::Released;
|
|
||||||
break;
|
|
||||||
case EventType::PointerMove:
|
|
||||||
touchPoint->state = (stationaryTouchPoint ? QEventPoint::State::Stationary
|
|
||||||
: QEventPoint::State::Updated);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QWindowSystemInterface::TouchPoint> touchPointList;
|
|
||||||
touchPointList.reserve(m_pointerIdToTouchPoints.size());
|
|
||||||
std::transform(m_pointerIdToTouchPoints.begin(), m_pointerIdToTouchPoints.end(),
|
|
||||||
std::back_inserter(touchPointList),
|
|
||||||
[](const QWindowSystemInterface::TouchPoint &val) { return val; });
|
|
||||||
|
|
||||||
if (event.type == EventType::PointerUp)
|
|
||||||
m_pointerIdToTouchPoints.remove(event.pointerId);
|
|
||||||
|
|
||||||
return event.type == EventType::PointerCancel
|
|
||||||
? QWindowSystemInterface::handleTouchCancelEvent(
|
|
||||||
m_window->window(), QWasmIntegration::getTimestamp(), m_screen->touchDevice(),
|
|
||||||
event.modifiers)
|
|
||||||
: QWindowSystemInterface::handleTouchEvent(
|
|
||||||
m_window->window(), QWasmIntegration::getTimestamp(), m_screen->touchDevice(),
|
|
||||||
touchPointList, event.modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
|
@ -1,53 +0,0 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
|
||||||
|
|
||||||
#ifndef QWASMWINDOWCLIENTAREA_H
|
|
||||||
#define QWASMWINDOWCLIENTAREA_H
|
|
||||||
|
|
||||||
#include <QtCore/qnamespace.h>
|
|
||||||
#include <qpa/qwindowsysteminterface.h>
|
|
||||||
#include <QtCore/QMap>
|
|
||||||
|
|
||||||
#include <emscripten/val.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
namespace qstdweb {
|
|
||||||
class EventCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PointerEvent;
|
|
||||||
class QWasmScreen;
|
|
||||||
class QWasmWindow;
|
|
||||||
|
|
||||||
class ClientArea
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ClientArea(QWasmWindow *window, QWasmScreen *screen, emscripten::val element);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void processPointer(const PointerEvent &event);
|
|
||||||
bool deliverEvent(const PointerEvent &event);
|
|
||||||
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_pointerDownCallback;
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_pointerMoveCallback;
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_pointerUpCallback;
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_pointerCancelCallback;
|
|
||||||
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_dragOverCallback;
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_dragStartCallback;
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_dragEndCallback;
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_dropCallback;
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_dragLeaveCallback;
|
|
||||||
|
|
||||||
QMap<int, QWindowSystemInterface::TouchPoint> m_pointerIdToTouchPoints;
|
|
||||||
|
|
||||||
QWasmScreen *m_screen;
|
|
||||||
QWasmWindow *m_window;
|
|
||||||
emscripten::val m_element;
|
|
||||||
};
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
#endif // QWASMWINDOWNONCLIENTAREA_H
|
|
Loading…
x
Reference in New Issue
Block a user