macos: refresh dpi_scale per Metal frame; guard backingScaleFactor=0#648
Merged
Conversation
e70097d to
dc7eed1
Compare
NSWindow.backingScaleFactor returns 0.0 when the window isn't attached to a screen yet — which is exactly the state during the startup update_dimensions() call (before makeKeyAndOrderFront). Without this guard the Metal backend silently records dpi_scale = 0, which then gets divided by downstream (e.g. macroquad's screen_width()) and either hangs at NaN or pins the UI at 0×0. Two fixes here: - update_dimensions() now skips the dpi_scale assignment when backingScaleFactor is 0, leaving the previous (correct) value in place until a later call catches a valid scale. - Metal's draw_rect (the per-frame entry point) now calls update_dimensions(), matching the OpenGL path. Otherwise the initial dpi_scale never gets refreshed and Retina apps render at point resolution.
dc7eed1 to
245dc58
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related fixes for macOS Metal high-DPI behaviour:
Guard
backingScaleFactor = 0.NSWindow.backingScaleFactorreturns0.0when the window isn't yet attached to a screen — exactly the state during the startupupdate_dimensions()call (beforemakeKeyAndOrderFront). Upstream then storesdpi_scale = 0, and any downstream divide bydpi_scale(e.g. macroquad'sscreen_width()) either NaN's or pins the UI to 0×0. Now we skip the assignment when the value is non-positive, leaving the prior (correct) value in place until a later call catches a real scale.Refresh
dpi_scaleper Metal frame. OpenGL'sdraw_rectcallsupdate_dimensions()every frame; the Metaldraw_rectdidn't, so even after the guarded startup case the initialdpi_scalewas never refreshed. Retina apps using the Metal backend rendered at point resolution. This change adds the matching call to Metal'sdraw_rect.Test plan
backingScaleFactor = 2): macOS Metal app now reportsdpi_scale = 2.0consistently from frame 1.dpi_scalefollows when the window is dragged between Retina and non-Retina displays.