diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index a099fa631..00ef203c0 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -477,11 +477,6 @@ ShouldGenerateWindowCloseOnAltF4(void) return !SDL_GetHintBoolean(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, SDL_FALSE); } -/* Win10 "Fall Creators Update" introduced the bug that SetCursorPos() (as used by SDL_WarpMouseInWindow()) - doesn't reliably generate WM_MOUSEMOVE events anymore (see #3931) which breaks relative mouse mode via warping. - This is used to implement a workaround.. */ -static SDL_bool isWin10FCUorNewer = SDL_FALSE; - /* We want to generate mouse events from mouse and pen, and touch events from touchscreens */ #define MI_WP_SIGNATURE 0xFF515700 #define MI_WP_SIGNATURE_MASK 0xFFFFFF00 @@ -581,7 +576,7 @@ WarpWithinBoundsRect(int x, int y, RECT *bounds) } else { warpY = SDL_clamp(y, targetTop, targetBottom); } - SetCursorPos(warpX, warpY); + WIN_SetCursorPos(warpX, warpY); } } } @@ -752,18 +747,6 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH && lParam != data->last_pointer_update) { SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - if (isWin10FCUorNewer && mouse->relative_mode_warp && - (data->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0) { - /* To work around #3931, Win10 bug introduced in Fall Creators Update, where - SetCursorPos() (SDL_WarpMouseInWindow()) doesn't reliably generate mouse events anymore, - after each windows mouse event generate a fake event for the middle of the window - if relative_mode_warp is used */ - int center_x = 0, center_y = 0; - SDL_GetWindowSize(data->window, ¢er_x, ¢er_y); - center_x /= 2; - center_y /= 2; - SDL_SendMouseMotion(data->window, 0, 0, center_x, center_y); - } } } } @@ -1703,8 +1686,6 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst) return SDL_SetError("Couldn't register application class"); } - isWin10FCUorNewer = IsWin10FCUorNewer(); - app_registered = 1; return 0; } diff --git a/src/video/windows/SDL_windowsmouse.c b/src/video/windows/SDL_windowsmouse.c index dd34bdcf7..a43ea45b7 100644 --- a/src/video/windows/SDL_windowsmouse.c +++ b/src/video/windows/SDL_windowsmouse.c @@ -236,6 +236,21 @@ WIN_ShowCursor(SDL_Cursor * cursor) return 0; } +void +WIN_SetCursorPos(int x, int y) +{ + /* We need to jitter the value because otherwise Windows will occasionally inexplicably ignore the SetCursorPos() or SendInput() */ + SetCursorPos(x, y); + SetCursorPos(x+1, y); + SetCursorPos(x, y); + + /* Flush any mouse motion prior to or associated with this warp */ + SDL_last_warp_time = GetTickCount(); + if (!SDL_last_warp_time) { + SDL_last_warp_time = 1; + } +} + static void WIN_WarpMouse(SDL_Window * window, int x, int y) { @@ -251,13 +266,9 @@ WIN_WarpMouse(SDL_Window * window, int x, int y) pt.x = x; pt.y = y; ClientToScreen(hwnd, &pt); - SetCursorPos(pt.x, pt.y); + WIN_SetCursorPos(pt.x, pt.y); - /* Flush any pending mouse motion and simulate motion for this warp */ - SDL_last_warp_time = GetTickCount(); - if (!SDL_last_warp_time) { - SDL_last_warp_time = 1; - } + /* Send the exact mouse motion associated with this warp */ SDL_SendMouseMotion(window, SDL_GetMouse()->mouseID, 0, x, y); } diff --git a/src/video/windows/SDL_windowsmouse.h b/src/video/windows/SDL_windowsmouse.h index 68279a685..0dcc53033 100644 --- a/src/video/windows/SDL_windowsmouse.h +++ b/src/video/windows/SDL_windowsmouse.h @@ -28,6 +28,7 @@ extern HCURSOR SDL_cursor; extern void WIN_InitMouse(_THIS); extern void WIN_QuitMouse(_THIS); +extern void WIN_SetCursorPos(int x, int y); #endif /* SDL_windowsmouse_h_ */