wasm: improve event coordinate handling

targetX and targetY are canvas-local coordinates,
while Qt generally works with window-local and global
coordinates.

Add coordinate mapping calls where needed and make
sure we pass correct coordinate types to Qt.

This starts mattering when we have canvases which
are not located at (0, 0).

Change-Id: I28563310ca17d0cc5535317cff99fcd82d3723db
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
This commit is contained in:
Morten Johan Sørvig 2019-04-02 01:18:29 +02:00
parent 7bae1bd5cb
commit e227c33455
3 changed files with 35 additions and 29 deletions

View File

@ -193,7 +193,7 @@ void QWasmCompositor::requestRedraw()
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
} }
QWindow *QWasmCompositor::windowAt(QPoint p, int padding) const QWindow *QWasmCompositor::windowAt(QPoint globalPoint, int padding) const
{ {
int index = m_windowStack.count() - 1; int index = m_windowStack.count() - 1;
// qDebug() << "window at" << "point" << p << "window count" << index; // qDebug() << "window at" << "point" << p << "window count" << index;
@ -205,7 +205,7 @@ QWindow *QWasmCompositor::windowAt(QPoint p, int padding) const
QRect geometry = compositedWindow.window->windowFrameGeometry() QRect geometry = compositedWindow.window->windowFrameGeometry()
.adjusted(-padding, -padding, padding, padding); .adjusted(-padding, -padding, padding, padding);
if (compositedWindow.visible && geometry.contains(p)) if (compositedWindow.visible && geometry.contains(globalPoint))
return m_windowStack.at(index)->window(); return m_windowStack.at(index)->window();
--index; --index;
} }

View File

@ -116,7 +116,7 @@ public:
void redrawWindowContent(); void redrawWindowContent();
void requestRedraw(); void requestRedraw();
QWindow *windowAt(QPoint p, int padding = 0) const; QWindow *windowAt(QPoint globalPoint, int padding = 0) const;
QWindow *keyWindow() const; QWindow *keyWindow() const;
bool event(QEvent *event); bool event(QEvent *event);

View File

@ -549,22 +549,22 @@ void resizeWindow(QWindow *window, QWasmWindow::ResizeMode mode,
void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent) void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent)
{ {
auto timestamp = mouseEvent->timestamp; auto timestamp = mouseEvent->timestamp;
QPoint point(mouseEvent->targetX, mouseEvent->targetY); QPoint targetPoint(mouseEvent->targetX, mouseEvent->targetY);
QPoint globalPoint = screen()->geometry().topLeft() + targetPoint;
QEvent::Type buttonEventType = QEvent::None; QEvent::Type buttonEventType = QEvent::None;
Qt::MouseButton button = translateMouseButton(mouseEvent->button); Qt::MouseButton button = translateMouseButton(mouseEvent->button);
Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent); Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent);
QWindow *window2 = screen()->compositor()->windowAt(point, 5); QWindow *window2 = screen()->compositor()->windowAt(globalPoint, 5);
if (window2 != nullptr) if (window2 == nullptr)
lastWindow = window2; return;
lastWindow = window2;
QPoint localPoint = window2->mapFromGlobal(globalPoint);
bool interior = window2->geometry().contains(globalPoint);
QWasmWindow *htmlWindow = static_cast<QWasmWindow*>(window2->handle()); QWasmWindow *htmlWindow = static_cast<QWasmWindow*>(window2->handle());
bool interior = window2 && window2->geometry().contains(point);
QPoint localPoint(point.x() - window2->geometry().x(), point.y() - window2->geometry().y());
switch (eventType) { switch (eventType) {
case EMSCRIPTEN_EVENT_MOUSEDOWN: case EMSCRIPTEN_EVENT_MOUSEDOWN:
{ {
@ -580,18 +580,18 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven
pressedWindow = window2; pressedWindow = window2;
buttonEventType = QEvent::MouseButtonPress; buttonEventType = QEvent::MouseButtonPress;
if (!(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized)) { if (!(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized)) {
if (htmlWindow && window2->flags().testFlag(Qt::WindowTitleHint) && htmlWindow->isPointOnTitle(point)) if (htmlWindow && window2->flags().testFlag(Qt::WindowTitleHint) && htmlWindow->isPointOnTitle(globalPoint))
draggedWindow = window2; draggedWindow = window2;
else if (htmlWindow && htmlWindow->isPointOnResizeRegion(point)) { else if (htmlWindow && htmlWindow->isPointOnResizeRegion(globalPoint)) {
draggedWindow = window2; draggedWindow = window2;
resizeMode = htmlWindow->resizeModeAtPoint(point); resizeMode = htmlWindow->resizeModeAtPoint(globalPoint);
resizePoint = point; resizePoint = globalPoint;
resizeStartRect = window2->geometry(); resizeStartRect = window2->geometry();
} }
} }
} }
htmlWindow->injectMousePressed(localPoint, point, button, modifiers); htmlWindow->injectMousePressed(localPoint, globalPoint, button, modifiers);
break; break;
} }
case EMSCRIPTEN_EVENT_MOUSEUP: case EMSCRIPTEN_EVENT_MOUSEUP:
@ -611,7 +611,7 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven
} }
if (oldWindow) if (oldWindow)
oldWindow->injectMouseReleased(localPoint, point, button, modifiers); oldWindow->injectMouseReleased(localPoint, globalPoint, button, modifiers);
break; break;
} }
case EMSCRIPTEN_EVENT_MOUSEMOVE: // drag event case EMSCRIPTEN_EVENT_MOUSEMOVE: // drag event
@ -640,7 +640,7 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven
} }
if (window2 && interior) { if (window2 && interior) {
QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>( QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(
window2, timestamp, localPoint, point, pressedButtons, button, buttonEventType, modifiers); window2, timestamp, localPoint, globalPoint, pressedButtons, button, buttonEventType, modifiers);
} }
} }
@ -675,11 +675,13 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
QWasmEventTranslator *translator = (QWasmEventTranslator*)userData; QWasmEventTranslator *translator = (QWasmEventTranslator*)userData;
Qt::KeyboardModifiers modifiers = translator->translateMouseEventModifier(&mouseEvent); Qt::KeyboardModifiers modifiers = translator->translateMouseEventModifier(&mouseEvent);
auto timestamp = mouseEvent.timestamp; auto timestamp = mouseEvent.timestamp;
QPoint globalPoint(mouseEvent.canvasX, mouseEvent.canvasY); QPoint targetPoint(mouseEvent.targetX, mouseEvent.targetY);
QPoint globalPoint = eventTranslator->screen()->geometry().topLeft() + targetPoint;
QWindow *window2 = eventTranslator->screen()->compositor()->windowAt(globalPoint, 5); QWindow *window2 = eventTranslator->screen()->compositor()->windowAt(globalPoint, 5);
if (!window2)
QPoint localPoint(globalPoint.x() - window2->geometry().x(), globalPoint.y() - window2->geometry().y()); return 0;
QPoint localPoint = window2->mapFromGlobal(globalPoint);
QPoint pixelDelta; QPoint pixelDelta;
@ -709,24 +711,28 @@ int QWasmEventTranslator::handleTouch(int eventType, const EmscriptenTouchEvent
const EmscriptenTouchPoint *touches = &touchEvent->touches[i]; const EmscriptenTouchPoint *touches = &touchEvent->touches[i];
QPoint point(touches->targetX, touches->targetY); QPoint targetPoint(touches->targetX, touches->targetY);
window2 = this->screen()->compositor()->windowAt(point, 5); QPoint globalPoint = screen()->geometry().topLeft() + targetPoint;
window2 = this->screen()->compositor()->windowAt(globalPoint, 5);
if (window2 == nullptr)
continue;
QWindowSystemInterface::TouchPoint touchPoint; QWindowSystemInterface::TouchPoint touchPoint;
touchPoint.area = QRect(0, 0, 8, 8); touchPoint.area = QRect(0, 0, 8, 8);
touchPoint.id = touches->identifier; touchPoint.id = touches->identifier;
touchPoint.pressure = 1.0; touchPoint.pressure = 1.0;
const QPointF screenPos(point); touchPoint.area.moveCenter(globalPoint);
touchPoint.area.moveCenter(screenPos);
const auto tp = pressedTouchIds.constFind(touchPoint.id); const auto tp = pressedTouchIds.constFind(touchPoint.id);
if (tp != pressedTouchIds.constEnd()) if (tp != pressedTouchIds.constEnd())
touchPoint.normalPosition = tp.value(); touchPoint.normalPosition = tp.value();
QPointF normalPosition(screenPos.x() / window2->width(), QPointF localPoint = QPointF(window2->mapFromGlobal(globalPoint));
screenPos.y() / window2->height()); QPointF normalPosition(localPoint.x() / window2->width(),
localPoint.y() / window2->height());
const bool stationaryTouchPoint = (normalPosition == touchPoint.normalPosition); const bool stationaryTouchPoint = (normalPosition == touchPoint.normalPosition);
touchPoint.normalPosition = normalPosition; touchPoint.normalPosition = normalPosition;