diff --git a/src/plugins/platforms/wasm/CMakeLists.txt b/src/plugins/platforms/wasm/CMakeLists.txt index 17acc40289..15892617ca 100644 --- a/src/plugins/platforms/wasm/CMakeLists.txt +++ b/src/plugins/platforms/wasm/CMakeLists.txt @@ -35,6 +35,7 @@ qt_internal_add_plugin(QWasmIntegrationPlugin qwasmstylepixmaps_p.h qwasmtheme.cpp qwasmtheme.h qwasmwindow.cpp qwasmwindow.h + qwasmwindowclientarea.cpp qwasmwindowclientarea.h qwasmwindownonclientarea.cpp qwasmwindownonclientarea.h qwasminputcontext.cpp qwasminputcontext.h qwasmdrag.cpp qwasmdrag.h diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index a530cd1f7a..b81a4ed5be 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -60,8 +60,6 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen) QWasmCompositor::~QWasmCompositor() { - m_windowUnderMouse.clear(); - if (m_requestAnimationFrameId != -1) emscripten_cancel_animation_frame(m_requestAnimationFrameId); @@ -75,8 +73,6 @@ void QWasmCompositor::deregisterEventHandlers() emscripten_set_keydown_callback(screenElementSelector.constData(), 0, 0, NULL); emscripten_set_keyup_callback(screenElementSelector.constData(), 0, 0, NULL); - emscripten_set_focus_callback(screenElementSelector.constData(), 0, 0, NULL); - emscripten_set_wheel_callback(screenElementSelector.constData(), 0, 0, NULL); emscripten_set_touchstart_callback(screenElementSelector.constData(), 0, 0, NULL); @@ -112,26 +108,6 @@ void QWasmCompositor::initEventHandlers() emscripten_set_keyup_callback(screenElementSelector.constData(), (void *)this, UseCapture, &keyboard_cb); - val screenElement = screen()->element(); - const auto callback = std::function([this](emscripten::val event) { - if (processPointer(*PointerEvent::fromWeb(event))) - event.call("preventDefault"); - }); - - m_pointerDownCallback = - std::make_unique(screenElement, "pointerdown", callback); - m_pointerMoveCallback = - std::make_unique(screenElement, "pointermove", callback); - m_pointerUpCallback = - std::make_unique(screenElement, "pointerup", callback); - m_pointerEnterCallback = - std::make_unique(screenElement, "pointerenter", callback); - m_pointerLeaveCallback = - std::make_unique(screenElement, "pointerleave", callback); - - emscripten_set_focus_callback(screenElementSelector.constData(), (void *)this, UseCapture, - &focus_cb); - emscripten_set_wheel_callback(screenElementSelector.constData(), (void *)this, UseCapture, &wheel_cb); @@ -144,10 +120,10 @@ void QWasmCompositor::initEventHandlers() emscripten_set_touchcancel_callback(screenElementSelector.constData(), (void *)this, UseCapture, &touchCallback); - screenElement.call("addEventListener", std::string("drop"), - val::module_property("qtDrop"), val(true)); - screenElement.set("data-qtdropcontext", // ? unique - emscripten::val(quintptr(reinterpret_cast(screen())))); + screen()->element().call("addEventListener", std::string("drop"), + val::module_property("qtDrop"), val(true)); + screen()->element().set("data-qtdropcontext", // ? unique + emscripten::val(quintptr(reinterpret_cast(screen())))); } void QWasmCompositor::addWindow(QWasmWindow *window) @@ -162,8 +138,6 @@ void QWasmCompositor::removeWindow(QWasmWindow *window) { m_requestUpdateWindows.remove(window); m_windowStack.removeWindow(window); - if (m_lastMouseTargetWindow == window->window()) - m_lastMouseTargetWindow = nullptr; if (m_windowStack.topWindow()) m_windowStack.topWindow()->requestActivateWindow(); @@ -344,15 +318,6 @@ int QWasmCompositor::keyboard_cb(int eventType, const EmscriptenKeyboardEvent *k return static_cast(wasmCompositor->processKeyboard(eventType, keyEvent)); } -int QWasmCompositor::focus_cb(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData) -{ - Q_UNUSED(eventType) - Q_UNUSED(focusEvent) - Q_UNUSED(userData) - - return 0; -} - int QWasmCompositor::wheel_cb(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData) { QWasmCompositor *compositor = (QWasmCompositor *) userData; @@ -365,112 +330,6 @@ int QWasmCompositor::touchCallback(int eventType, const EmscriptenTouchEvent *to return static_cast(compositor->processTouch(eventType, touchEvent)); } -bool QWasmCompositor::processPointer(const PointerEvent& event) -{ - if (event.pointerType != PointerType::Mouse) - return false; - - const auto pointInScreen = screen()->mapFromLocal(event.localPoint); - - QWindow *const targetWindow = ([this, pointInScreen]() -> QWindow * { - auto *targetWindow = m_mouseCaptureWindow != nullptr - ? m_mouseCaptureWindow.get() - : windowAt(pointInScreen, 5); - - return targetWindow ? targetWindow : m_lastMouseTargetWindow.get(); - })(); - if (!targetWindow) - return false; - m_lastMouseTargetWindow = targetWindow; - - const QPoint pointInTargetWindowCoords = targetWindow->mapFromGlobal(pointInScreen); - const bool pointerIsWithinTargetWindowBounds = targetWindow->geometry().contains(pointInScreen); - - if (m_mouseInScreen && m_windowUnderMouse != targetWindow - && pointerIsWithinTargetWindowBounds) { - // delayed mouse enter - enterWindow(targetWindow, pointInTargetWindowCoords, pointInScreen); - m_windowUnderMouse = targetWindow; - } - - switch (event.type) { - case EventType::PointerDown: - { - screen()->element().call("setPointerCapture", event.pointerId); - - if (targetWindow) - targetWindow->requestActivate(); - - break; - } - case EventType::PointerUp: - { - screen()->element().call("releasePointerCapture", event.pointerId); - - break; - } - case EventType::PointerEnter: - processMouseEnter(nullptr); - break; - case EventType::PointerLeave: - processMouseLeave(); - break; - default: - break; - }; - - if (!pointerIsWithinTargetWindowBounds && event.mouseButtons.testFlag(Qt::NoButton)) { - leaveWindow(m_lastMouseTargetWindow); - } - - const bool eventAccepted = deliverEventToTarget(event, targetWindow); - if (!eventAccepted && event.type == EventType::PointerDown) - QGuiApplicationPrivate::instance()->closeAllPopups(); - return eventAccepted; -} - -bool QWasmCompositor::deliverEventToTarget(const PointerEvent &event, QWindow *eventTarget) -{ - Q_ASSERT(!m_mouseCaptureWindow || m_mouseCaptureWindow.get() == eventTarget); - - const auto pointInScreen = screen()->mapFromLocal(event.localPoint); - - const QPoint targetPointClippedToScreen( - std::max(screen()->geometry().left(), - std::min(screen()->geometry().right(), pointInScreen.x())), - std::max(screen()->geometry().top(), - std::min(screen()->geometry().bottom(), pointInScreen.y()))); - - bool deliveringToPreviouslyClickedWindow = false; - - if (!eventTarget) { - if (event.type != EventType::PointerUp || !m_lastMouseTargetWindow) - return false; - - eventTarget = m_lastMouseTargetWindow; - m_lastMouseTargetWindow = nullptr; - deliveringToPreviouslyClickedWindow = true; - } - - WindowArea windowArea = WindowArea::Client; - if (!deliveringToPreviouslyClickedWindow && !m_mouseCaptureWindow - && !eventTarget->geometry().contains(targetPointClippedToScreen)) { - if (!eventTarget->frameGeometry().contains(targetPointClippedToScreen)) - return false; - windowArea = WindowArea::NonClient; - } - - const QEvent::Type eventType = - MouseEvent::mouseEventTypeFromEventType(event.type, windowArea); - - return eventType != QEvent::None && - QWindowSystemInterface::handleMouseEvent( - eventTarget, QWasmIntegration::getTimestamp(), - eventTarget->mapFromGlobal(targetPointClippedToScreen), - targetPointClippedToScreen, event.mouseButtons, event.mouseButton, - eventType, event.modifiers); -} - bool QWasmCompositor::processKeyboard(int eventType, const EmscriptenKeyboardEvent *emKeyEvent) { constexpr bool ProceedToNativeEvent = false; @@ -521,9 +380,8 @@ bool QWasmCompositor::processWheel(int eventType, const EmscriptenWheelEvent *wh scrollFactor = -scrollFactor; // Web scroll deltas are inverted from Qt deltas. Qt::KeyboardModifiers modifiers = KeyboardModifier::getForEvent(*mouseEvent); - QPoint targetPointInScreenElementCoords(mouseEvent->targetX, mouseEvent->targetY); QPoint targetPointInScreenCoords = - screen()->geometry().topLeft() + targetPointInScreenElementCoords; + screen()->mapFromLocal(QPoint(mouseEvent->targetX, mouseEvent->targetY)); QWindow *targetWindow = screen()->compositor()->windowAt(targetPointInScreenCoords, 5); if (!targetWindow) @@ -555,9 +413,8 @@ bool QWasmCompositor::processTouch(int eventType, const EmscriptenTouchEvent *to const EmscriptenTouchPoint *touches = &touchEvent->touches[i]; - QPoint targetPointInScreenElementCoords(touches->targetX, touches->targetY); QPoint targetPointInScreenCoords = - screen()->geometry().topLeft() + targetPointInScreenElementCoords; + screen()->mapFromLocal(QPoint(touches->targetX, touches->targetY)); targetWindow = screen()->compositor()->windowAt(targetPointInScreenCoords, 5); if (targetWindow == nullptr) @@ -624,39 +481,3 @@ bool QWasmCompositor::processTouch(int eventType, const EmscriptenTouchEvent *to return static_cast(accepted); } - -void QWasmCompositor::setCapture(QWasmWindow *window) -{ - Q_ASSERT(std::find(m_windowStack.begin(), m_windowStack.end(), window) != m_windowStack.end()); - m_mouseCaptureWindow = window->window(); -} - -void QWasmCompositor::releaseCapture() -{ - m_mouseCaptureWindow = nullptr; -} - -void QWasmCompositor::leaveWindow(QWindow *window) -{ - m_windowUnderMouse = nullptr; - QWindowSystemInterface::handleLeaveEvent(window); -} - -void QWasmCompositor::enterWindow(QWindow *window, const QPoint &pointInTargetWindowCoords, const QPoint &targetPointInScreenCoords) -{ - QWindowSystemInterface::handleEnterEvent(window, pointInTargetWindowCoords, targetPointInScreenCoords); -} - -bool QWasmCompositor::processMouseEnter(const EmscriptenMouseEvent *mouseEvent) -{ - Q_UNUSED(mouseEvent) - // mouse has entered the screen area - m_mouseInScreen = true; - return true; -} - -bool QWasmCompositor::processMouseLeave() -{ - m_mouseInScreen = false; - return true; -} diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h index 2c0ab6ae26..7e88986216 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.h +++ b/src/plugins/platforms/wasm/qwasmcompositor.h @@ -80,15 +80,10 @@ private: static int focus_cb(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData); static int wheel_cb(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData); - bool processPointer(const PointerEvent& event); - bool deliverEventToTarget(const PointerEvent& event, QWindow *eventTarget); - static int touchCallback(int eventType, const EmscriptenTouchEvent *ev, void *userData); bool processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent); bool processWheel(int eventType, const EmscriptenWheelEvent *wheelEvent); - bool processMouseEnter(const EmscriptenMouseEvent *mouseEvent); - bool processMouseLeave(); bool processTouch(int eventType, const EmscriptenTouchEvent *touchEvent); void enterWindow(QWindow *window, const QPoint &localPoint, const QPoint &globalPoint); @@ -106,25 +101,11 @@ private: int m_requestAnimationFrameId = -1; bool m_inDeliverUpdateRequest = false; - QPointer m_lastMouseTargetWindow; - QPointer m_mouseCaptureWindow; - - std::unique_ptr m_pointerDownCallback; - std::unique_ptr m_pointerMoveCallback; - std::unique_ptr m_pointerUpCallback; - std::unique_ptr m_pointerLeaveCallback; - std::unique_ptr m_pointerEnterCallback; - std::unique_ptr m_touchDevice; QMap m_pressedTouchIds; - bool m_isResizeCursorDisplayed = false; - std::unique_ptr m_eventTranslator; - - bool m_mouseInScreen = false; - QPointer m_windowUnderMouse; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmcssstyle.cpp b/src/plugins/platforms/wasm/qwasmcssstyle.cpp index 2fc2527129..a1c6b6a365 100644 --- a/src/plugins/platforms/wasm/qwasmcssstyle.cpp +++ b/src/plugins/platforms/wasm/qwasmcssstyle.cpp @@ -29,7 +29,6 @@ const char *Style = R"css( .qt-window { box-shadow: rgb(0 0 0 / 20%) 0px 10px 16px 0px, rgb(0 0 0 / 19%) 0px 6px 20px 0px; - pointer-events: none; position: absolute; background-color: lightgray; } @@ -41,7 +40,6 @@ const char *Style = R"css( .resize-outline { position: absolute; - pointer-events: all; display: none; } @@ -119,7 +117,6 @@ const char *Style = R"css( overflow: hidden; height: 18px; padding-bottom: 4px; - pointer-events: all; } .qt-window.has-title-bar .title-bar { @@ -184,7 +181,6 @@ const char *Style = R"css( } .title-bar .action-button { pointer-events: all; - align-self: end; } .qt-window.blocked div { diff --git a/src/plugins/platforms/wasm/qwasmevent.cpp b/src/plugins/platforms/wasm/qwasmevent.cpp index 7276087033..d4f9991feb 100644 --- a/src/plugins/platforms/wasm/qwasmevent.cpp +++ b/src/plugins/platforms/wasm/qwasmevent.cpp @@ -39,7 +39,7 @@ std::optional PointerEvent::fromWeb(emscripten::val event) return std::nullopt; ret.type = *eventType; - ret.currentTarget = event["currentTarget"]; + ret.target = event["target"]; ret.pointerType = event["pointerType"].as() == "mouse" ? PointerType::Mouse : PointerType::Other; ret.mouseButton = MouseEvent::buttonFromWeb(event["button"].as()); diff --git a/src/plugins/platforms/wasm/qwasmevent.h b/src/plugins/platforms/wasm/qwasmevent.h index 7fe68ce6c8..f9d6411d60 100644 --- a/src/plugins/platforms/wasm/qwasmevent.h +++ b/src/plugins/platforms/wasm/qwasmevent.h @@ -110,7 +110,7 @@ QFlags getForEvent( struct Q_CORE_EXPORT Event { EventType type; - emscripten::val currentTarget = emscripten::val::undefined(); + emscripten::val target = emscripten::val::undefined(); }; struct Q_CORE_EXPORT MouseEvent : public Event diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 43fc151d72..07f73f5eb9 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -12,6 +12,7 @@ #include "qwasmbase64iconstore.h" #include "qwasmdom.h" #include "qwasmwindow.h" +#include "qwasmwindowclientarea.h" #include "qwasmscreen.h" #include "qwasmstylepixmaps_p.h" #include "qwasmcompositor.h" @@ -24,6 +25,8 @@ #include +#include + QT_BEGIN_NAMESPACE Q_GUI_EXPORT int qt_defaultDpiX(); @@ -45,6 +48,8 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingSt m_nonClientArea = std::make_unique(this, m_qtWindow); m_nonClientArea->titleBar()->setTitle(window()->title()); + m_clientArea = std::make_unique(this, compositor->screen(), m_canvas); + m_qtWindow.call("appendChild", m_windowContents); m_canvas["classList"].call("add", emscripten::val("qt-window-content")); @@ -65,6 +70,16 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingSt emscripten::val::module_property("specialHTMLTargets").set(canvasSelector(), m_canvas); m_compositor->addWindow(this); + + const auto callback = std::function([this](emscripten::val event) { + if (processPointer(*PointerEvent::fromWeb(event))) + event.call("preventDefault"); + }); + + m_pointerEnterCallback = + std::make_unique(m_qtWindow, "pointerenter", callback); + m_pointerLeaveCallback = + std::make_unique(m_qtWindow, "pointerleave", callback); } QWasmWindow::~QWasmWindow() @@ -106,8 +121,8 @@ void QWasmWindow::onNonClientAreaInteraction() bool QWasmWindow::onNonClientEvent(const PointerEvent &event) { QPoint pointInScreen = platformScreen()->mapFromLocal( - dom::mapPoint(event.currentTarget, platformScreen()->element(), event.localPoint)); - return QWindowSystemInterface::handleMouseEvent( + dom::mapPoint(event.target, platformScreen()->element(), event.localPoint)); + return QWindowSystemInterface::handleMouseEvent( window(), QWasmIntegration::getTimestamp(), window()->mapFromGlobal(pointInScreen), pointInScreen, event.mouseButtons, event.mouseButton, ([event]() { switch (event.type) { @@ -287,12 +302,6 @@ void QWasmWindow::propagateSizeHints() } } -bool QWasmWindow::startSystemResize(Qt::Edges) -{ - // TODO(mikolajboc): This can only be implemented if per-window events are up and running - return false; -} - void QWasmWindow::invalidate() { m_compositor->requestUpdateWindow(this); @@ -374,6 +383,29 @@ void QWasmWindow::applyWindowState() setGeometry(newGeom); } +bool QWasmWindow::processPointer(const PointerEvent &event) +{ + if (event.pointerType != PointerType::Mouse) + return false; + + switch (event.type) { + case EventType::PointerEnter: { + const auto pointInScreen = platformScreen()->mapFromLocal( + dom::mapPoint(event.target, platformScreen()->element(), event.localPoint)); + QWindowSystemInterface::handleEnterEvent( + window(), m_window->mapFromGlobal(pointInScreen), pointInScreen); + break; + } + case EventType::PointerLeave: + QWindowSystemInterface::handleLeaveEvent(window()); + break; + default: + break; + } + + return false; +} + QRect QWasmWindow::normalGeometry() const { return m_normalGeometry; @@ -418,11 +450,8 @@ void QWasmWindow::requestActivateWindow() bool QWasmWindow::setMouseGrabEnabled(bool grab) { - if (grab) - m_compositor->setCapture(this); - else - m_compositor->releaseCapture(); - return true; + Q_UNUSED(grab); + return false; } bool QWasmWindow::windowEvent(QEvent *event) diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index d5a902e8b0..af0353924f 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -20,6 +20,12 @@ QT_BEGIN_NAMESPACE +namespace qstdweb { +class EventCallback; +} + +class ClientArea; + class QWasmWindow final : public QPlatformWindow { public: @@ -59,7 +65,6 @@ public: bool setKeyboardGrabEnabled(bool) override { return false; } bool setMouseGrabEnabled(bool grab) final; bool windowEvent(QEvent *event) final; - bool startSystemResize(Qt::Edges edges) final; QWasmScreen *platformScreen() const; void setBackingStore(QWasmBackingStore *store) { m_backingStore = store; } @@ -76,6 +81,8 @@ private: bool hasTitleBar() const; void applyWindowState(); + bool processPointer(const PointerEvent &event); + QWindow *m_window = nullptr; QWasmCompositor *m_compositor = nullptr; QWasmBackingStore *m_backingStore = nullptr; @@ -89,13 +96,21 @@ private: emscripten::val m_context2d = emscripten::val::undefined(); std::unique_ptr m_nonClientArea; + std::unique_ptr m_clientArea; + + std::unique_ptr m_pointerLeaveCallback; + std::unique_ptr m_pointerEnterCallback; + std::unique_ptr m_pointerMoveCallback; Qt::WindowStates m_state = Qt::WindowNoState; Qt::WindowStates m_previousWindowState = Qt::WindowNoState; Qt::WindowFlags m_flags = Qt::Widget; + QPoint m_lastPointerMovePoint; + WId m_winId = 0; + bool m_wantCapture = false; bool m_hasTitle = false; bool m_needsCompositor = false; long m_requestAnimationFrameId = -1; diff --git a/src/plugins/platforms/wasm/qwasmwindowclientarea.cpp b/src/plugins/platforms/wasm/qwasmwindowclientarea.cpp new file mode 100644 index 0000000000..e3e17baa1e --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmwindowclientarea.cpp @@ -0,0 +1,93 @@ +// 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 +#include + +#include + +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("preventDefault"); + }); + + m_pointerDownCallback = + std::make_unique(element, "pointerdown", callback); + m_pointerMoveCallback = + std::make_unique(element, "pointermove", callback); + m_pointerUpCallback = std::make_unique(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 QPoint pointInTargetWindowCoords = m_window->mapFromGlobal(pointInScreen); + + switch (event.type) { + case EventType::PointerDown: { + m_element.call("setPointerCapture", event.pointerId); + m_window->window()->requestActivate(); + break; + } + case EventType::PointerUp: { + m_element.call("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 QPoint targetPointClippedToScreen( + std::max(m_screen->geometry().left(), + std::min(m_screen->geometry().right(), pointInScreen.x())), + std::max(m_screen->geometry().top(), + std::min(m_screen->geometry().bottom(), pointInScreen.y()))); + + 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 diff --git a/src/plugins/platforms/wasm/qwasmwindowclientarea.h b/src/plugins/platforms/wasm/qwasmwindowclientarea.h new file mode 100644 index 0000000000..f2fd115e25 --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmwindowclientarea.h @@ -0,0 +1,42 @@ +// 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 + +#include + +#include + +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: + bool processPointer(const PointerEvent &event); + bool deliverEvent(const PointerEvent &event); + + std::unique_ptr m_pointerDownCallback; + std::unique_ptr m_pointerMoveCallback; + std::unique_ptr m_pointerUpCallback; + + QWasmScreen *m_screen; + QWasmWindow *m_window; + emscripten::val m_element; +}; + +QT_END_NAMESPACE +#endif // QWASMWINDOWNONCLIENTAREA_H diff --git a/src/plugins/platforms/wasm/qwasmwindownonclientarea.cpp b/src/plugins/platforms/wasm/qwasmwindownonclientarea.cpp index 170cbbfa31..304f678add 100644 --- a/src/plugins/platforms/wasm/qwasmwindownonclientarea.cpp +++ b/src/plugins/platforms/wasm/qwasmwindownonclientarea.cpp @@ -55,14 +55,16 @@ void WebImageButton::setCallbacks(Callbacks callbacks) if (callbacks) { if (!m_webClickEventCallback) { m_webMouseDownEventCallback = std::make_unique( - m_containerElement, "mousedown", [this](emscripten::val event) { + m_containerElement, "pointerdown", [this](emscripten::val event) { event.call("preventDefault"); event.call("stopPropagation"); m_callbacks.onInteraction(); }); m_webClickEventCallback = std::make_unique( - m_containerElement, "click", - [this](emscripten::val) { m_callbacks.onClick(); }); + m_containerElement, "click", [this](emscripten::val event) { + m_callbacks.onClick(); + event.call("stopPropagation"); + }); } } else { m_webMouseDownEventCallback.reset(); @@ -104,12 +106,10 @@ Resizer::ResizerElement::ResizerElement(emscripten::val parentElement, Qt::Edges event.call("preventDefault"); event.call("stopPropagation"); }); - m_mouseDragEvent = std::make_unique( + m_mouseMoveEvent = std::make_unique( m_element, "pointermove", [this](emscripten::val event) { - if (onPointerMove(*PointerEvent::fromWeb(event))) { + if (onPointerMove(*PointerEvent::fromWeb(event))) event.call("preventDefault"); - event.call("stopPropagation"); - } }); m_mouseUpEvent = std::make_unique( m_element, "pointerup", [this](emscripten::val event) { @@ -193,7 +193,7 @@ void Resizer::startResize(Qt::Edges resizeEdges, const PointerEvent &event) m_currentResizeData.reset(new ResizeData{ .edges = resizeEdges, .originInScreenCoords = dom::mapPoint( - event.currentTarget, m_window->platformScreen()->element(), event.localPoint), + event.target, m_window->platformScreen()->element(), event.localPoint), }); const auto *window = m_window->window(); @@ -213,15 +213,12 @@ void Resizer::startResize(Qt::Edges resizeEdges, const PointerEvent &event) window->maximumHeight() - window->geometry().height())); m_currentResizeData->initialBounds = window->geometry(); - - // TODO(mikolajboc): Implement system resize - // .m_originInScreenCoords = m_systemDragInitData.lastMouseMovePoint, } void Resizer::continueResize(const PointerEvent &event) { - const auto pointInScreen = dom::mapPoint( - event.currentTarget, m_window->platformScreen()->element(), event.localPoint); + const auto pointInScreen = + dom::mapPoint(event.target, m_window->platformScreen()->element(), event.localPoint); const auto amount = pointInScreen - m_currentResizeData->originInScreenCoords; const QPoint cappedGrowVector( std::min(m_currentResizeData->maxGrow.x(), @@ -310,11 +307,10 @@ TitleBar::TitleBar(QWasmWindow *window, emscripten::val parentElement) event.call("preventDefault"); event.call("stopPropagation"); }); - m_mouseDragEvent = std::make_unique( + m_mouseMoveEvent = std::make_unique( m_element, "pointermove", [this](emscripten::val event) { if (onPointerMove(*PointerEvent::fromWeb(event))) { event.call("preventDefault"); - event.call("stopPropagation"); } }); m_mouseUpEvent = std::make_unique( diff --git a/src/plugins/platforms/wasm/qwasmwindownonclientarea.h b/src/plugins/platforms/wasm/qwasmwindownonclientarea.h index b561e8de78..18d1c63f4b 100644 --- a/src/plugins/platforms/wasm/qwasmwindownonclientarea.h +++ b/src/plugins/platforms/wasm/qwasmwindownonclientarea.h @@ -137,7 +137,7 @@ public: Resizer *m_resizer; std::unique_ptr m_mouseDownEvent; - std::unique_ptr m_mouseDragEvent; + std::unique_ptr m_mouseMoveEvent; std::unique_ptr m_mouseUpEvent; }; @@ -203,7 +203,7 @@ private: QPoint m_lastMovePoint; std::unique_ptr m_mouseDownEvent; - std::unique_ptr m_mouseDragEvent; + std::unique_ptr m_mouseMoveEvent; std::unique_ptr m_mouseUpEvent; std::unique_ptr m_doubleClickEvent; };