Agent chat: a drag selects the words under the pointer, not the line above

Merged
AU
12d ago
+246-27

Summary

In the agent chat, a drag to select text picked words on the line above the pointer (dogfood report, 2026-10-21; the reporter's chat runs at app.uiScale 1.35 Ɨ agentPane.zoom 0.9, in the app's Chromium page). Transcript rows and the thread's lift were placed with transform: translateY(...). They are now placed with top:

  • RowFrame sets top: top + THREAD_TOP. An explicit top counts from the thread's padding edge, where the unset one sat 16 px lower, so the row adds the thread's 16 px padding and draws exactly where the translate put it.
  • The thread's lift is top: lift instead of translateY(lift). The glide() animation still adds a transform on top, so the sum is unchanged.

The reporter tried a build of this branch (23826-chat-select-offset-fix) at their zoom and confirmed the drag now selects under the pointer.

Tests that read a row's place from its transform now read style.top less the 16 px padding (thread minimap rail, scroll-map rail, turn keys, fold anchor, long-chat updates, chat column). The thought-find gallery play's layout-shift limit goes from 0.01 to 0.05. Find's intended move of the rows below now counts as a layout shift (0.034 in Chromium), because a top move is measured and a transform move was not.

New webviews/test/agent-pane-select-drag.test.ts (real agent pane, Chromium and WebKit, root CSS zoom 1 and 1.25): drags along each line of a long reply select words from that line only, and the first row sits 16 px into the thread. CSS zoom is not the app's page zoom, so this guards selection and placement. It does not reproduce the app's bug, and it passed before the fix at zoom 1 and 1.25.

Testing

  • Hosted CI on 54d2c91: all webview shard failures that remained are base reds (also red on feat-cmux-next c3c859fb: agent-pane-peer-chat, lit-glyph-css, agent-pane-subagents-tab). Two were this PR's, and 03454d1 fixes both: transcript-thought (the layout-shift limit above) and the select-drag 1.5 CSS-zoom case (dropped).
  • Gallery health: green on 54d2c91.
  • cmux-next checks → "Checks job structure", release-notary / Guard status and the CI guard group's workflow tests are red on feat-cmux-next too. This PR changes only webviews/ files.
  • bun run check (webviews) and scripts/cmux-next/prepush-gate.py: pass.
  • Tagged builds: 23826-chat-select-offset-before (c862eb5, test only), 23826-chat-select-offset-fix (04d59c4; the reporter confirmed the fix on it), 23826-chat-select-offset-fix-v2 (54d2c91, with the 16 px correction).

Observed / Not run

  • Observed: the reporter dragged in the -fix build at their zoom; the selection lands under the pointer.
  • Not run: the reporter has not yet tried the -fix-v2 build, which only adds the 16 px placement correction (rows back where they were drawn before). Not run locally: Swift or app builds (fleet only), webview tests (hosted CI).
  • In the tagged app the agent pane renders with CEF. debug.mouse drags go to the main window, not the page's child window, so automation could not show the offset.

Review

Two subagent correctness reviews. The first found that rows drew 16 px high (explicit top vs static position), fixed in 54d2c91. The second, on 54d2c91, returned SHIP with nits (stale test comments, fixed in 03454d1).

Changelog

Fixed: A drag in the agent chat selects the words under the pointer, not the line above

šŸ¤– Generated with Claude Code