fix: render Ghostty surface at GLArea FBO size on fractional scales#83
Open
manuacl wants to merge 1 commit into
Open
fix: render Ghostty surface at GLArea FBO size on fractional scales#83manuacl wants to merge 1 commit into
manuacl wants to merge 1 commit into
Conversation
manuacl
added a commit
to manuacl/limux
that referenced
this pull request
May 24, 2026
manuacl
added a commit
to manuacl/limux
that referenced
this pull request
May 25, 2026
d85bf4a to
73e6cd6
Compare
GTK4 allocates the GLArea backing FBO at `logical_size * scale_factor()` physical pixels. On Wayland fractional-scale outputs (1.25, 1.5, ...), the compositor downscales that integer-scaled buffer to the fractional surface size via wp-fractional-scale-v1. `refresh_surface_display` was passing the logical CSS allocation as Ghostty's canvas size, with content_scale set to the integer device scale factor. Ghostty's renderer treats `set_size` as the physical- pixel canvas and `set_content_scale` as the HiDPI font/cell-metrics density, so it ended up drawing into the bottom-left sub-rectangle of an oversized FBO. Visible symptom: terminal area occupies ~62% (at 1.25) or ~44% (at 1.5) of the pane, the rest is black, keystrokes are consumed but rendered off-screen. Pass the physical-pixel canvas to `ghostty_surface_set_size` and keep `content_scale` at the integer scale factor so font metrics still match the compositor's downscale path. At integer scales (1.0, 2.0) the behaviour is unchanged. Extract the conversion as a pure helper `physical_size_for_scale` with a regression test pinning the invariant (logical × scale, including zero-dim edge cases). Update the initial-sizing comment to point at the helper and drop the redundant width/height gating (refresh_surface_display already checks > 0 internally). Add a CLAUDE.md Pitfalls entry on the GTK ↔ Ghostty pixel-unit boundary so future contributors touching the GLArea sizing path see the gotcha. Closes am-will#82 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
73e6cd6 to
66c002b
Compare
|
Tested on Hyprland + GTK 4.22 (1.25× scaling), fix works. Thanks! |
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
Fixes the terminal area rendering into the bottom-left sub-rectangle of the GLArea on Wayland fractional-scale outputs (1.25, 1.5, …). Keystrokes were accepted but invisible because they were drawn outside the visible region.
Root cause and reproduction documented in #82.
Fix
refresh_surface_displayused to pass:set_size(w, h)withw, h= GLArea logical allocation (CSS pixels)set_content_scale(scale, scale)withscale = gl_area.scale_factor()(integer)GTK4 actually allocates the FBO at
logical_size × scale_factor()physical pixels and Ghostty treatsset_sizeas the physical-pixel canvas, so the renderer drew into a sub-rectangle of the oversized FBO.This PR passes the physical-pixel canvas to
set_size(logical × scale_factor) and keepscontent_scaleat the integer scale so font/cell metrics match the compositor's downscale path. At integer scales (1.0, 2.0) the behaviour is unchanged.Behavior changes
surface-health.width_px/surface-health.height_pxexposed via the control bridge now report physical pixels instead of logical ones, because they are sourced fromghostty_surface_size()andset_sizeis now physical. External consumers (cmux, automation scripts) that compare these against GTK allocations or previous expected values will see numbers scaled byscale_factor()on HiDPI displays.Test plan
./scripts/check.sh— passes (only the known baseline test failure from CLAUDE.md is unaffected)Tested on Bazzite Fedora 44, NVIDIA open 595.71.05, GTK 4.22.4 system + bundled libghostty.
Closes #82
Before fix
After fix