Skip to content

Calling SDL_WarpMouseInWindow immediatelly after turning off relative mode produces unexpected results #4339

@Susko3

Description

@Susko3

If the mouse is moving, and you disable relative mode and then warp the cursor, sometimes the cursor will not warp.

Code used to reproduce the issue:

#include <SDL.h>
#include <SDL_hints.h>

int main(int argc, char** args)
{
    SDL_Init(SDL_INIT_EVENTS);
    SDL_Window* win = SDL_CreateWindow("test window", 100, 100, 1200, 500, SDL_WINDOW_RESIZABLE);
    SDL_SetHint(SDL_HINT_EVENT_LOGGING, "2");

    bool loop = true;
    bool relative = false;
    SDL_SetRelativeMouseMode(SDL_bool::SDL_FALSE);

    while (loop)
    {
        SDL_Event e;
        while (SDL_PollEvent(&e) > 0)
        {
            if (e.type == SDL_EventType::SDL_KEYDOWN)
            {
                SDL_Keysym key = e.key.keysym;
                if (key.sym == SDLK_b)
                {
                    relative = !relative;
                    SDL_SetRelativeMouseMode(relative ? SDL_bool::SDL_TRUE : SDL_bool::SDL_FALSE);
                    if (!relative)
                    {
                        SDL_WarpMouseInWindow(win, 1000, 250);
                        SDL_Log("warp");
                    }
                    else
                        SDL_Log("toggle");
                }

                if (key.sym == SDLK_ESCAPE)
                    loop = false;
            }
        }
    }
    return 0;
}
video.mp4

How to reproduce:

  1. Press B once to enable relative mode (the OS cursor will dissapear)
  2. Start moving your mouse (I do it in a circle on the left side of the window, so it's easier to track)
  3. Press B to disable relative mode and warp the cursor
  4. The cursor will appear on the screen, but the location of the cursor is not predictable

The cursor is expected to be at the location that SDL_WarpMouseInWindow specified (on the right side of the window, with my example code). Sometimes the cursor will appear here as expected.
But if the bug occurs, the cursor will not warp, and will appear on the location of the last SDL_MOUSEMOTION event (on the left side in the video).

If you don't move your mouse, the cursor will always appear in the location specified by SDL_WarpMouseInWindow.

There is a slight difference between the latest main and 2.0.14: On 2.0.14 it's the same as main, but the cursor can also appear in the middle of the window.

Seems to happen much more frequently when mouse report rate is set to 1000 Hz. But I managed to reproduce it with 125 Hz, as seen in the logs below:

Normal logs:

INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=8916 windowid=1 which=0 state=0 x=83 y=116 xrel=29 yrel=-10)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=8923 windowid=1 which=0 state=0 x=122 y=104 xrel=39 yrel=-12)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=8932 windowid=1 which=0 state=0 x=167 y=94 xrel=45 yrel=-10)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=8936 windowid=1 state=pressed repeat=false scancode=5 keycode=98 mod=0)
INFO: SDL EVENT: SDL_TEXTINPUT (timestamp=8936 windowid=1 text='b')
INFO: warp
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=8939 windowid=1 which=0 state=0 x=1035 y=243 xrel=868 yrel=149)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=8947 windowid=1 which=0 state=0 x=1050 y=242 xrel=15 yrel=-1)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=8955 windowid=1 which=0 state=0 x=1048 y=242 xrel=-2 yrel=0)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=8963 windowid=1 which=0 state=0 x=1034 y=248 xrel=-14 yrel=6)

Logs when the cursor doesn't warp:

INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=10211 windowid=1 which=0 state=0 x=182 y=259 xrel=-3 yrel=2)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=10219 windowid=1 which=0 state=0 x=187 y=258 xrel=5 yrel=-1)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=10227 windowid=1 which=0 state=0 x=201 y=253 xrel=14 yrel=-5)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=10235 windowid=1 state=pressed repeat=false scancode=5 keycode=98 mod=0)
INFO: SDL EVENT: SDL_TEXTINPUT (timestamp=10235 windowid=1 text='b')
INFO: warp
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=10236 windowid=1 which=0 state=0 x=224 y=246 xrel=23 yrel=-7)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=10243 windowid=1 which=0 state=0 x=248 y=242 xrel=24 yrel=-4)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=10252 windowid=1 which=0 state=0 x=265 y=239 xrel=17 yrel=-3)
INFO: SDL EVENT: SDL_MOUSEMOTION (timestamp=10259 windowid=1 which=0 state=0 x=267 y=239 xrel=2 yrel=0)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions