Skip to content

Keep a paragraph’s closing whitespace on its last row and in its width - #7

Draft
francois-unity wants to merge 2 commits into
unity/a11y-automationfrom
unity/HUB-8048-hang-trailing-whitespace
Draft

francois-unity wants to merge 2 commits into
unity/a11y-automationfrom
unity/HUB-8048-hang-trailing-whitespace

Conversation

@francois-unity

@francois-unity francois-unity commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Keeps the whitespace that ends a paragraph on its last row, and counts it in the paragraph’s block width when it fits, so a block ending in a space neither grows an empty row nor loses its space.

Why: Parley’s line breaker hangs a space that overflows a row and then breaks, so a space that ends the paragraph leaves an empty row behind, and that row counts in the layout height. A block’s max-content width comes from Layout::width(), which leaves trailing whitespace out, so laying the text out again at exactly that width always wraps it. In the native Unity Hub, div().child("Can’t find the version you’re looking for? Visit our ") laid out at 303×40 instead of 303×20 (Inter 13px on a 20px line), and a baseline-aligned row of such fragments dropped its link a line (HUB-8048).

  • First commit: when the last rows hold only whitespace after a soft break, parley_paragraph_layout breaks the paragraph again, the earlier rows as before and the last one with no width limit, still aligned within the wrap width. That also removes the empty row Parley leaves after an oversized inline box that ends a paragraph. A forced break (U+2028) still starts its own row.
  • Second commit: hanging alone kept the row but not the space, so in a sentence built from fragments the link sat flush against “our”. A block’s width now counts the whitespace that ends its paragraph when it fits in the width the paragraph was given, as a text element’s width (LineLayout::width) already does. When it doesn’t fit, it hangs and stops counting.

How to test

  • cargo +1.98.1 test -p gpui_ce_parley: four new tests in text_system/tests/inline_reflow.rs, each failing without the fix: the Hub’s footer sentence as a baseline-aligned flex row (one row, space kept), the closing-space width rule, the text system at its own width with and without a line clamp, and an oversized trailing inline box. block_line_clamp_ignores_wrapped_trailing_whitespace stays green.
  • cargo +1.98.1 test -p gpui_ce_elements -p gpui_ce_macos stays green.
  • clippy, msrv, test-linux and test-windows stop on the base’s bindgen build-script error before reaching this code; Declare gpui_media’s bindgen build dependency on every host #6 fixes that.
  • Unity Hub pins the same two commits on top of unity/wayland-early-app-id (unity/HUB-8048-hub-pin-3, 6f7e4cfe3b), since its pin also carries elements/div: add an aria_url passthrough #4 and the test text system commit.

@francois-unity francois-unity self-assigned this Oct 5, 2026
@francois-unity francois-unity changed the title Hang the whitespace that ends a paragraph on its last row Keep a paragraph’s closing whitespace on its last row and in its width Oct 6, 2026
@chris-addison
chris-addison force-pushed the unity/a11y-automation branch from 2805d34 to 33d34a1 Compare October 6, 2026 18:24
Parley’s line breaker hangs a space that overflows a row and then
breaks, so a space that ends the paragraph leaves an empty row behind,
and that row counts in the layout height. A block’s max-content width
comes from Layout::width(), which leaves trailing whitespace out, so
laying the text out again at exactly that width always wraps it: a box
holding "Visit our " measured one row taller than the text it paints.
CSS hangs that whitespace instead.

After line breaking, a paragraph whose last rows hold only whitespace
after a soft break is now broken again: the earlier rows as before, and
the last one with no width limit, still aligned within the wrap width.
That covers several trailing spaces, whitespace-only text and clamped
layouts, and the empty row Parley also leaves after an oversized inline
box that ends a paragraph. A forced break (U+2028) still starts its own
row, and widths don’t change, since Layout::width() already left the
hanging whitespace out.
The previous commit hangs a paragraph’s closing whitespace on its last
row instead of wrapping it onto an empty one. A block still measured
its width with Layout::width(), which leaves trailing whitespace out,
so a fragment ending in a space now sat flush against the next one: in
a sentence built from fragments, "Visit our " followed by a link read
"Visit ourdownload archive". A text element’s width
(LineLayout::width) already keeps that space.

A block’s width now counts the whitespace that ends its paragraph when
it fits in the width the paragraph was given, so a block laid out
again at its own measured width keeps both its row and its space. When
it doesn’t fit, it still hangs and stops counting. Whitespace before a
forced break and the spaces a soft wrap hangs still don’t count.

The element test now builds that sentence as a baseline-aligned flex
row and checks both its row and its space, and a unit test pins when
the space counts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant