Skip to content

Fix assistant layout after collapsing a work log - #898

Merged
Tryanks merged 1 commit into
mainfrom
fix/collapse-layout-shift
Oct 16, 2026
Merged

Tryanks merged 1 commit into
mainfrom
fix/collapse-layout-shift

Conversation

@Tryanks

@Tryanks Tryanks commented Oct 16, 2026

Copy link
Copy Markdown
Owner

Summary

Collapsing a Work Log can leave the following assistant answer at the timeline's left edge, with its timing footer over the last line. Keep each virtualized chat row identified by its existing content identity.

 ChatView timeline row
-  anonymous root (gpui-fast matches it by list index)
+  .id(("timeline-row", row.identity))

Expanding a Work Log inserts virtualized activity rows, changing the following message's list index. gpui-fast 0.1.8 can reuse its retained Markdown layout under the changed ancestor path without measuring it again, losing ancestor offsets. The carry belongs at the chat list owner, using the identity already owned by TimelineRow; it adds no state, helper, dependency, or test-only production seam.

Checked the other collapsibles: command output, tool details, thinking blocks, disclosures, and inline diffs append their bodies as final children. They do not omit a child before a following sibling when toggled. Changed-file chips and their more/fewer control already have element IDs. The work-log header renders separately from its virtualized activity rows, so an empty body placeholder would not address this case.

Evidence

  • Before: chat::tests::collapsing_work_log_preserves_following_message_bounds fails alone and with the chat suite (34 other tests pass). The 720px-wide answer moves from (340, 640) to (20, 736); its last paragraph ends at y=830 while the footer remains at y=770. Removing only the row ID makes the final regression test fail again for the same bounds mismatch.
    After: The real ChatView is seeded through the existing host fixture, rendered, expanded and collapsed through simulated clicks, then drawn. The answer's first/last paragraph bounds and footer bounds equal their initial values, and the footer clears the final paragraph, in light and dark themes at 1400px and 393px. The chat suite passes all 35 tests.
  • The failing assertion protects the reported visible geometry regression; existing virtualization and manual-collapse tests did not assert the following answer's bounds. CONTRIBUTING's failure review settles this at step 3: a real product failure, fixed at its owner. No existing tests were rewritten, loosened, or removed. chat/mod.rs: 34 → 35 tests; +4 production lines, +76 test lines.
  • Validation (all cargo subcommands used /Users/tryanks/.local/share/mise/installs/mr-boxington/latest/.mise-bins/mbx):
    • mbx fmt --all --check and git diff --check — passed.
    • mbx clippy --workspace --all-targets --locked -- -D warnings — passed.
    • mbx nextest run --workspace --locked --test-threads 4 --no-fail-fast — 1,242 passed, 13 skipped; no leaks.
    • RUSTFLAGS='-D warnings' mbx check -p tcode-web --target wasm32-unknown-unknown --locked — passed.
    • mbx machete — passed; no unused dependencies.
  • Per the maintainer's updated instructions, no app was launched or driven, no new screenshots were taken, and nothing was installed. Desktop visual verification is left to the maintainer; the two-theme/two-width checks above are suite geometry checks. No upstream files were changed or upstream actions taken.

Merge Danger

Door: two-way

Blast Radius: chat

Changes retained element identity for chat timeline rows; existing layout and scroll tests run against it. No protocol, persistence, or dependency changes.

@Tryanks
Tryanks merged commit c658643 into main Oct 16, 2026
7 checks passed
@Tryanks
Tryanks deleted the fix/collapse-layout-shift branch October 16, 2026 04:34
Tryanks added a commit that referenced this pull request Oct 29, 2026
…ds it closes removed (#1011)

* Dependencies: gpui-base, gpui-kit and gpui-webview 0.8.1, on gpui-fast 0.1.12

gpui-base 0.8.1 pins gpui-pre 0.3.10 and gpui-fast 0.1.12, so the
reqwest-client snapshot follows to 0.3.10 and every crate's gpui-fast
minimum states 0.1.12.

GPUI renamed `ScrollWheelEvent` to `ScrollEvent` and added the input's
source; the mobile two-finger pan is a touch scroll, and so are the finger
pans the selection tests simulate.

`KeyBinding::new` no longer reads `secondary-`: it panics at startup.
`shortcut::secondary` loads those bindings for the host OS, which GPUI now
reports at run time, so a browser on a Mac binds Command as a native Mac
build does. `Kbd::format` reads the same OS, so a hint names the key its
binding takes.

* Scroll, Sidebar, Chat: drop the workarounds gpui-base 0.8.1 and gpui-fast closed

Page viewports go back to gpui-base's own wheel bounce. #933 turned it off
because a release while moving threw the edge and f32 rounding of the delta
the content used read as reaching it; gpui-base 0.8.1 throws the edge only
when it is stretched and ignores that rounding. The test #933 added, a drag
right after a flick, holds with the default.

gpui-fast fixed a reparented retained child left unmeasured (#68) in 0.1.9,
and since 0.1.11 measures text that reaches prepaint unmeasured instead of
panicking. The sidebar's empty provider-mark slot and the chat row's
content-keyed id existed only for #68: the mark is absent while marks are
off, and rows carry no id; the images inside them are keyed by their
message. The provider-mark toggle test (#452) and the Work Log collapse
test (#898) still pass.

* Markdown: a drag or shift-click from a double or triple click extends by its unit

gpui-base 0.8.1 extends a double- or triple-click drag, and a shift-click
after it, by words or lines, and keeps the clicked unit selected whichever
way they go (#3681). A transcript owns its selection, so it now holds the
unit the same way: until the button is released a drag moves the far end to
the edge of the word or line under the pointer, and a shift-click does so
until a plain click starts afresh. A long press, a touch handle and Select
Entry make their own selection and hold no unit.

* Mobile backends: report their OS to GPUI, and corners GPUI cannot see

gpui-fast 0.1.12 asks every platform for the host OS, which decides what
`secondary-` binds and how a keystroke is written: the iOS backend reports
iOS and the Android one Android, both native, so `secondary` stays Control
there as before. Window insets gained the display's corner radii; neither
host reports them, so they are zero, which GPUI reads as square or unknown.
The palette shortcut no longer imports `KeyBinding` for the macOS-only Quit.
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