| Summary: | SDL_SetCursorGrab() is buggy on Windows | ||
|---|---|---|---|
| Product: | SDL | Reporter: | BurnSpamAddress |
| Component: | video | Assignee: | 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 | ||
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.
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. This should be fixed in 2.0.3, please let me know if you are still having issues with this. Cheers! |
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; }