F08 — DPI / runtime rescale
Logical vs physical coordinates, and what happens when the scale changes under a live window. The four platforms give four different answers — including X11's "no runtime answer at all", which is a deliverable here, not a gap.
Requirements
- Continuously display (render into the frame) and log: logical size, physical (pixel) size, and the current scale factor; crisp 1-physical-px hairlines at the window edge make scaling artifacts visible.
- Handle a runtime scale change and log the full event sequence:
- Wayland: implement BOTH paths and switch on advertised globals:
wp_fractional_scale_v1(preferred-scale in 1/120ths) +wp_viewportfor buffer-size decoupling, AND the integerwl_surface.set_buffer_scalefallback driven bywl_surface.preferred_buffer_scale/wl_output.scale. Log which path is active. - Win32: Per-Monitor-v2 awareness (manifest or
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)); onWM_DPICHANGED, honor the suggested rect (lParam) and log old/new DPI + rect. - macOS: observe
backingScaleFactorviaviewDidChangeBackingProperties/NSWindowDidChangeBackingPropertiesNotification; logconvertRectToBacking:round-trips. - X11: demonstrate that there is no runtime mechanism: read
Xft.dpifrom resources andRANDRphysical dimensions at startup, change the system scale, show the running window receives nothing. That finding IS the deliverable.
- Wayland: implement BOTH paths and switch on advertised globals:
- Survive a monitor-to-monitor drag between different scales without blurriness or wrong-size buffers (Tier C where it needs real monitors; headless weston can be configured with two outputs at different scales — do that for Wayland).
Instrumentation
scale_changed scale=… path=…, dpi_changed old=… new=… suggested=WxH, plus resize size=WxH scale=S everywhere sizes change.
Findings to record
- The native coordinate unit per platform and where the scale is first learnable (the "created at wrong scale then rescaled" problem — log whether it happens).
- The full event order for a scale change (feeds
event-sequences.md). - Fractional-scale buffer-size math on Wayland (rounding rules) and what
viewportdecouples. - The X11 absence, documented with the startup-snapshot workaround frameworks use.
Verification
Wayland: Tier A (headless weston with two outputs, scales 1 and 1.5/2). X11: Tier A (the absence-proof). Win32: A[wine] for the WM_DPICHANGED plumbing (Wine emulates per-monitor DPI imperfectly — label it), real mixed-DPI drag Tier C. macOS: scale observation A[ssh], monitor drag Tier C.