Open
Description
Ref: Factorio bug report
On Windows, if you change the resolution of a secondary display while an SDL app is running, the coordinates returned by SDL_GetMouseState
become offset from the actual cursor position.
SDL-given cursor position is represented by the white square:
Reproduction
- Connect two displays to a Windows machine
- Change the resolution of the secondary display (display that the SDL app is not running on)
- Observe discrepancy
Sample code:
#include <SDL3/SDL.h>
#include <stdlib.h>
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_main.h>
static SDL_Window* window = NULL;
static SDL_Renderer* renderer = NULL;
static const SDL_FRect rect = { .x = 100, .y = 100, .w = 100, .h = 100 };
SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) {
SDL_SetHint(SDL_HINT_EVENT_LOGGING, "1");
SDL_CreateWindowAndRenderer("SDL test", 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY, &window, &renderer);
SDL_SetRenderVSync(renderer, 1);
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
if (event->type == SDL_EVENT_QUIT)
return SDL_APP_SUCCESS;
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppIterate(void* appstate) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
float mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
const bool mouseInRect = SDL_PointInRectFloat(&(SDL_FPoint){ .x = mouseX, .y = mouseY }, &rect);
SDL_SetRenderDrawColor(renderer, mouseInRect ? 0 : 255, mouseInRect ? 150 : 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderFillRect(renderer, &(SDL_FRect){.x = mouseX - 5, .y = mouseY - 5, .w = 10, .h = 10});
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE;
}
void SDL_AppQuit(void* appstate, SDL_AppResult result) {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}