diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 788dee6cbc7..5b684a37b2c 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -95,6 +95,7 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen) , pressedButtons(Qt::NoButton) , resizeMode(QWasmCompositor::ResizeNone) , eventTranslator(new QWasmEventTranslator()) + , mouseInCanvas(false) { touchDevice = new QPointingDevice( "touchscreen", 1, QInputDevice::DeviceType::TouchScreen, @@ -106,6 +107,8 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen) QWasmCompositor::~QWasmCompositor() { + windowUnderMouse.clear(); + if (m_requestAnimationFrameId != -1) emscripten_cancel_animation_frame(m_requestAnimationFrameId); @@ -122,6 +125,8 @@ void QWasmCompositor::deregisterEventHandlers() emscripten_set_mousedown_callback(canvasSelector.constData(), 0, 0, NULL); emscripten_set_mouseup_callback(canvasSelector.constData(), 0, 0, NULL); emscripten_set_mousemove_callback(canvasSelector.constData(), 0, 0, NULL); + emscripten_set_mouseenter_callback(canvasSelector.constData(), 0, 0, NULL); + emscripten_set_mouseleave_callback(canvasSelector.constData(), 0, 0, NULL); emscripten_set_focus_callback(canvasSelector.constData(), 0, 0, NULL); @@ -177,6 +182,8 @@ void QWasmCompositor::initEventHandlers() emscripten_set_mousedown_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); emscripten_set_mouseup_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); emscripten_set_mousemove_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); + emscripten_set_mouseenter_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); + emscripten_set_mouseleave_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); emscripten_set_focus_callback(canvasSelector.constData(), (void *)this, 1, &focus_cb); @@ -965,8 +972,12 @@ int QWasmCompositor::mouse_cb(int eventType, const EmscriptenMouseEvent *mouseEv return static_cast(compositor->processMouse(eventType, mouseEvent)); } -int QWasmCompositor::focus_cb(int /*eventType*/, const EmscriptenFocusEvent */*focusEvent*/, void */*userData*/) +int QWasmCompositor::focus_cb(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData) { + Q_UNUSED(eventType) + Q_UNUSED(focusEvent) + Q_UNUSED(userData) + return 0; } @@ -1004,6 +1015,14 @@ bool QWasmCompositor::processMouse(int eventType, const EmscriptenMouseEvent *mo QPoint localPoint = window2->mapFromGlobal(globalPoint); bool interior = window2->geometry().contains(globalPoint); + if (mouseInCanvas) { + if (windowUnderMouse != window2 && interior) { + // delayed mouse enter + enterWindow(window2, localPoint, globalPoint); + windowUnderMouse = window2; + } + } + QWasmWindow *htmlWindow = static_cast(window2->handle()); switch (eventType) { case EMSCRIPTEN_EVENT_MOUSEDOWN: @@ -1100,9 +1119,19 @@ bool QWasmCompositor::processMouse(int eventType, const EmscriptenMouseEvent *mo } break; } - default: // MOUSELEAVE MOUSEENTER + case EMSCRIPTEN_EVENT_MOUSEENTER: + processMouseEnter(mouseEvent); break; + case EMSCRIPTEN_EVENT_MOUSELEAVE: + processMouseLeave(); + break; + default: break; }; + + if (!interior && pressedButtons.testFlag(Qt::NoButton)) { + leaveWindow(lastWindow); + } + if (!window2 && buttonEventType == QEvent::MouseButtonRelease) { window2 = lastWindow; lastWindow = nullptr; @@ -1300,3 +1329,24 @@ int QWasmCompositor::handleTouch(int eventType, const EmscriptenTouchEvent *touc return static_cast(accepted); } + +void QWasmCompositor::leaveWindow(QWindow *window) +{ + windowUnderMouse = nullptr; + QWindowSystemInterface::handleLeaveEvent(window); +} +void QWasmCompositor::enterWindow(QWindow *window, const QPoint &localPoint, const QPoint &globalPoint) +{ + QWindowSystemInterface::handleEnterEvent(window, localPoint, globalPoint); +} +bool QWasmCompositor::processMouseEnter(const EmscriptenMouseEvent *mouseEvent) +{ + // mouse has entered the canvas area + mouseInCanvas = true; + return true; +} +bool QWasmCompositor::processMouseLeave() +{ + mouseInCanvas = false; + return true; +} diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h index 27f518635d6..e98f03743f5 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.h +++ b/src/plugins/platforms/wasm/qwasmcompositor.h @@ -157,6 +157,11 @@ public: int handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent); void resizeWindow(QWindow *window, QWasmCompositor::ResizeMode mode, QRect startRect, QPoint amount); + bool processMouseEnter(const EmscriptenMouseEvent *mouseEvent); + bool processMouseLeave(); + void enterWindow(QWindow* window, const QPoint &localPoint, const QPoint &globalPoint); + void leaveWindow(QWindow* window); + private slots: void frame(); @@ -217,6 +222,9 @@ private: static int touchCallback(int eventType, const EmscriptenTouchEvent *ev, void *userData); QWasmEventTranslator *eventTranslator; + + bool mouseInCanvas; + QPointer windowUnderMouse; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QWasmCompositor::SubControls)