Fixed bug 2260 - SDL_SetCursorGrab() is buggy on Windows
BurnSpamAddress 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. 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.main
parent
fa4e4a643a
commit
d2511d9ef9
|
@ -286,6 +286,45 @@ WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
WIN_UpdateClipCursor(SDL_Window *window)
|
||||||
|
{
|
||||||
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
|
|
||||||
|
/* Don't clip the cursor while we're in the modal resize or move loop */
|
||||||
|
if (data->in_modal_loop) {
|
||||||
|
ClipCursor(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_GetMouse()->relative_mode) {
|
||||||
|
LONG cx, cy;
|
||||||
|
RECT rect;
|
||||||
|
GetWindowRect(data->hwnd, &rect);
|
||||||
|
|
||||||
|
cx = (rect.left + rect.right) / 2;
|
||||||
|
cy = (rect.top + rect.bottom) / 2;
|
||||||
|
|
||||||
|
/* Make an absurdly small clip rect */
|
||||||
|
rect.left = cx-1;
|
||||||
|
rect.right = cx+1;
|
||||||
|
rect.top = cy-1;
|
||||||
|
rect.bottom = cy+1;
|
||||||
|
|
||||||
|
ClipCursor(&rect);
|
||||||
|
} else if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
|
||||||
|
(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
|
||||||
|
RECT rect;
|
||||||
|
if (GetClientRect(data->hwnd, &rect) && !IsRectEmpty(&rect)) {
|
||||||
|
ClientToScreen(data->hwnd, (LPPOINT) & rect);
|
||||||
|
ClientToScreen(data->hwnd, (LPPOINT) & rect + 1);
|
||||||
|
ClipCursor(&rect);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ClipCursor(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -369,22 +408,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2 );
|
WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2 );
|
||||||
data->mouse_button_flags = 0;
|
data->mouse_button_flags = 0;
|
||||||
|
|
||||||
if(SDL_GetMouse()->relative_mode) {
|
WIN_UpdateClipCursor(data->window);
|
||||||
LONG cx, cy;
|
|
||||||
RECT rect;
|
|
||||||
GetWindowRect(hwnd, &rect);
|
|
||||||
|
|
||||||
cx = (rect.left + rect.right) / 2;
|
|
||||||
cy = (rect.top + rect.bottom) / 2;
|
|
||||||
|
|
||||||
/* Make an absurdly small clip rect */
|
|
||||||
rect.left = cx-1;
|
|
||||||
rect.right = cx+1;
|
|
||||||
rect.top = cy-1;
|
|
||||||
rect.bottom = cy+1;
|
|
||||||
|
|
||||||
ClipCursor(&rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: Update keyboard state
|
* FIXME: Update keyboard state
|
||||||
|
@ -585,6 +609,22 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
break;
|
break;
|
||||||
#endif /* WM_INPUTLANGCHANGE */
|
#endif /* WM_INPUTLANGCHANGE */
|
||||||
|
|
||||||
|
case WM_ENTERSIZEMOVE:
|
||||||
|
case WM_ENTERMENULOOP:
|
||||||
|
{
|
||||||
|
data->in_modal_loop = SDL_TRUE;
|
||||||
|
WIN_UpdateClipCursor(data->window);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_EXITSIZEMOVE:
|
||||||
|
case WM_EXITMENULOOP:
|
||||||
|
{
|
||||||
|
data->in_modal_loop = SDL_FALSE;
|
||||||
|
WIN_UpdateClipCursor(data->window);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
#ifdef WM_GETMINMAXINFO
|
#ifdef WM_GETMINMAXINFO
|
||||||
case WM_GETMINMAXINFO:
|
case WM_GETMINMAXINFO:
|
||||||
{
|
{
|
||||||
|
@ -673,20 +713,14 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
RECT rect;
|
RECT rect;
|
||||||
int x, y;
|
int x, y;
|
||||||
int w, h;
|
int w, h;
|
||||||
Uint32 window_flags;
|
|
||||||
|
|
||||||
if (!GetClientRect(hwnd, &rect) ||
|
if (!GetClientRect(hwnd, &rect) || IsRectEmpty(&rect)) {
|
||||||
(rect.right == rect.left && rect.bottom == rect.top)) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ClientToScreen(hwnd, (LPPOINT) & rect);
|
ClientToScreen(hwnd, (LPPOINT) & rect);
|
||||||
ClientToScreen(hwnd, (LPPOINT) & rect + 1);
|
ClientToScreen(hwnd, (LPPOINT) & rect + 1);
|
||||||
|
|
||||||
window_flags = SDL_GetWindowFlags(data->window);
|
WIN_UpdateClipCursor(data->window);
|
||||||
if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
|
|
||||||
(window_flags & SDL_WINDOW_INPUT_FOCUS)) {
|
|
||||||
ClipCursor(&rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
x = rect.left;
|
x = rect.left;
|
||||||
y = rect.top;
|
y = rect.top;
|
||||||
|
|
|
@ -207,7 +207,7 @@ WIN_SetRelativeMouseMode(SDL_bool enabled)
|
||||||
|
|
||||||
|
|
||||||
/* (Un)register raw input for mice */
|
/* (Un)register raw input for mice */
|
||||||
if(RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) {
|
if (RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) {
|
||||||
|
|
||||||
/* Only return an error when registering. If we unregister and fail, then
|
/* Only return an error when registering. If we unregister and fail, then
|
||||||
it's probably that we unregistered twice. That's OK. */
|
it's probably that we unregistered twice. That's OK. */
|
||||||
|
@ -216,7 +216,7 @@ WIN_SetRelativeMouseMode(SDL_bool enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enabled) {
|
if (enabled) {
|
||||||
LONG cx, cy;
|
LONG cx, cy;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetWindowRect(hWnd, &rect);
|
GetWindowRect(hWnd, &rect);
|
||||||
|
@ -231,10 +231,9 @@ WIN_SetRelativeMouseMode(SDL_bool enabled)
|
||||||
rect.bottom = cy+1;
|
rect.bottom = cy+1;
|
||||||
|
|
||||||
ClipCursor(&rect);
|
ClipCursor(&rect);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
ClipCursor(NULL);
|
ClipCursor(NULL);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue