Skip to content

Clip a line whose fallback run has no ellipsis glyph - #14967

Open
bobrnor wants to merge 1 commit into
warpdotdev:masterfrom
bobrnor:ellipsis-fallback-clip
Open

Clip a line whose fallback run has no ellipsis glyph#14967
bobrnor wants to merge 1 commit into
warpdotdev:masterfrom
bobrnor:ellipsis-fallback-clip

Conversation

@bobrnor

@bobrnor bobrnor commented Aug 11, 2026

Copy link
Copy Markdown

Description

A line that asks for ClipStyle::Ellipsis is 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_internal looked 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 :

"✳ Собрать версию с ПРа" laid out in Hack 12pt
run[0] font=ZapfDingbatsITC glyphs=1  advance=8.99  hasEllipsis=false
run[1] font=Hack-Regular    glyphs=21 advance=7.22  hasEllipsis=true

Hack has no U+2733, so Core Text splits the leading into a Zapf Dingbats run, the lookup fails there, and ellipsis_width stays 0 — which the glyph loop reads as "no ellipsis to reserve room for", falling back to the bare remaining_width <= 0. stop that lets the last glyph overhang. The fade that would have hidden it is disabled unconditionally for ClipStyle::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:

  • Resolve 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.
  • Fall back to the fade when no run can supply one. ClipStyle::Ellipsis now 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:

test failure without the fix
warpui_core … test_paint_end_ellipsis_fades_when_no_run_can_draw_an_ellipsis glyph at x=0 was painted with no fade
warpui_core … test_paint_end_ellipsis_resolves_from_a_later_run expected 3 glyphs plus an ellipsis: 5 != 4
warpui_core … test_paint_start_ellipsis_resolves_from_an_earlier_run expected 3 glyphs plus an ellipsis: 5 != 4
warpui platform::mac::… test_ellipsis_resolves_past_a_symbol_fallback_run the truncated line painted no ellipsis

The warpui_core tests are platform-independent, which matters here: the run walk would otherwise be pinned only by the macOS test, and reverting it to runs.first() would stay green everywhere else. To get there the test FontDB grew two builder methods — without_glyph and with_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_id of 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, and cargo nextest run -p warpui_core -p warpui are clean.

  • I have manually tested my changes locally with ./script/run

Not checked deliberately: ./script/run builds 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_core tests cover the run walk itself on every platform; what stays uncovered is real fallback behavior off macOS.

Linked Issue

Closes #14966.

Related

warpdotdev/warp#14930 fixes a different defect on the same row — the agent avatar sitting in the top-left of the footprint render_icon_with_status reserves 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

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

@cla-bot cla-bot Bot added the cla-signed label Aug 11, 2026
@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label Aug 11, 2026
@oz-for-oss

oz-for-oss Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

@bobrnor

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

@oz-for-oss oz-for-oss Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bobrnor

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
@bobrnor
bobrnor force-pushed the ellipsis-fallback-clip branch from bc447e7 to e85ab4b Compare August 12, 2026 06:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Truncated text paints past its bounds when its fallback run's font has no ellipsis

1 participant