diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index 4ecd83403..8e35e283e 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -93,8 +93,9 @@ typedef enum SDL_EVENT_DISPLAY_CONNECTED, /**< Display has been added to the system */ SDL_EVENT_DISPLAY_DISCONNECTED, /**< Display has been removed from the system */ SDL_EVENT_DISPLAY_MOVED, /**< Display has changed position */ + SDL_EVENT_DISPLAY_SCALE_CHANGED, /**< Display has changed desktop display scale */ SDL_EVENT_DISPLAY_FIRST = SDL_EVENT_DISPLAY_ORIENTATION, - SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_DISCONNECTED, + SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_SCALE_CHANGED, /* Window events */ /* 0x200 was SDL_WINDOWEVENT, reserve the number for sdl2-compat */ diff --git a/src/events/SDL_displayevents.c b/src/events/SDL_displayevents.c index 10d7bdcce..cf3694466 100644 --- a/src/events/SDL_displayevents.c +++ b/src/events/SDL_displayevents.c @@ -28,7 +28,7 @@ int SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent, { int posted; - if (display == NULL) { + if (display == NULL || display->id == 0) { return 0; } switch (displayevent) { diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index ef5b43f4d..87152d0e6 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -223,6 +223,7 @@ static void SDL_LogEvent(const SDL_Event *event) SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_CONNECTED); SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_DISCONNECTED); SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_MOVED); + SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_SCALE_CHANGED); #undef SDL_DISPLAYEVENT_CASE #define SDL_WINDOWEVENT_CASE(x) \ diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index b85d5ede5..47cc0bbb7 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -1511,6 +1511,17 @@ static void SDLTest_PrintEvent(SDL_Event *event) SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " connected", event->display.displayID); break; + case SDL_EVENT_DISPLAY_SCALE_CHANGED: + { + float display_scale = 1.0f; + const SDL_DisplayMode *mode = SDL_GetDesktopDisplayMode(event->display.displayID); + if (mode) { + display_scale = mode->display_scale; + } + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed scale to %d%%", + event->display.displayID, (int)(display_scale * 100.0f)); + } + break; case SDL_EVENT_DISPLAY_MOVED: SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed position", event->display.displayID); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 0d9aaa322..742b4fc2c 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1077,9 +1077,15 @@ const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID display void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) { + float display_scale = display->desktop_mode.display_scale; + SDL_memcpy(&display->desktop_mode, mode, sizeof(*mode)); display->desktop_mode.displayID = display->id; SDL_FinalizeDisplayMode(&display->desktop_mode); + + if (display_scale != display->desktop_mode.display_scale) { + SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_SCALE_CHANGED, 0); + } } const SDL_DisplayMode *SDL_GetDesktopDisplayMode(SDL_DisplayID displayID) diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c index af0962c3a..0da179e82 100644 --- a/src/video/windows/SDL_windowsmodes.c +++ b/src/video/windows/SDL_windowsmodes.c @@ -324,6 +324,7 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_DisplayData *driverdata = _this->displays[i].driverdata; if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) { SDL_bool moved = (index != i); + SDL_bool changed_bounds = SDL_FALSE; if (moved) { SDL_VideoDisplay tmp; @@ -343,10 +344,14 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_Rect bounds; SDL_ResetFullscreenDisplayModes(existing_display); - if (WIN_GetDisplayBounds(_this, existing_display, &bounds) == 0) { - if (SDL_memcmp(&driverdata->bounds, &bounds, sizeof(bounds)) != 0 || moved) { - SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_MOVED, 0); - } + SDL_SetDesktopDisplayMode(existing_display, &mode); + if (WIN_GetDisplayBounds(_this, existing_display, &bounds) == 0 && + SDL_memcmp(&driverdata->bounds, &bounds, sizeof(bounds)) != 0) { + changed_bounds = SDL_TRUE; + SDL_copyp(&driverdata->bounds, &bounds); + } + if (moved || changed_bounds) { + SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_MOVED, 0); } SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_ORIENTATION, orientation); }