From d6eea89bc6a4f64c08486a9fd87479707455c381 Mon Sep 17 00:00:00 2001 From: Mikolaj Boc Date: Fri, 3 Feb 2023 18:16:17 +0100 Subject: [PATCH] Use floating point coords for mouse/wheel events on wasm Fractional mouse movements may be reported on hi-dpi. Floating point event fields help us perform correct calculations in line with the web platform. Change-Id: Ic0c457db408c2bf28179ffcfdb032cde64ca8bbd Reviewed-by: Lorn Potter Reviewed-by: Aleksandr Reviakin --- .../platforms/wasm/qwasmcompositor.cpp | 7 +++--- src/plugins/platforms/wasm/qwasmdom.cpp | 10 ++++----- src/plugins/platforms/wasm/qwasmdom.h | 2 +- src/plugins/platforms/wasm/qwasmevent.cpp | 8 +++---- src/plugins/platforms/wasm/qwasmevent.h | 8 +++---- src/plugins/platforms/wasm/qwasmscreen.cpp | 9 ++++---- src/plugins/platforms/wasm/qwasmscreen.h | 4 ++-- src/plugins/platforms/wasm/qwasmwindow.cpp | 22 +++++++++---------- .../platforms/wasm/qwasmwindowclientarea.cpp | 11 +++++----- .../wasm/qwasmwindownonclientarea.cpp | 14 +++++------- .../platforms/wasm/qwasmwindownonclientarea.h | 8 ++++--- 11 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 73faef4999..426fc6a192 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -292,11 +292,10 @@ bool QWasmCompositor::processTouch(int eventType, const EmscriptenTouchEvent *to const EmscriptenTouchPoint *emTouchPoint = &touchEvent->touches[i]; - - QPoint targetPointInScreenCoords = + QPointF targetPointInScreenCoords = screen()->mapFromLocal(QPoint(emTouchPoint->targetX, emTouchPoint->targetY)); - targetWindow = screen()->compositor()->windowAt(targetPointInScreenCoords, 5); + targetWindow = screen()->compositor()->windowAt(targetPointInScreenCoords.toPoint(), 5); if (targetWindow == nullptr) continue; @@ -312,7 +311,7 @@ bool QWasmCompositor::processTouch(int eventType, const EmscriptenTouchEvent *to if (tp != m_pressedTouchIds.constEnd()) touchPoint.normalPosition = tp.value(); - QPointF pointInTargetWindowCoords = QPointF(targetWindow->mapFromGlobal(targetPointInScreenCoords)); + QPointF pointInTargetWindowCoords = targetWindow->mapFromGlobal(targetPointInScreenCoords); QPointF normalPosition(pointInTargetWindowCoords.x() / targetWindow->width(), pointInTargetWindowCoords.y() / targetWindow->height()); diff --git a/src/plugins/platforms/wasm/qwasmdom.cpp b/src/plugins/platforms/wasm/qwasmdom.cpp index f9705f1a1c..9aca102b2e 100644 --- a/src/plugins/platforms/wasm/qwasmdom.cpp +++ b/src/plugins/platforms/wasm/qwasmdom.cpp @@ -25,15 +25,15 @@ void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool fl element["classList"].call("remove", emscripten::val(std::move(cssClassName))); } -QPoint mapPoint(emscripten::val source, emscripten::val target, const QPoint &point) +QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point) { - auto sourceBoundingRect = + const auto sourceBoundingRect = QRectF::fromDOMRect(source.call("getBoundingClientRect")); - auto targetBoundingRect = + const auto targetBoundingRect = QRectF::fromDOMRect(target.call("getBoundingClientRect")); - auto offset = sourceBoundingRect.topLeft() - targetBoundingRect.topLeft(); - return (point + offset).toPoint(); + const auto offset = sourceBoundingRect.topLeft() - targetBoundingRect.topLeft(); + return point + offset; } } // namespace dom diff --git a/src/plugins/platforms/wasm/qwasmdom.h b/src/plugins/platforms/wasm/qwasmdom.h index 80661fce19..074eea7061 100644 --- a/src/plugins/platforms/wasm/qwasmdom.h +++ b/src/plugins/platforms/wasm/qwasmdom.h @@ -24,7 +24,7 @@ inline emscripten::val document() void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool flag); -QPoint mapPoint(emscripten::val source, emscripten::val target, const QPoint &point); +QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point); } // namespace dom QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmevent.cpp b/src/plugins/platforms/wasm/qwasmevent.cpp index 8caea84053..ba6e3e95be 100644 --- a/src/plugins/platforms/wasm/qwasmevent.cpp +++ b/src/plugins/platforms/wasm/qwasmevent.cpp @@ -114,9 +114,9 @@ MouseEvent::MouseEvent(EventType type, emscripten::val event) : Event(type, even // it up here. if (type == EventType::PointerDown) mouseButtons |= mouseButton; - localPoint = QPoint(event["offsetX"].as(), event["offsetY"].as()); - pointInPage = QPoint(event["pageX"].as(), event["pageY"].as()); - pointInViewport = QPoint(event["clientX"].as(), event["clientY"].as()); + localPoint = QPointF(event["offsetX"].as(), event["offsetY"].as()); + pointInPage = QPointF(event["pageX"].as(), event["pageY"].as()); + pointInViewport = QPointF(event["clientX"].as(), event["clientY"].as()); modifiers = KeyboardModifier::getForEvent(event); } @@ -222,7 +222,7 @@ WheelEvent::WheelEvent(EventType type, emscripten::val event) : MouseEvent(type, return DeltaMode::Page; })(); - delta = QPoint(event["deltaX"].as(), event["deltaY"].as()); + delta = QPointF(event["deltaX"].as(), event["deltaY"].as()); webkitDirectionInvertedFromDevice = event["webkitDirectionInvertedFromDevice"].as(); } diff --git a/src/plugins/platforms/wasm/qwasmevent.h b/src/plugins/platforms/wasm/qwasmevent.h index 73bb28d267..383e1300c6 100644 --- a/src/plugins/platforms/wasm/qwasmevent.h +++ b/src/plugins/platforms/wasm/qwasmevent.h @@ -190,9 +190,9 @@ struct MouseEvent : public Event } } - QPoint localPoint; - QPoint pointInPage; - QPoint pointInViewport; + QPointF localPoint; + QPointF pointInPage; + QPointF pointInViewport; Qt::MouseButton mouseButton; Qt::MouseButtons mouseButtons; QFlags modifiers; @@ -241,7 +241,7 @@ struct WheelEvent : public MouseEvent DeltaMode deltaMode; bool webkitDirectionInvertedFromDevice; - QPoint delta; + QPointF delta; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp index cc7c0c43f0..67449b6578 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.cpp +++ b/src/plugins/platforms/wasm/qwasmscreen.cpp @@ -203,15 +203,16 @@ QWindow *QWasmScreen::topLevelAt(const QPoint &p) const return m_compositor->windowAt(p); } -QPoint QWasmScreen::mapFromLocal(const QPoint &p) const +QPointF QWasmScreen::mapFromLocal(const QPointF &p) const { return geometry().topLeft() + p; } -QPoint QWasmScreen::clipPoint(const QPoint &p) const +QPointF QWasmScreen::clipPoint(const QPointF &p) const { - return QPoint(qBound(screen()->geometry().left(), p.x(), screen()->geometry().right()), - qBound(screen()->geometry().top(), p.y(), screen()->geometry().bottom())); + const auto geometryF = screen()->geometry().toRectF(); + return QPointF(qBound(geometryF.left(), p.x(), geometryF.right()), + qBound(geometryF.top(), p.y(), geometryF.bottom())); } void QWasmScreen::invalidateSize() diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h index 98be384522..39791d3d83 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.h +++ b/src/plugins/platforms/wasm/qwasmscreen.h @@ -52,8 +52,8 @@ public: QWindow *topWindow() const; QWindow *topLevelAt(const QPoint &p) const override; - QPoint mapFromLocal(const QPoint &p) const; - QPoint clipPoint(const QPoint &p) const; + QPointF mapFromLocal(const QPointF &p) const; + QPointF clipPoint(const QPointF &p) const; void invalidateSize(); void updateQScreenAndCanvasRenderSize(); diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 3530ff6181..f6e17bf86a 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -165,7 +165,7 @@ void QWasmWindow::onNonClientAreaInteraction() bool QWasmWindow::onNonClientEvent(const PointerEvent &event) { - QPoint pointInScreen = platformScreen()->mapFromLocal( + QPointF pointInScreen = platformScreen()->mapFromLocal( dom::mapPoint(event.target, platformScreen()->element(), event.localPoint)); return QWindowSystemInterface::handleMouseEvent( window(), QWasmIntegration::getTimestamp(), window()->mapFromGlobal(pointInScreen), @@ -504,13 +504,13 @@ bool QWasmWindow::processDrop(const DragEvent &event) return image; }, [this, event](std::unique_ptr data) { - QWindowSystemInterface::handleDrag(window(), data.get(), event.pointInPage, - event.dropAction, event.mouseButton, - event.modifiers); + QWindowSystemInterface::handleDrag(window(), data.get(), + event.pointInPage.toPoint(), event.dropAction, + event.mouseButton, event.modifiers); - QWindowSystemInterface::handleDrop(window(), data.get(), event.pointInPage, - event.dropAction, event.mouseButton, - event.modifiers); + QWindowSystemInterface::handleDrop(window(), data.get(), + event.pointInPage.toPoint(), event.dropAction, + event.mouseButton, event.modifiers); QWindowSystemInterface::handleDrag(window(), nullptr, QPoint(), Qt::IgnoreAction, {}, {}); @@ -536,10 +536,10 @@ bool QWasmWindow::processWheel(const WheelEvent &event) dom::mapPoint(event.target, platformScreen()->element(), event.localPoint)); return QWindowSystemInterface::handleWheelEvent( - window(), QWasmIntegration::getTimestamp(), mapFromGlobal(pointInScreen), pointInScreen, - event.delta * scrollFactor, event.delta * scrollFactor, event.modifiers, - Qt::NoScrollPhase, Qt::MouseEventNotSynthesized, - event.webkitDirectionInvertedFromDevice); + window(), QWasmIntegration::getTimestamp(), window()->mapFromGlobal(pointInScreen), + pointInScreen, (event.delta * scrollFactor).toPoint(), + (event.delta * scrollFactor).toPoint(), event.modifiers, Qt::NoScrollPhase, + Qt::MouseEventNotSynthesized, event.webkitDirectionInvertedFromDevice); } QRect QWasmWindow::normalGeometry() const diff --git a/src/plugins/platforms/wasm/qwasmwindowclientarea.cpp b/src/plugins/platforms/wasm/qwasmwindowclientarea.cpp index e3e17baa1e..d6c6b14b57 100644 --- a/src/plugins/platforms/wasm/qwasmwindowclientarea.cpp +++ b/src/plugins/platforms/wasm/qwasmwindowclientarea.cpp @@ -39,7 +39,7 @@ bool ClientArea::processPointer(const PointerEvent &event) dom::mapPoint(event.target, m_screen->element(), event.localPoint); const auto pointInScreen = m_screen->mapFromLocal(localScreenPoint); - const QPoint pointInTargetWindowCoords = m_window->mapFromGlobal(pointInScreen); + const QPointF pointInTargetWindowCoords = m_window->window()->mapFromGlobal(pointInScreen); switch (event.type) { case EventType::PointerDown: { @@ -73,11 +73,10 @@ 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 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); diff --git a/src/plugins/platforms/wasm/qwasmwindownonclientarea.cpp b/src/plugins/platforms/wasm/qwasmwindownonclientarea.cpp index 8650f7a0c9..4bdc2f072f 100644 --- a/src/plugins/platforms/wasm/qwasmwindownonclientarea.cpp +++ b/src/plugins/platforms/wasm/qwasmwindownonclientarea.cpp @@ -219,7 +219,7 @@ void Resizer::continueResize(const PointerEvent &event) { const auto pointInScreen = dom::mapPoint(event.target, m_window->platformScreen()->element(), event.localPoint); - const auto amount = pointInScreen - m_currentResizeData->originInScreenCoords; + const auto amount = (pointInScreen - m_currentResizeData->originInScreenCoords).toPoint(); const QPoint cappedGrowVector( std::min(m_currentResizeData->maxGrow.x(), std::max(m_currentResizeData->minShrink.x(), @@ -377,8 +377,8 @@ bool TitleBar::onPointerDown(const PointerEvent &event) m_element.call("setPointerCapture", event.pointerId); m_capturedPointerId = event.pointerId; - const QPoint targetPointClippedToScreen = clipPointWithScreen(event.localPoint); - m_lastMovePoint = targetPointClippedToScreen; + m_moveStartWindowPosition = m_window->window()->position(); + m_moveStartPoint = clipPointWithScreen(event.localPoint); m_window->onNonClientEvent(event); return true; } @@ -388,11 +388,9 @@ bool TitleBar::onPointerMove(const PointerEvent &event) if (m_capturedPointerId != event.pointerId) return false; - const QPoint targetPointClippedToScreen = clipPointWithScreen(event.localPoint); - const QPoint delta = targetPointClippedToScreen - m_lastMovePoint; - m_lastMovePoint = targetPointClippedToScreen; + const QPoint delta = (clipPointWithScreen(event.localPoint) - m_moveStartPoint).toPoint(); - m_window->window()->setPosition(m_window->window()->position() + delta); + m_window->window()->setPosition(m_moveStartWindowPosition + delta); m_window->onNonClientEvent(event); return true; } @@ -414,7 +412,7 @@ bool TitleBar::onDoubleClick() return true; } -QPoint TitleBar::clipPointWithScreen(const QPoint &pointInTitleBarCoords) const +QPointF TitleBar::clipPointWithScreen(const QPointF &pointInTitleBarCoords) const { auto *screen = m_window->platformScreen(); return screen->clipPoint(screen->mapFromLocal( diff --git a/src/plugins/platforms/wasm/qwasmwindownonclientarea.h b/src/plugins/platforms/wasm/qwasmwindownonclientarea.h index 8683fc7e6c..29168b9957 100644 --- a/src/plugins/platforms/wasm/qwasmwindownonclientarea.h +++ b/src/plugins/platforms/wasm/qwasmwindownonclientarea.h @@ -4,6 +4,7 @@ #ifndef QWASMWINDOWNONCLIENTAREA_H #define QWASMWINDOWNONCLIENTAREA_H +#include #include #include @@ -155,7 +156,7 @@ private: struct ResizeData { Qt::Edges edges = Qt::Edges::fromInt(0); - QPoint originInScreenCoords; + QPointF originInScreenCoords; QPoint minShrink; QPoint maxGrow; QRect initialBounds; @@ -188,7 +189,7 @@ private: bool onPointerUp(const PointerEvent &event); bool onDoubleClick(); - QPoint clipPointWithScreen(const QPoint &pointInTitleBarCoords) const; + QPointF clipPointWithScreen(const QPointF &pointInTitleBarCoords) const; QWasmWindow *m_window; @@ -201,7 +202,8 @@ private: std::unique_ptr m_icon; int m_capturedPointerId = -1; - QPoint m_lastMovePoint; + QPointF m_moveStartPoint; + QPoint m_moveStartWindowPosition; std::unique_ptr m_mouseDownEvent; std::unique_ptr m_mouseMoveEvent;