text_view: Let fenced code blocks scroll inside a height cap - #3322
Merged
huacnlee merged 2 commits intoOct 1, 2026
Merged
Conversation
Setting `overflow_y: scroll` on the `code_block` style refinement now puts the block in a vertical scroll viewport with its own `ScrollHandle`, a `ScrollableMask` and a `Scrollbar`, like tables do with `overflow_x: scroll`. The mask consumes the wheel in the capture phase, so a parent `gpui::list` no longer scrolls together with the code. The code block actions stay pinned to the block's top-right corner. Closes longbridge#3321 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
jarviisha
marked this pull request as draft
September 30, 2026 04:02
…nd fix docs The scrolling code block test now also runs without `code_block_actions`, the case that couldn't scroll at all before, and asserts that the code itself moves, not only that the list stays put. The vertical mask takes the block's id, as the table's mask does. The style docs and comments name the real `overflow.y` field, and ARCHITECTURE.md lists the code block next to the table under scrolling. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Closes #3321
Description
A long fenced code block in a chat answer rendered with
TextView::markdowninside agpui::listpushes the rest of the answer off screen. Capping it withTextViewStyle::code_block(StyleRefinement::default().max_h(..))could only clip it, and settingoverflow.y = Scrollon the refinement didn't work properly: the block only scrolled whencode_block_actionsgave it an id, it had no scrollbar, and one wheel tick scrolled both the code and the parent list.This follows the existing table pattern (
overflow_x: scrollonstyle.table). When thecode_blockrefinement setsoverflow.ytoOverflow::Scroll,CodeBlock::renderwraps the block with:ScrollHandle, kept per block withuse_keyed_state(block_element_id("codeblock-scroll", span, ix)), as tables do;ScrollableMask, which consumes the wheel in the capture phase so an ancestorgpui::listdoesn't scroll on the same event. Once the code reaches its top or bottom edge, the mask lets the wheel through to the list, as native nested scrollers do;Scrollbar.The mask takes the block's id, as the table's mask does. The mask, the scrollbar and the
code_block_actionsbox are siblings of the scrolled block, so the copy button stays pinned to the block's top-right corner. Scrolling doesn't depend oncode_block_actionsany more. Withoutoverflow.yset toOverflow::Scrollthe rendered tree is unchanged.docs/ARCHITECTURE.mdlists the code block next to the table under "Scrolling and Virtualization".Known limit, shared with the table scroll layout: if the refinement sets a margin or a fixed width, the mask, scrollbar and actions follow the outer frame rather than the block.
Public API
No items are added, changed or removed. One existing item gains a documented behavior:
gpui_base::text::TextViewStyle::with_code_block(style: StyleRefinement) -> Selfandgpui_component::text::TextViewStyle::code_block(style: StyleRefinement) -> Self: withoverflow.yset toOverflow::Scrolland a max height onstyle, long code scrolls inside the block with its own scrollbar instead of growing it.How to Test
cargo test -p gpui-base --lib scrolling_code_block_keeps_wheel_from_the_list: a scrollableTextView(backed bygpui::list) with a capped scrolling code block, run with and withoutcode_block_actions. From the painted text lines it asserts that a wheel over the code scrolls the code by exactly the wheel delta while the paragraph below (the list) and the pinned actions stay put, and that a wheel below the code still scrolls the list. The test fails without this change: the list scrolls under the code block.cargo test -p gpui-base --lib text::andcargo test -p gpui-componentpass.This change touches
gpui-base, becauseCodeBlockandTextViewlive there.The code and this description were written with AI assistance (Claude) and reviewed by me.
Checklist
cargo runfor story tests related to the changes.🤖 Generated with Claude Code