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 <lorn.potter@gmail.com> Reviewed-by: Aleksandr Reviakin <aleksandr.reviakin@qt.io>
This commit is contained in:
parent
249d613a60
commit
d6eea89bc6
@ -292,11 +292,10 @@ bool QWasmCompositor::processTouch(int eventType, const EmscriptenTouchEvent *to
|
|||||||
|
|
||||||
const EmscriptenTouchPoint *emTouchPoint = &touchEvent->touches[i];
|
const EmscriptenTouchPoint *emTouchPoint = &touchEvent->touches[i];
|
||||||
|
|
||||||
|
QPointF targetPointInScreenCoords =
|
||||||
QPoint targetPointInScreenCoords =
|
|
||||||
screen()->mapFromLocal(QPoint(emTouchPoint->targetX, emTouchPoint->targetY));
|
screen()->mapFromLocal(QPoint(emTouchPoint->targetX, emTouchPoint->targetY));
|
||||||
|
|
||||||
targetWindow = screen()->compositor()->windowAt(targetPointInScreenCoords, 5);
|
targetWindow = screen()->compositor()->windowAt(targetPointInScreenCoords.toPoint(), 5);
|
||||||
if (targetWindow == nullptr)
|
if (targetWindow == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -312,7 +311,7 @@ bool QWasmCompositor::processTouch(int eventType, const EmscriptenTouchEvent *to
|
|||||||
if (tp != m_pressedTouchIds.constEnd())
|
if (tp != m_pressedTouchIds.constEnd())
|
||||||
touchPoint.normalPosition = tp.value();
|
touchPoint.normalPosition = tp.value();
|
||||||
|
|
||||||
QPointF pointInTargetWindowCoords = QPointF(targetWindow->mapFromGlobal(targetPointInScreenCoords));
|
QPointF pointInTargetWindowCoords = targetWindow->mapFromGlobal(targetPointInScreenCoords);
|
||||||
QPointF normalPosition(pointInTargetWindowCoords.x() / targetWindow->width(),
|
QPointF normalPosition(pointInTargetWindowCoords.x() / targetWindow->width(),
|
||||||
pointInTargetWindowCoords.y() / targetWindow->height());
|
pointInTargetWindowCoords.y() / targetWindow->height());
|
||||||
|
|
||||||
|
@ -25,15 +25,15 @@ void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool fl
|
|||||||
element["classList"].call<void>("remove", emscripten::val(std::move(cssClassName)));
|
element["classList"].call<void>("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<emscripten::val>("getBoundingClientRect"));
|
QRectF::fromDOMRect(source.call<emscripten::val>("getBoundingClientRect"));
|
||||||
auto targetBoundingRect =
|
const auto targetBoundingRect =
|
||||||
QRectF::fromDOMRect(target.call<emscripten::val>("getBoundingClientRect"));
|
QRectF::fromDOMRect(target.call<emscripten::val>("getBoundingClientRect"));
|
||||||
|
|
||||||
auto offset = sourceBoundingRect.topLeft() - targetBoundingRect.topLeft();
|
const auto offset = sourceBoundingRect.topLeft() - targetBoundingRect.topLeft();
|
||||||
return (point + offset).toPoint();
|
return point + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
@ -24,7 +24,7 @@ inline emscripten::val document()
|
|||||||
|
|
||||||
void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool flag);
|
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
|
} // namespace dom
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -114,9 +114,9 @@ MouseEvent::MouseEvent(EventType type, emscripten::val event) : Event(type, even
|
|||||||
// it up here.
|
// it up here.
|
||||||
if (type == EventType::PointerDown)
|
if (type == EventType::PointerDown)
|
||||||
mouseButtons |= mouseButton;
|
mouseButtons |= mouseButton;
|
||||||
localPoint = QPoint(event["offsetX"].as<int>(), event["offsetY"].as<int>());
|
localPoint = QPointF(event["offsetX"].as<qreal>(), event["offsetY"].as<qreal>());
|
||||||
pointInPage = QPoint(event["pageX"].as<int>(), event["pageY"].as<int>());
|
pointInPage = QPointF(event["pageX"].as<qreal>(), event["pageY"].as<qreal>());
|
||||||
pointInViewport = QPoint(event["clientX"].as<int>(), event["clientY"].as<int>());
|
pointInViewport = QPointF(event["clientX"].as<qreal>(), event["clientY"].as<qreal>());
|
||||||
modifiers = KeyboardModifier::getForEvent(event);
|
modifiers = KeyboardModifier::getForEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ WheelEvent::WheelEvent(EventType type, emscripten::val event) : MouseEvent(type,
|
|||||||
return DeltaMode::Page;
|
return DeltaMode::Page;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
delta = QPoint(event["deltaX"].as<int>(), event["deltaY"].as<int>());
|
delta = QPointF(event["deltaX"].as<qreal>(), event["deltaY"].as<qreal>());
|
||||||
|
|
||||||
webkitDirectionInvertedFromDevice = event["webkitDirectionInvertedFromDevice"].as<bool>();
|
webkitDirectionInvertedFromDevice = event["webkitDirectionInvertedFromDevice"].as<bool>();
|
||||||
}
|
}
|
||||||
|
@ -190,9 +190,9 @@ struct MouseEvent : public Event
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint localPoint;
|
QPointF localPoint;
|
||||||
QPoint pointInPage;
|
QPointF pointInPage;
|
||||||
QPoint pointInViewport;
|
QPointF pointInViewport;
|
||||||
Qt::MouseButton mouseButton;
|
Qt::MouseButton mouseButton;
|
||||||
Qt::MouseButtons mouseButtons;
|
Qt::MouseButtons mouseButtons;
|
||||||
QFlags<Qt::KeyboardModifier> modifiers;
|
QFlags<Qt::KeyboardModifier> modifiers;
|
||||||
@ -241,7 +241,7 @@ struct WheelEvent : public MouseEvent
|
|||||||
|
|
||||||
DeltaMode deltaMode;
|
DeltaMode deltaMode;
|
||||||
bool webkitDirectionInvertedFromDevice;
|
bool webkitDirectionInvertedFromDevice;
|
||||||
QPoint delta;
|
QPointF delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -203,15 +203,16 @@ QWindow *QWasmScreen::topLevelAt(const QPoint &p) const
|
|||||||
return m_compositor->windowAt(p);
|
return m_compositor->windowAt(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint QWasmScreen::mapFromLocal(const QPoint &p) const
|
QPointF QWasmScreen::mapFromLocal(const QPointF &p) const
|
||||||
{
|
{
|
||||||
return geometry().topLeft() + p;
|
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()),
|
const auto geometryF = screen()->geometry().toRectF();
|
||||||
qBound(screen()->geometry().top(), p.y(), screen()->geometry().bottom()));
|
return QPointF(qBound(geometryF.left(), p.x(), geometryF.right()),
|
||||||
|
qBound(geometryF.top(), p.y(), geometryF.bottom()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmScreen::invalidateSize()
|
void QWasmScreen::invalidateSize()
|
||||||
|
@ -52,8 +52,8 @@ public:
|
|||||||
QWindow *topWindow() const;
|
QWindow *topWindow() const;
|
||||||
QWindow *topLevelAt(const QPoint &p) const override;
|
QWindow *topLevelAt(const QPoint &p) const override;
|
||||||
|
|
||||||
QPoint mapFromLocal(const QPoint &p) const;
|
QPointF mapFromLocal(const QPointF &p) const;
|
||||||
QPoint clipPoint(const QPoint &p) const;
|
QPointF clipPoint(const QPointF &p) const;
|
||||||
|
|
||||||
void invalidateSize();
|
void invalidateSize();
|
||||||
void updateQScreenAndCanvasRenderSize();
|
void updateQScreenAndCanvasRenderSize();
|
||||||
|
@ -165,7 +165,7 @@ void QWasmWindow::onNonClientAreaInteraction()
|
|||||||
|
|
||||||
bool QWasmWindow::onNonClientEvent(const PointerEvent &event)
|
bool QWasmWindow::onNonClientEvent(const PointerEvent &event)
|
||||||
{
|
{
|
||||||
QPoint pointInScreen = platformScreen()->mapFromLocal(
|
QPointF pointInScreen = platformScreen()->mapFromLocal(
|
||||||
dom::mapPoint(event.target, platformScreen()->element(), event.localPoint));
|
dom::mapPoint(event.target, platformScreen()->element(), event.localPoint));
|
||||||
return QWindowSystemInterface::handleMouseEvent(
|
return QWindowSystemInterface::handleMouseEvent(
|
||||||
window(), QWasmIntegration::getTimestamp(), window()->mapFromGlobal(pointInScreen),
|
window(), QWasmIntegration::getTimestamp(), window()->mapFromGlobal(pointInScreen),
|
||||||
@ -504,13 +504,13 @@ bool QWasmWindow::processDrop(const DragEvent &event)
|
|||||||
return image;
|
return image;
|
||||||
},
|
},
|
||||||
[this, event](std::unique_ptr<QMimeData> data) {
|
[this, event](std::unique_ptr<QMimeData> data) {
|
||||||
QWindowSystemInterface::handleDrag(window(), data.get(), event.pointInPage,
|
QWindowSystemInterface::handleDrag(window(), data.get(),
|
||||||
event.dropAction, event.mouseButton,
|
event.pointInPage.toPoint(), event.dropAction,
|
||||||
event.modifiers);
|
event.mouseButton, event.modifiers);
|
||||||
|
|
||||||
QWindowSystemInterface::handleDrop(window(), data.get(), event.pointInPage,
|
QWindowSystemInterface::handleDrop(window(), data.get(),
|
||||||
event.dropAction, event.mouseButton,
|
event.pointInPage.toPoint(), event.dropAction,
|
||||||
event.modifiers);
|
event.mouseButton, event.modifiers);
|
||||||
|
|
||||||
QWindowSystemInterface::handleDrag(window(), nullptr, QPoint(), Qt::IgnoreAction,
|
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));
|
dom::mapPoint(event.target, platformScreen()->element(), event.localPoint));
|
||||||
|
|
||||||
return QWindowSystemInterface::handleWheelEvent(
|
return QWindowSystemInterface::handleWheelEvent(
|
||||||
window(), QWasmIntegration::getTimestamp(), mapFromGlobal(pointInScreen), pointInScreen,
|
window(), QWasmIntegration::getTimestamp(), window()->mapFromGlobal(pointInScreen),
|
||||||
event.delta * scrollFactor, event.delta * scrollFactor, event.modifiers,
|
pointInScreen, (event.delta * scrollFactor).toPoint(),
|
||||||
Qt::NoScrollPhase, Qt::MouseEventNotSynthesized,
|
(event.delta * scrollFactor).toPoint(), event.modifiers, Qt::NoScrollPhase,
|
||||||
event.webkitDirectionInvertedFromDevice);
|
Qt::MouseEventNotSynthesized, event.webkitDirectionInvertedFromDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect QWasmWindow::normalGeometry() const
|
QRect QWasmWindow::normalGeometry() const
|
||||||
|
@ -39,7 +39,7 @@ bool ClientArea::processPointer(const PointerEvent &event)
|
|||||||
dom::mapPoint(event.target, m_screen->element(), event.localPoint);
|
dom::mapPoint(event.target, m_screen->element(), event.localPoint);
|
||||||
const auto pointInScreen = m_screen->mapFromLocal(localScreenPoint);
|
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) {
|
switch (event.type) {
|
||||||
case EventType::PointerDown: {
|
case EventType::PointerDown: {
|
||||||
@ -73,11 +73,10 @@ bool ClientArea::deliverEvent(const PointerEvent &event)
|
|||||||
const auto pointInScreen = m_screen->mapFromLocal(
|
const auto pointInScreen = m_screen->mapFromLocal(
|
||||||
dom::mapPoint(event.target, m_screen->element(), event.localPoint));
|
dom::mapPoint(event.target, m_screen->element(), event.localPoint));
|
||||||
|
|
||||||
const QPoint targetPointClippedToScreen(
|
const auto geometryF = m_screen->geometry().toRectF();
|
||||||
std::max(m_screen->geometry().left(),
|
const QPointF targetPointClippedToScreen(
|
||||||
std::min(m_screen->geometry().right(), pointInScreen.x())),
|
qBound(geometryF.left(), pointInScreen.x(), geometryF.right()),
|
||||||
std::max(m_screen->geometry().top(),
|
qBound(geometryF.top(), pointInScreen.y(), geometryF.bottom()));
|
||||||
std::min(m_screen->geometry().bottom(), pointInScreen.y())));
|
|
||||||
|
|
||||||
const QEvent::Type eventType =
|
const QEvent::Type eventType =
|
||||||
MouseEvent::mouseEventTypeFromEventType(event.type, WindowArea::Client);
|
MouseEvent::mouseEventTypeFromEventType(event.type, WindowArea::Client);
|
||||||
|
@ -219,7 +219,7 @@ void Resizer::continueResize(const PointerEvent &event)
|
|||||||
{
|
{
|
||||||
const auto pointInScreen =
|
const auto pointInScreen =
|
||||||
dom::mapPoint(event.target, m_window->platformScreen()->element(), event.localPoint);
|
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(
|
const QPoint cappedGrowVector(
|
||||||
std::min(m_currentResizeData->maxGrow.x(),
|
std::min(m_currentResizeData->maxGrow.x(),
|
||||||
std::max(m_currentResizeData->minShrink.x(),
|
std::max(m_currentResizeData->minShrink.x(),
|
||||||
@ -377,8 +377,8 @@ bool TitleBar::onPointerDown(const PointerEvent &event)
|
|||||||
m_element.call<void>("setPointerCapture", event.pointerId);
|
m_element.call<void>("setPointerCapture", event.pointerId);
|
||||||
m_capturedPointerId = event.pointerId;
|
m_capturedPointerId = event.pointerId;
|
||||||
|
|
||||||
const QPoint targetPointClippedToScreen = clipPointWithScreen(event.localPoint);
|
m_moveStartWindowPosition = m_window->window()->position();
|
||||||
m_lastMovePoint = targetPointClippedToScreen;
|
m_moveStartPoint = clipPointWithScreen(event.localPoint);
|
||||||
m_window->onNonClientEvent(event);
|
m_window->onNonClientEvent(event);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -388,11 +388,9 @@ bool TitleBar::onPointerMove(const PointerEvent &event)
|
|||||||
if (m_capturedPointerId != event.pointerId)
|
if (m_capturedPointerId != event.pointerId)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const QPoint targetPointClippedToScreen = clipPointWithScreen(event.localPoint);
|
const QPoint delta = (clipPointWithScreen(event.localPoint) - m_moveStartPoint).toPoint();
|
||||||
const QPoint delta = targetPointClippedToScreen - m_lastMovePoint;
|
|
||||||
m_lastMovePoint = targetPointClippedToScreen;
|
|
||||||
|
|
||||||
m_window->window()->setPosition(m_window->window()->position() + delta);
|
m_window->window()->setPosition(m_moveStartWindowPosition + delta);
|
||||||
m_window->onNonClientEvent(event);
|
m_window->onNonClientEvent(event);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -414,7 +412,7 @@ bool TitleBar::onDoubleClick()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint TitleBar::clipPointWithScreen(const QPoint &pointInTitleBarCoords) const
|
QPointF TitleBar::clipPointWithScreen(const QPointF &pointInTitleBarCoords) const
|
||||||
{
|
{
|
||||||
auto *screen = m_window->platformScreen();
|
auto *screen = m_window->platformScreen();
|
||||||
return screen->clipPoint(screen->mapFromLocal(
|
return screen->clipPoint(screen->mapFromLocal(
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#ifndef QWASMWINDOWNONCLIENTAREA_H
|
#ifndef QWASMWINDOWNONCLIENTAREA_H
|
||||||
#define QWASMWINDOWNONCLIENTAREA_H
|
#define QWASMWINDOWNONCLIENTAREA_H
|
||||||
|
|
||||||
|
#include <QtCore/qrect.h>
|
||||||
#include <QtCore/qtconfigmacros.h>
|
#include <QtCore/qtconfigmacros.h>
|
||||||
#include <QtCore/qnamespace.h>
|
#include <QtCore/qnamespace.h>
|
||||||
|
|
||||||
@ -155,7 +156,7 @@ private:
|
|||||||
struct ResizeData
|
struct ResizeData
|
||||||
{
|
{
|
||||||
Qt::Edges edges = Qt::Edges::fromInt(0);
|
Qt::Edges edges = Qt::Edges::fromInt(0);
|
||||||
QPoint originInScreenCoords;
|
QPointF originInScreenCoords;
|
||||||
QPoint minShrink;
|
QPoint minShrink;
|
||||||
QPoint maxGrow;
|
QPoint maxGrow;
|
||||||
QRect initialBounds;
|
QRect initialBounds;
|
||||||
@ -188,7 +189,7 @@ private:
|
|||||||
bool onPointerUp(const PointerEvent &event);
|
bool onPointerUp(const PointerEvent &event);
|
||||||
bool onDoubleClick();
|
bool onDoubleClick();
|
||||||
|
|
||||||
QPoint clipPointWithScreen(const QPoint &pointInTitleBarCoords) const;
|
QPointF clipPointWithScreen(const QPointF &pointInTitleBarCoords) const;
|
||||||
|
|
||||||
QWasmWindow *m_window;
|
QWasmWindow *m_window;
|
||||||
|
|
||||||
@ -201,7 +202,8 @@ private:
|
|||||||
std::unique_ptr<WebImageButton> m_icon;
|
std::unique_ptr<WebImageButton> m_icon;
|
||||||
|
|
||||||
int m_capturedPointerId = -1;
|
int m_capturedPointerId = -1;
|
||||||
QPoint m_lastMovePoint;
|
QPointF m_moveStartPoint;
|
||||||
|
QPoint m_moveStartWindowPosition;
|
||||||
|
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_mouseDownEvent;
|
std::unique_ptr<qstdweb::EventCallback> m_mouseDownEvent;
|
||||||
std::unique_ptr<qstdweb::EventCallback> m_mouseMoveEvent;
|
std::unique_ptr<qstdweb::EventCallback> m_mouseMoveEvent;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user