Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to Capture Mouse Cursor in QWindow for First-Person Camera Control (Raw Mouse Input / Relative Mouse Mode)?
Forum Updated to NodeBB v4.3 + New Features

How to Capture Mouse Cursor in QWindow for First-Person Camera Control (Raw Mouse Input / Relative Mouse Mode)?

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 64 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • EndrII 0E Offline
    EndrII 0E Offline
    EndrII 0
    wrote last edited by
    #1

    Hi everyone,

    I'm developing a graphics application (a game) with a first-person perspective using Qt (QWindow ) and I'm facing a challenge with mouse-based camera control.

    My Goal:
    I need the mouse cursor to remain "captured" within my QWindow, and for me to receive only relative changes in mouse position (deltas), not absolute cursor coordinates. This is crucial for smooth and continuous camera rotation, regardless of the physical screen boundaries or the cursor moving outside the QWindow. Additionally, the system cursor should be hidden, as I plan to draw my own custom cursor or not display one at all.

    The Problem:
    Standard QMouseEvents (for example, from QWindow::mouseMoveEvent) stop being sent when the mouse cursor reaches the edge of the screen or moves outside my QWindow. This results in the camera "hitting a wall" and interrupting rotation.

    What I've Explored/Tried:

    I understand that this functionality (often referred to as "raw mouse input" or "relative mouse mode") is possible on all major platforms (Windows, Linux, macOS) and is commonly used in games.

    I've looked into the QSinglePointEvent::exclusivePointGrabber property, but:

    I can't find a working example of how to use it.
    Based on its description, it seems to be more about "grabbing" pointer events (to ensure they're delivered only to one QWindow), rather than "locking" the cursor in the center of the window and providing relative deltas. My primary need is for the cursor not to escape and hit the screen edge.

    My Question:
    Is there a built-in, cross-platform way in Qt to achieve this "relative mouse mode" (mouse grabbing / relative mouse mode) for a QWindow, such that:

    The mouse cursor remains contained within the QWindow?

    I receive only xrel and yrel (delta) mouse movements?

    The system cursor is hidden?

    I'm looking for something that works like SDL_SetRelativeMouseMode in SDL

    Any help and code examples would be greatly appreciated!
    Thank you.

    1 Reply Last reply
    0
    • GrecKoG Offline
      GrecKoG Offline
      GrecKo
      Qt Champions 2018
      wrote last edited by
      #2

      I've done this with only Qt APIs by calling QCursor::setPos everytime I get a new cursor position. The delta is the diff between the new position and the forced pos.

      A blank cursor can be set with QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));

      EndrII 0E 1 Reply Last reply
      1
      • GrecKoG GrecKo

        I've done this with only Qt APIs by calling QCursor::setPos everytime I get a new cursor position. The delta is the diff between the new position and the forced pos.

        A blank cursor can be set with QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));

        EndrII 0E Offline
        EndrII 0E Offline
        EndrII 0
        wrote last edited by
        #3

        @GrecKo "Oh, I did that, but it's a bad solution and mostly a crutch, as I know that all display servers on all platforms offer mouse capture functionality at the windowing system level, and that's exactly what should be used.

        The problem with setPos is that it's an attempt to modify a system component – a direct security violation – and new window managers like Wayland directly forbid such a function. I've written about this here and here, but I haven't found a relatively simple solution to this problem. Currently, I'm using the outdated xWayland for Wayland to redirect setPos through the X11 API where such functionality is allowed.

        However, using xWayland for games means huge FPS losses for no good reason, which is especially noticeable with Vulkan, and that's extremely frustrating.

        I need a way to directly subscribe to the cursor capture functionality, so that for a specific window, the display server starts sending deltas instead of absolute coordinates. These deltas should always be received, regardless of where the cursor physically lands."

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved