linux: render at the fractional output scale instead of the integer scale factor - #359
linux: render at the fractional output scale instead of the integer scale factor#359Reliacrt wants to merge 1 commit into
Conversation
|
@Reliacrt is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
725b534 to
d5a56ca
Compare
|
Fixed both review findings in d5a56ca:
Verified: rebuilt the example against the patched SDK (ReleaseFast) — compiles clean and renders ( |
d5a56ca to
cad2d3b
Compare
|
Addressed the remaining GTK 4.10 build concern in cad2d3b: the three emit-path call sites (window frame, resize, and the window-state scale) now route through a new |
…cale factor The GTK host derives the canvas render scale from gtk_widget_get_scale_factor, which rounds to the integer wl_output scale. On a 150%-scaled Wayland output the compositor reports scale 2 (integer protocol) but its real scale is 1.5 (fractional-scale protocol): the canvas renders at 2x and the compositor resamples the buffer down to 1.5x, so every curve — glyph arcs, rounded corners, chart lines — comes out softened and jagged. Use gdk_surface_get_scale (GDK >= 4.12), which returns the exact fractional scale, for the render resolution, the resize/frame event payloads, and the draw-time device-scale comparison (keeps the buffer at 1:1 with the widget so the NEAREST fast path still holds). Also connect notify::scale on the surface so fractional scale changes re-sync geometry when a window moves between outputs. Verified on niri (output scale 1.5, 2560x1600): gpu_scale goes from 2 to 1.5, the present path reports buf/logical/widget_scale all at 1.5 with NEAREST, and curves render smoothly.
cad2d3b to
eb34da0
Compare
Summary
The Linux GTK host derives the canvas render scale from
gtk_widget_get_scale_factor, which rounds to the integerwl_outputscale. On a fractionally-scaled Wayland output the compositor's real scale differs from that integer:scale 1.5(and KWin fractional scaling) reportwl_output::scale = 2(the protocol only carries integers) but deliver the true1.5viawp_fractional_scale_manager_v1.That buffer/compositor mismatch softens and jags every curve — glyph arcs, rounded button corners, chart lines — regardless of the renderer's own AA quality.
Fix
Use GDK's fractional-scale API (
gdk_surface_get_scale, GDK >= 4.12) wherever the host previously read the integergtk_widget_get_scale_factor/gdk_surface_get_scale_factor:native_sdk_gtk_fractional_scale()helper (falls back to the integer factor on pre-4.12 GTK)notify::scaleconnection on the surface so fractional scale changes (window moved to an output with a different 150%-style scale) re-sync geometryVerification
Environment: Linux + niri, output scale 1.5, 2560x1600.
buf=480x780 logical=320x520 widget_scale=1.5 dev_scale=1.5 filter=NEAREST(previously640x1040/2.0/ resampled).gpu_scale=1.5after the fix (was2).zig build validatepasses;zig build testpasses in the local gate run (a known flaky--listen-runner failure on this machine also reproduces standalone-clean and does not compilegtk_host.c;desktop-platform-tests, which does, passes standalone with this change).Notes
examples/calculatorwindow-height issue seen alongside this (hardcodedwindow_height = 490insrc/main.zigclips the last keypad row under a Linux titlebar) is a separate example bug; happy to file it separately if wanted.