Experiment: explicit user-controlled pixel scale (no HiDPI automagic) - #579
Draft
pusewicz wants to merge 7 commits into
Draft
Experiment: explicit user-controlled pixel scale (no HiDPI automagic)#579pusewicz wants to merge 7 commits into
pusewicz wants to merge 7 commits into
Conversation
bullno1
reviewed
Aug 17, 2026
pusewicz
force-pushed
the
hidpi-explicit-scale
branch
from
August 17, 2026 21:59
b90e4ae to
d62ec37
Compare
This was referenced Aug 17, 2026
pusewicz
added a commit
to pusewicz/cute_framework
that referenced
this pull request
Aug 17, 2026
cf_app_get_dpi_scale / cf_app_dpi_scale_was_changed read like the OS's vague "suggested UI content scale" concept. The value is actually SDL_GetWindowDisplayScale -- the OS's points-to-pixels conversion for the window's display -- so name it that. Hard rename, no compat alias. Also drops CF_App::dpi_scale_prev, which was written once at init and never read. First slice of the RandyGaul#579 split.
…ion) Experiment, not a proposal: remove all event-driven HiDPI automagic in favor of user-controlled state, to see what the model looks like. - cf_app_set_pixel_scale: pixel scale is now a plain user value (AA + glyph density); the canvas is resized explicitly via set_canvas_size. - cf_app_pixel_scale_was_changed + cf_app_get_natural_pixel_scale; a density change only raises dpi_scale_was_changed, never applies. - Startup is the single automatic step: canvas at natural density, default 2d projection from the logical window size -- both set once. - cf_draw_projection is now truly sticky: window resizes, canvas recreation, and MSAA changes never touch the projection. - hidpi sample carries the copy-paste resize/density recipe and forced 1x/2x/4x switching; test_hidpi reworked for the new contracts. 350/350 tests pass on a 2x display (master baseline: 319/339 -- the 20 Retina failures were the half-size regression, which dies structurally here since nothing ever rebuilds the projection in pixel units). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LHq3Cx7xcjAQhji9m1ADJn
bullno1's follow-up suggestion on the PR RandyGaul#575 thread: package the recurring three-step reaction (set pixel scale, resize canvas to window * scale, rebuild the logical-points projection) into a single public helper. The window size is read internally rather than passed in -- it is always current by the time user code reacts to an event, and passing it would only invite stale values. The sample, the shared test-app sweep, and the hidpi tests all shrink to one call each, which was the tell that the helper deserved to be public API. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LHq3Cx7xcjAQhji9m1ADJn
pusewicz
force-pushed
the
hidpi-explicit-scale
branch
from
August 21, 2026 13:35
d62ec37 to
1654603
Compare
Terminology follows the SDL functions underneath, per the PR thread: - cf_app_get_display_scale / cf_app_display_scale_was_changed (backed by SDL_GetWindowDisplayScale): what the OS wants, point-to-pixel, consistent across platforms. Replaces both the dpi_scale pair (term dropped) and cf_app_get_natural_pixel_scale (SDL_GetWindowPixelDensity is 1.0 on Windows/X11 where the scale lives in content-scale, so display scale is the right value to follow everywhere). - cf_app_update_display(scale): renamed from cf_app_apply_pixel_scale. - pixel_scale keeps its name: how fonts/shapes are scaled, arbitrary or following the reported display scale. - Initial pixel_scale now comes from display scale (identical on Mac, correct on Windows where density alone under-reports). Window size and mouse coordinates are now normalized to logical points at the SDL boundary via SDL_GetDisplayContentScale (window create, set_size, resize events, mouse events; touch already derives from app->w/h). A no-op on macOS where content scale is 1.0 -- the normalization needs verification on Windows and X11 at >100% scaling. 351/351 tests, docsparser clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LHq3Cx7xcjAQhji9m1ADJn
cf_destroy_draw freed s_draw but never nulled it (the make-error path did), so cf_app_set_pixel_scale on a NO_GFX app created after a gfx app's destruction passed the hook's s_draw guard with a dangling pointer -- an instant access violation on Windows, silently-readable freed memory on POSIX. The synthetic WINDOW_RESIZED event in test_hidpi pushed 500 raw, but SDL resize events carry raw window coordinates which CF now divides by the display content scale -- not 1.0 on the X11 CI runners. Push points * content_scale like a real event, and compare against the handler's exact round-trip. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LHq3Cx7xcjAQhji9m1ADJn
…ic event On X11 the ConfigureNotify confirming test_make_app's SDL_SetWindowSize can arrive late and land in the same pump as the synthetic resize event, stomping app->w after it. Drain it first -- the same settling dance the one-shot test used on the previous branch, lost in the rewrite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LHq3Cx7xcjAQhji9m1ADJn
Shows raw screen coords next to cf_screen_to_world's translation, so the HiDPI mouse mapping can be eyeballed against known shape positions at any forced pixel scale. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The pixel scale only ever changes when user code calls cf_app_set_pixel_scale, so this flag just echoed the caller's own action back one frame later -- no OS event ever set it. The real event remains cf_app_display_scale_was_changed, and anyone wanting change detection can compare cf_app_get_pixel_scale against a cached value. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S4anUDPNkAio27kQbWAqrn
pusewicz
force-pushed
the
hidpi-explicit-scale
branch
from
August 21, 2026 13:38
bf973ba to
49a6b0c
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.
Working demo of @bullno1's proposal from the #575 review thread (including the follow-up naming refinements): remove all event-driven HiDPI behavior and make pixel scale a plain user-controlled value. Draft on purpose — it exists to give that design discussion something concrete to poke at.
window_size * display_scale, default 2d projection from the logical window size, both set once. Resizes and scale changes only raise flags (cf_app_was_resized/cf_app_display_scale_was_changed).cf_app_get_display_scale(+_was_changed) isSDL_GetWindowDisplayScale— what the OS wants, consistent across platforms; thedpinames are gone.cf_app_set_pixel_scaleis how fonts/shapes scale — arbitrary, or following the reported display scale; it does not touch the canvas (cf_app_set_canvas_sizeis separate).cf_app_update_display(scale)is the all-in-one helper bringing canvas, projection, and pixel scale together, usable on both resize and scale change — the w/h params are omitted since the window size is always current by the time user code reacts.SDL_GetDisplayContentScale(window creation,cf_app_set_size, resize events, mouse events; touch derives from window size). This is a no-op on macOS (content scale 1.0) and needs verification on Windows/X11 at >100% scaling — I can only test on a Mac.cf_draw_projectionbecomes truly sticky andcf_app_set_canvas_sizepersistent. The half-size regression Fix HiDPI half-size regression: default 2d projection is logical points #575 fixes dies structurally — no code path can rebuild the projection in pixel units — and all of Fix HiDPI half-size regression: default 2d projection is logical points #575's deferral/guard machinery becomes unnecessary. 351/351 tests on a 2x display (master: 319/339, the 20 failures being that regression).Cost, stated plainly: breaking change. 44 of 76 samples use resizable windows and each needs the two-line recipe (deliberately not yet updated); canvas_modes.c needs a rewrite.
NO_HIGH_DPI_BITis kept: it is the only handle on the creation-time 1x swapchain (memory + final-blit bandwidth), whichcf_app_update_display(1)cannot replicate.🤖 Generated with Claude Code
https://claude.ai/code/session_01LHq3Cx7xcjAQhji9m1ADJn