This plugin does not support QCursor::setPos(); emulating movement within the application.
-
I need to lock a mouse pointer in the center in the browser for the first person camera movement. It works on desktop but doesn't work in the browser. You can open the browser console, open the following link, and click inside the client area: https://6670cb99548ca7757dc712a1--small-opengles2-examples-qt6-cpp.netlify.app/ You can leave the looking mouse pointer by Escape key. You will see this message in the console: This plugin does not support QCursor::setPos(); emulating movement within the application. I have created the issue: https://bugreports.qt.io/browse/QTBUG-126429 But perhaps there is some solution.
main.cpp
#include <QtGui/QKeyEvent> #include <QtGui/QMouseEvent> #include <QtGui/QOpenGLFunctions> #include <QtOpenGL/QOpenGLWindow> #include <QtWidgets/QApplication> class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { public: OpenGLWindow() { setTitle("OpenGL ES 2.0, Qt6, C++"); resize(350, 350); } private: void mousePressEvent(QMouseEvent *event) override { Q_UNUSED(event); m_isCursorLooked = true; } void mouseMoveEvent(QMouseEvent *event) override { Q_UNUSED(event); if (m_isCursorLooked) { QPoint before(mapFromGlobal(QCursor::pos())); QPoint center = mapToGlobal(QPoint(width() / 2, height() / 2)); QCursor::setPos(center); int dx = before.x() - mapFromGlobal(QCursor::pos()).x(); int dy = before.y() - mapFromGlobal(QCursor::pos()).y(); qDebug() << dx << dy; } } virtual void keyPressEvent(QKeyEvent *event) override { switch (event->key()) { case Qt::Key::Key_Escape: { m_isCursorLooked = false; break; } default: { break; } } } virtual void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.2f, 0.2f, 0.2f, 1.f); } virtual void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); } bool m_isCursorLooked = false; }; int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL); QApplication app(argc, argv); OpenGLWindow w; w.show(); return app.exec(); }
pro
QT += core gui openglwidgets win32: LIBS += -lopengl32 CONFIG += c++17 SOURCES += \ main.cpp
-
Lorn Potter added a comment in the bug report
The mouse cursor is owned by the browser, and apparently setting mouse position in the browser is not allowed due to security issues.
I will continue to find another way to lock a mouse cursor in the following topic: emscripten_request_pointerlock() returns EMSCRIPTEN_RESULT_UNKNOWN_TARGET
-
When WebAssembly does not allow this what should Qt do then?
-
I think it is the Qt issue because
QCursor::setPos();
is Qt class/method. -
In your bug ticket you already got a comment saying similar thing to what @Christian-Ehrlicher wrote: this is not supported by WebAssembly or not allowed by the browser. So, what can Qt do here? Yes, it has QCursor::setPos(), but if the underlying platform does not support it Qt cannot do anything about it.
-
This ruins my main plans. I wanted to do first person movement in the browser. Let them close the bug report then. My only hope is
document.body.requestPointerLock()
: https://plnkr.co/edit/uuyQpC05gFgTFXIO?preview<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>document.body.requestPointerLock() in JavaScript</title> </head> <body> <script type="module" src="./js/index.js"></script> </body> </html>
index.js
// Lock pointer by click document.onclick = () => { document.body.requestPointerLock(); }; // Print dx and dy document.body.onmousemove = (event) => { if (document.pointerLockElement === document.body) { const dx = event.movementX; const dy = event.movementY; console.log(dx, dy); } };
I call
requestPointerLock
like this, but how to getdx
anddy
in themouseMoveEvent
method?#include <QtGui/QMouseEvent> #include <QtGui/QOpenGLFunctions> #include <QtOpenGL/QOpenGLWindow> #include <QtWidgets/QApplication> #ifdef Q_OS_WASM #include <emscripten.h> #endif #ifdef Q_OS_WASM EM_JS(void, requestPointerLock, (), { document.body.requestPointerLock(); }) #endif class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { public: OpenGLWindow() { setTitle("OpenGL ES 2.0, Qt6, C++"); resize(350, 350); } private: void mousePressEvent(QMouseEvent *event) override { Q_UNUSED(event); requestPointerLock(); } void mouseMoveEvent(QMouseEvent *event) override { Q_UNUSED(event); // How to get dx and dy here? // qDebug() << dx << dy; } virtual void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.2f, 0.2f, 0.2f, 1.f); } virtual void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); } }; int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL); QApplication app(argc, argv); OpenGLWindow w; w.show(); return app.exec(); }
-
Lorn Potter added a comment in the bug report
The mouse cursor is owned by the browser, and apparently setting mouse position in the browser is not allowed due to security issues.
I will continue to find another way to lock a mouse cursor in the following topic: emscripten_request_pointerlock() returns EMSCRIPTEN_RESULT_UNKNOWN_TARGET
-