diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index eaf8b7566a..b8cecc7fd5 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -329,7 +329,7 @@ static void WIN_CheckAsyncMouseRelease(Uint64 timestamp, SDL_WindowData *data) data->mouse_button_flags = (WPARAM)-1; } -static void WIN_UpdateFocus(SDL_Window *window, bool expect_focus, DWORD pos) +static void WIN_UpdateFocus(SDL_Window *window, bool expect_focus, LPPOINT pos) { SDL_WindowData *data = window->internal; HWND hwnd = data->hwnd; @@ -366,8 +366,8 @@ static void WIN_UpdateFocus(SDL_Window *window, bool expect_focus, DWORD pos) // In relative mode we are guaranteed to have mouse focus if we have keyboard focus if (!SDL_GetMouse()->relative_mode) { - cursorPos.x = (LONG)GET_X_LPARAM(pos); - cursorPos.y = (LONG)GET_Y_LPARAM(pos); + cursorPos.x = pos->x; + cursorPos.y = pos->y; ScreenToClient(hwnd, &cursorPos); SDL_SendMouseMotion(WIN_GetEventTimestamp(), window, SDL_GLOBAL_MOUSE_ID, false, (float)cursorPos.x, (float)cursorPos.y); } @@ -1221,8 +1221,13 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara /* Update the focus here, since it's possible to get WM_ACTIVATE and WM_SETFOCUS without actually being the foreground window, but this appears to get called in all cases where - the global foreground window changes to and from this window. */ - WIN_UpdateFocus(data->window, !!wParam, GetMessagePos()); + the global foreground window changes to and from this window. + + The current cursor position is needed here, as the message position contains old + coordinates if the pointer moved while an overlay was active. */ + POINT pos = { 0, 0 }; + GetCursorPos(&pos); + WIN_UpdateFocus(data->window, !!wParam, &pos); /* Handle borderless windows; this event is intended for drawing the titlebar, so we need to stop that from happening. */ @@ -1246,7 +1251,9 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara case WM_ACTIVATE: { // Update the focus in case we changed focus to a child window and then away from the application - WIN_UpdateFocus(data->window, !!LOWORD(wParam), GetMessagePos()); + const DWORD msgPos = GetMessagePos(); + POINT pos = { GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos) }; + WIN_UpdateFocus(data->window, !!LOWORD(wParam), &pos); } break; case WM_MOUSEACTIVATE: @@ -1269,14 +1276,18 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara case WM_SETFOCUS: { // Update the focus in case it's changing between top-level windows in the same application - WIN_UpdateFocus(data->window, true, GetMessagePos()); + const DWORD msgPos = GetMessagePos(); + POINT pos = { GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos) }; + WIN_UpdateFocus(data->window, true, &pos); } break; case WM_KILLFOCUS: case WM_ENTERIDLE: { // Update the focus in case it's changing between top-level windows in the same application - WIN_UpdateFocus(data->window, false, GetMessagePos()); + const DWORD msgPos = GetMessagePos(); + POINT pos = { GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos) }; + WIN_UpdateFocus(data->window, false, &pos); } break; case WM_POINTERENTER: