diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 8cf0bf12af3..b1673908500 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -901,9 +901,10 @@ bool QWasmCompositor::processPointer(const PointerEvent& event) const QPoint targetPointInScreenCoords = screen()->geometry().topLeft() + event.point; QWindow *const targetWindow = ([this, &targetPointInScreenCoords]() -> QWindow * { - auto *targetWindow = - m_windowManipulation.operation() == WindowManipulation::Operation::None ? - screen()->compositor()->windowAt(targetPointInScreenCoords, 5) : nullptr; + auto *targetWindow = m_mouseCaptureWindow != nullptr ? m_mouseCaptureWindow.get() + : m_windowManipulation.operation() == WindowManipulation::Operation::None + ? screen()->compositor()->windowAt(targetPointInScreenCoords, 5) + : nullptr; return targetWindow ? targetWindow : m_lastMouseTargetWindow.get(); })(); @@ -997,6 +998,8 @@ bool QWasmCompositor::processPointer(const PointerEvent& event) bool QWasmCompositor::deliverEventToTarget(const PointerEvent &event, QWindow *eventTarget) { + Q_ASSERT(!m_mouseCaptureWindow || m_mouseCaptureWindow.get() == eventTarget); + const QPoint pointInScreenCoords = screen()->geometry().topLeft() + event.point; const QPoint targetPointClippedToScreen( std::max(screen()->geometry().left(), @@ -1016,8 +1019,8 @@ bool QWasmCompositor::deliverEventToTarget(const PointerEvent &event, QWindow *e } WindowArea windowArea = WindowArea::Client; - if (!eventTarget->geometry().contains(targetPointClippedToScreen) - && !deliveringToPreviouslyClickedWindow) { + if (!deliveringToPreviouslyClickedWindow && !m_mouseCaptureWindow + && !eventTarget->geometry().contains(targetPointClippedToScreen)) { if (!eventTarget->frameGeometry().contains(targetPointClippedToScreen)) return false; windowArea = WindowArea::NonClient; @@ -1288,6 +1291,17 @@ int QWasmCompositor::handleTouch(int eventType, const EmscriptenTouchEvent *touc 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; diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h index c883fc310df..8a6fd400d38 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.h +++ b/src/plugins/platforms/wasm/qwasmcompositor.h @@ -123,6 +123,8 @@ public: bool processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent); bool processWheel(int eventType, const EmscriptenWheelEvent *wheelEvent); int handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent); + void setCapture(QWasmWindow *window); + void releaseCapture(); bool processMouseEnter(const EmscriptenMouseEvent *mouseEvent); bool processMouseLeave(); @@ -218,6 +220,7 @@ private: QPointer m_pressedWindow; QPointer m_lastMouseTargetWindow; + QPointer m_mouseCaptureWindow; std::unique_ptr m_pointerDownCallback; std::unique_ptr m_pointerMoveCallback; diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 16b4c6f53f6..ca58c52b2cb 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -438,4 +438,13 @@ void QWasmWindow::requestActivateWindow() QPlatformWindow::requestActivateWindow(); } +bool QWasmWindow::setMouseGrabEnabled(bool grab) +{ + if (grab) + m_compositor->setCapture(this); + else + m_compositor->releaseCapture(); + return true; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index 6503c4a5c68..f1fc5e061c5 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -65,7 +65,7 @@ public: void setWindowState(Qt::WindowStates state) override; void applyWindowState(); bool setKeyboardGrabEnabled(bool) override { return false; } - bool setMouseGrabEnabled(bool) override { return false; } + bool setMouseGrabEnabled(bool grab) final; protected: void invalidate();