Repository navigation
fix(ui): stop code blocks from widening chat bubbles and make their scrollbar usable - #1189
Merged
catatafishen merged 1 commit intoOct 17, 2026
Conversation
…crollbar usable A fenced code block with one long line laid the whole document body, prose included, out at the code width, so every prose line clipped at the bubble edge (catatafishen#1180). ScrollableCodeView hides its preferred X span but not its minimum, and BoxView.layoutMinorAxis never allocates a child below its minimum, so the uncapped code-line minimum propagated up through the whole box hierarchy. - ScrollableCodeView.getMinimumSpan(X_AXIS) = 0, mirroring the preferred-span override that already exists - scrollbar strip is now interactive: thumb drag, track-click jump, events intercepted before the caret so no text gets selected - scrolling invalidates the paint cache (stale-frame blit made every scroll visually dead) and is baked into getOffset geometry so selection hit-testing matches the painted pixels - Shift+wheel scrolls an overflowing block, plain wheel always passes through to the chat; a widening resize re-clamps or clears the scroll so no stale offset survives - a selection dragged past the block edge auto-scrolls the block - an in-progress strip drag is dropped when the document re-renders Tests: overflow matrix incl. the streaming path and the real thinking-bubble hierarchy from catatafishen#1180, interaction coverage for the scrollbar, resize and non-overflowing wheel cases.
BambinoSK
requested a deployment
to
fuzzing-gate
October 17, 2026 00:32 — with
GitHub Actions
Waiting
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This branch is waiting to be deployed
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.
Fixes #1180
Problem
When a chat bubble contains a fenced code block with one long line, the whole bubble body (prose paragraphs included) is laid out at the code width instead of the bubble width. Every prose line then clips mid-word at the right edge of the bubble. Issue #1180 reports this for the thinking bubble; the same mechanism affects message bubbles.
Root cause:
ScrollableCodeView(the view behind<pre>blocks) overridesgetPreferredSpan(X_AXIS)to report 0 so the pane does not inflate to the code width, but it did not overridegetMinimumSpan.BoxView.layoutMinorAxisnever allocates a child less than its minimum span (spans = max(childMin, targetSpan)), and the view's inline children are deliberately uncapped so code lines stay intact for horizontal scrolling. The longest code line's minimum therefore propagated up through the whole box hierarchy, and the body laid out at the code width no matter how narrow the bubble was.What this PR does
ScrollableCodeView.getMinimumSpan(X_AXIS)now reports 0, mirroring the existing preferred-span override. The document body lays out at the bubble width again; code blocks keep their natural line width and remain horizontally scrollable, by design.BoxView.getOffsetgeometry instead of a paint-time translation, so hit-testing (viewToModel), the caret and selection painting agree with the painted pixels; selecting in a scrolled block no longer hits wrong charactersNotes for reviewers
NativeChatPanel: prose streamed in chunks likesession/update, laid out headlessly, laid-out content measured against the pane width. With the fix reverted it fails (prose at 633px in a 175px pane); with the fix it passes.Verification
NativeMarkdownOverflowTest(8): overflow matrix - plain prose, long inline code, indented code, list-item inline code, table code cell, blockquote code, fenced block with a long line (complete and streamed parse)NativeMarkdownCodeScrollInteractionTest(8): strip drag to max without selecting text, track-click jump, press outside strip passes through, plain wheel passes through to the chat, Shift+wheel consumed, selection drag auto-scrolls, widening resize clears a stale scroll, Shift+wheel over a non-overflowing block passes throughNativeChatThinkingBubbleWidthTest(2): prose-only and prose + code block in the thinking bubble stay inside the paneNativeMarkdownWrappingTest(10) still green.getMinimumSpanoverride makes the fenced and thinking-bubble tests fail, the prose-only tests stay green (prose always wrapped; only the code-block channel regresses).How to verify
git log --graph --pretty=format:...command) with prose around it.