Commit 4077f7a2d9111094129f82f28b7a71afb1878170

David Gow 2021-08-03T20:55:45

Update the Renderer dpi_scale on SIZE_CHANGED event (fix #4580) The Renderer logical scaling code scales mouse coordinates, and needs to take the window DPI into account on HIGHDPI windows. However, the variable which tracks this, renderer->dpi_scale, is set once when the renderer is created, and then not updated. In the event that the window is moved to another screen, or the screen DPI otherwise changes, this will be outdates, and potentially the coordinates will be all wrong. So let's update the dpi_scale on the SIZE_CHANGED event: it's at least a possibility that this will be issued on some OSes when DPI changes, and it's otherwise already handled by SDL_Renderer's event filter.

diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index d111e77..75adfab 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -619,6 +619,17 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
                     SDL_SetRenderTarget(renderer, NULL);
                 }
 
+                /* Update the DPI scale if the window has been resized. */
+                if (window && renderer->GetOutputSize) {
+                    int window_w, window_h;
+                    int output_w, output_h;
+                    if (renderer->GetOutputSize(renderer, &output_w, &output_h) == 0) {
+                        SDL_GetWindowSize(renderer->window, &window_w, &window_h);
+                        renderer->dpi_scale.x = (float)window_w / output_w;
+                        renderer->dpi_scale.y = (float)window_h / output_h;
+                    }
+                }
+
                 if (renderer->logical_w) {
                     UpdateLogicalSize(renderer);
                 } else {