We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2260

Summary: SDL_SetCursorGrab() is buggy on Windows
Product: SDL Reporter: BurnSpamAddress
Component: videoAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: tomrijnbeek
Version: 2.0.1   
Hardware: x86   
OS: Windows 7   

Description BurnSpamAddress 2013-11-22 12:24:32 UTC
Steps to reproduce:
1. Grab the cursor with SDL_SetCursorGrab()
2. Alt-tab away from the window
3. Click on the titlebar of the window

This will cause the window to disappear underneath the taskbar!

This appears to be a general issue with ClipCursor() on windows, i.e. I am getting the same behavior if I call ClipCursor() directly. Can anyone think of a good workaround?

The following code reproduces the issue on Windows 7 SP1 and Windows 8.1.

#include "SDL.h"
#include "SDL_main.h"

int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);

    auto wnd = SDL_CreateWindow(
        "Test",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        800,
        600,
        0);

    SDL_SetWindowGrab(wnd, SDL_TRUE);

    bool running = true;
    while (running)
    {
        SDL_Event e;
        if (SDL_PollEvent(&e))
        {
            switch (e.type)
            {
            case SDL_KEYDOWN:
            case SDL_WINDOWEVENT_CLOSE:
            case SDL_QUIT:
                running = false;
                break;
            }
        }
    }

    SDL_Quit();

    return 0;
}
Comment 1 BurnSpamAddress 2013-11-22 13:30:34 UTC
Additional investigation indicates that this issue is not specific to SDL, but can be reproduced on native applications under the correct circumstances.

It is caused by a feedback loop between the ClipCursor function and the modal resize/move event loop that handles mouse-based sizing on Windows. The solution lies in SDL_windowsevents.c (WIN_WindowProc)

switch (msg)
{
case WM_ENTERSIZEMOVE:
case WM_ENTERMENULOOP:
    is_in_modal_loop = 1;
    if (cursor_grabbed) {
        ClipCursor(NULL);
    }
    break;

case WM_EXITSIZEMOVE:
case WM_EXITMENULOOP:
    is_in_modal_loop = 0;
    if (cursor_grabbed) {
        ClipCursor(&rect);
    }
    break;

case WM_WINDOWPOSCHANGED:
    if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
        (window_flags & SDL_WINDOW_INPUT_FOCUS) &&
        !is_in_modal_loop) {
        ClipCursor(&rect);
    }
}

Apologies for not creating a proper patch, but I do not have access to hg at work.
Comment 2 Tom Rijnbeek 2014-03-22 21:06:18 UTC
I am running OpenTK on top of the SDL2 Win32 backend (Windows 8) and I am running into the same issue. As I don't really have access to the SDL2 source, manually patching is not really an option. I made a video showing what exactly happens for our game that can be found at http://youtu.be/uvFzta6COYw
It would be much appreciated if this could be fixed.
Comment 3 Sam Lantinga 2014-03-23 16:49:50 UTC
This should be fixed in 2.0.3, please let me know if you are still having issues with this.

Cheers!