Clip a line whose fallback run has no ellipsis glyph - #14967
Conversation
|
Every PR must be linked to a same-repo issue before Oz can review it. This PR is linked to #14966, but no linked issue is marked See the contribution guidelines for the full readiness model. Powered by Oz |
There was a problem hiding this comment.
Every PR must be linked to a same-repo issue before Oz can review it.
This PR is linked to #14966, but no linked issue is marked ready-to-implement yet. Only repository maintainers apply that label, so please wait for a maintainer to mark the issue. Once it is marked, push a new commit or comment /oz-review to re-trigger review.
See the contribution guidelines for the full readiness model.
Powered by Oz
`Line::paint_internal` looked up '…' in one run only — `runs.first()` for end-clipping — with fallback fonts disabled. A title starting with a symbol its font lacks puts that symbol in its own fallback run, and that run's font usually has no ellipsis: Hack has no U+2733, so Core Text splits a leading `✳` into a Zapf Dingbats run. The lookup failed there, `ellipsis_width` stayed 0, and the glyph loop read that as "no ellipsis to reserve room for" and fell through to the bare `remaining_width <= 0.` stop, which lets the straddling glyph paint in full. The fade that would have hidden it was disabled unconditionally for `ClipStyle::Ellipsis`, so the line painted past its own bounds — a CLI agent tab title drawn over the vertical-tabs unread dot beside it. Resolve the ellipsis from any run that can draw one, keeping the previous starting point because it decides which font's advance a mixed-font line reserves room for, and suppress the fade only once an ellipsis is actually available so it can serve as the safety net. The test `FontDB` grows `without_glyph` and `with_advance` so a test can build a line whose runs disagree about their coverage, the shape real font fallback produces. Both default to today's behavior. Without them the run walk would be pinned only by the macOS test and reverting it would stay green everywhere else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fcFQkeeuTcrw5phcxSd2X
bc447e7 to
e85ab4b
Compare
Description
A line that asks for
ClipStyle::Ellipsisis not clipped at all when no run on it can draw an ellipsis. It gets neither the ellipsis nor the fade, so the glyph straddling the right edge is painted in full and the text overhangs its own layout box onto whatever was placed after it.That is reachable in normal use.
Line::paint_internallooked the ellipsis glyph up in exactly one run —runs.first()for end-clipping — with fallback fonts disabled. A title that starts with a symbol its font lacks puts that symbol in its own fallback run, and that run's font usually has no…:Hack has no U+2733, so Core Text splits the leading
✳into a Zapf Dingbats run, the lookup fails there, andellipsis_widthstays 0 — which the glyph loop reads as "no ellipsis to reserve room for", falling back to the bareremaining_width <= 0.stop that lets the last glyph overhang. The fade that would have hidden it is disabled unconditionally forClipStyle::Ellipsis.CLI agent tab titles are prefixed with exactly such a glyph, so in the vertical tabs sidebar a
✳-prefixed title paints over the unread-activity dot pinned to the right of the title line. The same title with a prefix Hack does have (◑, U+25D1) stays a single Hack run, finds the ellipsis, and truncates correctly — same code, same widths, different first-run font.Two changes:
…from any run, walking from the run painting starts at and continuing through the rest, rather than giving up on the first one. A run whose font reports a zero advance for…is skipped too, since the truncation branch would ignore it anyway. The starting point is deliberately unchanged: it decides which font's…— and so which advance — a mixed-font line reserves room for.ClipStyle::Ellipsisnow suppresses the fade only when an ellipsis is actually available, so the overhang can no longer paint unmasked.The fix is in the shared line painter, so it covers every
ClipConfig::ellipsis()caller, not just the sidebar.Testing
Four tests, all verified to fail on the pre-fix code, so none passes vacuously:
warpui_core … test_paint_end_ellipsis_fades_when_no_run_can_draw_an_ellipsisglyph at x=0 was painted with no fadewarpui_core … test_paint_end_ellipsis_resolves_from_a_later_runexpected 3 glyphs plus an ellipsis: 5 != 4warpui_core … test_paint_start_ellipsis_resolves_from_an_earlier_runexpected 3 glyphs plus an ellipsis: 5 != 4warpui platform::mac::… test_ellipsis_resolves_past_a_symbol_fallback_runthe truncated line painted no ellipsisThe
warpui_coretests are platform-independent, which matters here: the run walk would otherwise be pinned only by the macOS test, and reverting it toruns.first()would stay green everywhere else. To get there the testFontDBgrew two builder methods —without_glyphandwith_advance— so a test can build a line whose runs disagree about which characters they can draw, which is the shape real font fallback produces. Both default to today's behavior, so existing tests are unaffected.They assert the ellipsis carries the
font_idof the run that can draw one, that it lands inside the line's bounds, and that a line which did resolve an ellipsis is not also faded — the other half of the changed condition.The macOS test loads the bundled Hack, lays the reported title out through Core Text, and asserts the premise before the behavior: the leading run is not Hack and its font has no
…../script/format,cargo clippy -p warpui_core -p warpui --all-targets --tests -- -D warnings, andcargo nextest run -p warpui_core -p warpuiare clean../script/runNot checked deliberately:
./script/runbuilds the OSS channel, and reproducing this needs a CLI agent pane whose title carries the prefix glyph. The measurement above is from the reported build; the scene-level assertions are the evidence here.Known coverage limit
The winit font path has no equivalent test. Whether fontdb/rustybuzz splits a symbol-prefixed title into its own fallback run the way Core Text does is unverified, so a test written against it would be speculative about its own premise. The
warpui_coretests cover the run walk itself on every platform; what stays uncovered is real fallback behavior off macOS.Linked Issue
Closes #14966.
ready-to-implement. — Truncated text paints past its bounds when its fallback run's font has no ellipsis #14966 was filed alongside this PR and has not been triaged yet.Related
warpdotdev/warp#14930fixes a different defect on the same row — the agent avatar sitting in the top-left of the footprintrender_icon_with_statusreserves instead of centered in it. The two are independent: that one moves the icon, this one stops the title from painting past its box.Agent Mode