Repository navigation
Agent chat: the minimap's hover card blurs the chat behind it, not just tints it - #24024
Conversation
After #23782 the card hovering a minimap mark had the tooltip tint and backdrop-filter: blur(20px) saturate(1.4), but the transcript showed through it sharp, in Chromium and WebKit. The card drew inside the transcript scroller, whose soft-edge mask makes the scroller the card's backdrop root, so the blur had nothing to read. The card now draws in the scroller's parent (a portal), positioned from an anchor left in the rail, so it lands where it did and blurs the rows. The rail keeps the scroller's fade mask. The card takes the rail's tokens and the tooltip layer. Tests: the card is never inside .acpmux-scroll (both rails). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Owned by glass-regressions on cosmic-gray · session |
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Gallery before/after for
States
Pick other states with a Passes: CI passes on CI passes on Written by red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: Tour of |
|
Found 11 test failures on Blacksmith runners: Failures
...and 1 more test failures. View all on Blacksmith
|
Drawn outside the transcript scroller, the card took the wheel to the stage, which does not scroll. It hands the wheel to the scroller, as the card did when it drew inside it. The card now takes the scroller itself and draws in its parent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Bead |
… listeners Drawn outside the transcript scroller, the card scrolled it with scrollBy alone, so the scroller's wheel listeners never ran: the scroll did not count as the reader's (a slow scroll up from the latest row snapped back), and a minimap jump or glide in flight kept going. The card now hands the wheel on as Jump to latest does (wheelPassThrough's forwardWheel): a copy to the scroller first, then the scroll, with page deltas and pinch handled the same way. A scrolling key on the card's bookmark (arrows, Page Up/Down, Home, End) scrolls the transcript too, as it did when the card drew inside it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…minimap jump Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review (subagent, correctness first): SHIP at 1403012 Blocking findings: none. Non-blocking findings: the new rail test does not directly assert Space/Return bookmark activation or a horizontal-only wheel; I found no regression in those paths from the diff. The forwarded wheel and key events are non-bubbling, so they reach the transcript's own listeners once without re-entering the card or rail handlers. Home/End, deltaMode 2, ctrl-pinch, and the bookmark PageDown path are covered. Checked: exact diff from merge-base c3075d0; portal placement and anchor geometry in PreviewCard.tsx, forwardWheel and unchanged installWheelPassThrough behavior, both ThreadMinimap and ScrollMap callers, App/followTrace/scrollMotion/fold-anchor/pending-step listeners, and the test delta. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review (Codex xhigh via acpmux, correctness first): SHIP at 57f4868 Blocking findings: none. Non-blocking findings: none. Checked: the PR-only patch has the same stable patch ID before and after the merge; the only intervening base commit touching these paths changes diff-viewer option persistence in App.tsx and does not affect the minimap card, scroller wheel or key forwarding, masking, or rail tests. |
An independent review blocked the gap sentence this PR had added: "backdrop-filter does not draw over a see-through Chromium page, so a glass panel over one reads as tint without the frost it has over WebKit." The repo's only probe of that says the opposite. glass-lens-DESIGN.md (macOS 27, Playwright WebKit, 2026-10-20): WKWebView "parses `backdrop-filter: url(#svg-filter)` but renders nothing for it ... where Chromium bent them." #24024 separately frosts a glass card over the Chromium agent chat. Replacing one false claim with another unverified one is the thing this PR exists to stop, so the sentence goes rather than gets narrowed. What stays is what the review verified hop by hop: the shim binding (`shim_process.mm`, `shim_background.mm`), `CEFTab.pageSeeThrough`, the single unconditional `setSeeThrough(true)` on the one Chromium start path in `PageWebView+Chromium`, and a browser site staying opaque because `pageSeeThrough` defaults false. Two additions, both cited in the tree: a browser tab on the New Tab or blank page is see-through in both engines, Chromium's by masking the page out (`PageBackground`, `CEFTab.applyOcclusion`, Lawrence 2026-10-10); and the engine-agnostic reason a `backdrop-filter` has nothing to bend over a transparent region, which is why the lens hands each page a still of the wallpaper (glass-lens-DESIGN.md). "web pages" became "a site in a browser tab": the One backdrop rule twenty lines up uses "web pages" for cmux's own surfaces, so the two read as a contradiction. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cb8-bbf0-7010-8d04-f9f2c0cb55df&host=big-red
#24269) * docs(next): a Chromium page is see-through, and the gap is backdrop-filter The "Known gap" paragraph said a Chromium page is an opaque child window that cannot show a see-through backdrop. 8e36a5b fixed that the same day the chat moved to Chromium, by binding the fork's cmux_tab_set_transparent_background through the shim, and PageWebView+Chromium applies it to every cmux page; the paragraph was never updated. Leo asked today whether we can show the background and style pages like AppKit, and this is the line someone reads to answer that. The real remaining gap goes in its place: backdrop-filter does not draw over a see-through Chromium page, so a glass panel over one reads as tint without the frost it has over WebKit (#24160 measured it). Leo-ask: ask-665f9ad8ba Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cb8-bbf0-7010-8d04-f9f2c0cb55df&host=big-red * docs(next): drop the backdrop-filter gap claim, which was backwards An independent review blocked the gap sentence this PR had added: "backdrop-filter does not draw over a see-through Chromium page, so a glass panel over one reads as tint without the frost it has over WebKit." The repo's only probe of that says the opposite. glass-lens-DESIGN.md (macOS 27, Playwright WebKit, 2026-10-20): WKWebView "parses `backdrop-filter: url(#svg-filter)` but renders nothing for it ... where Chromium bent them." #24024 separately frosts a glass card over the Chromium agent chat. Replacing one false claim with another unverified one is the thing this PR exists to stop, so the sentence goes rather than gets narrowed. What stays is what the review verified hop by hop: the shim binding (`shim_process.mm`, `shim_background.mm`), `CEFTab.pageSeeThrough`, the single unconditional `setSeeThrough(true)` on the one Chromium start path in `PageWebView+Chromium`, and a browser site staying opaque because `pageSeeThrough` defaults false. Two additions, both cited in the tree: a browser tab on the New Tab or blank page is see-through in both engines, Chromium's by masking the page out (`PageBackground`, `CEFTab.applyOcclusion`, Lawrence 2026-10-10); and the engine-agnostic reason a `backdrop-filter` has nothing to bend over a transparent region, which is why the lens hands each page a still of the wallpaper (glass-lens-DESIGN.md). "web pages" became "a site in a browser tab": the One backdrop rule twenty lines up uses "web pages" for cmux's own surfaces, so the two read as a contradiction. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cb8-bbf0-7010-8d04-f9f2c0cb55df&host=big-red * docs(next): make the see-through paragraph say exactly what each engine does Three precision findings from the second review, all of them wording this doc exists to get right. The New Tab sentence said "see-through in both engines too", which the source it paraphrases (`PageBackground`) also says unqualified — but the two mechanisms are not the same and they diverge. WebKit re-reads the URL every time (`WebKitTab+LoadingBackground.pageDidFinish`: `guard !PageBackground.isBlank`), while Chromium holes the page out only until the first real page and latches it (`CEFTab+LoadingBackground.reachedFirstRealPage`: `guard !pastFirstRealPage`, then `pastFirstRealPage = true`, with no reset in Sources). So a tab that visits a real page and returns to the New Tab page is see-through in WebKit and not in Chromium. The paragraph now names both mechanisms and that consequence. The wallpaper still is the host's, not the lens's: glass-lens-DESIGN.md says "the host gives each page a still of the wallpaper as it is drawn, and the page lenses its own copy of it", and the lens is the in-page canvas that consumes it. The see-through hop is gated on fork API 17 (`CEFShimLibrary`: "0 when the fork lacks it"), which the text stated flatly; it now names the API, as the sentence this PR deleted once named the fork. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cb8-bbf0-7010-8d04-f9f2c0cb55df&host=big-red --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
… that the card draws outside the scroller #24024 (on the base) moved the preview card out of the transcript scroller, counted from an anchor at the rail box's origin. The base merge keeps that and puts the anchor at the box's top-right corner on the right edge; the card's right edge sits 52 px in from it (translateX(-100%)), so it still opens on the rail's left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cfc-5eec-7700-94d7-9a3a1f7d889a&host=Air-Blue
|
Shipped in:
|
|
Shipped in:
|
…24131) * feat(webviews): right-click the prompt rail to move it to the right edge Leo 2026-10-22: "also we can add an option for moving it the right.. maybe specifically right clicking that area (and as a toggle) it can happen". - New setting agentPane.display.rail.side (left, the default, or right): Settings > Appearance > Agent Chat > Prompt Rail Side. The page writes it through pane.setDisplay like the chat's other display keys, so it persists in cmux.json and every pane follows. - Right-clicking the rail (the compact wave or the full-height map) opens a one-item menu: Move to Right Edge, or Move to Left Edge once there. - On the right the rail keeps its 16 px inset, its ticks mirror so they grow toward the chat, and the preview card opens on its left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cfc-5eec-7700-94d7-9a3a1f7d889a&host=Air-Blue * chore(settings): regenerate settings exports for agentPane.display.rail.side From the cmux-next PR autofix's pr-autofix-patch (run 39722195254). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cfc-5eec-7700-94d7-9a3a1f7d889a&host=Air-Blue * test(webviews): the right-edge card test reads the card's anchor, now that the card draws outside the scroller #24024 (on the base) moved the preview card out of the transcript scroller, counted from an anchor at the rail box's origin. The base merge keeps that and puts the anchor at the box's top-right corner on the right edge; the card's right edge sits 52 px in from it (translateX(-100%)), so it still opens on the rail's left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cfc-5eec-7700-94d7-9a3a1f7d889a&host=Air-Blue * chore(settings): regenerate settings exports after the base merge Applied the pr-autofix-patch artifact of cmux-next PR autofix run 39866476045 at 05920ae. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15cfc-5eec-7700-94d7-9a3a1f7d889a&host=Air-Blue * Keep right prompt rails clear of narrow transcript input Apply the base rail overlap budget to both sides: the right rail needs its 16px inset plus 36px box minus the allowed 8px overlap. Cover compact and full-map rails at 780, 800 and 808px while preserving the left rail at 780px. Agent-Session: https://cmux.com/deeplink/agent?id=aid-6ad1c5c1b6253dbaefb1 * Fix prompt rail preview layout through its context-menu wrapper Agent-Session: https://cmux.com/deeplink/agent?id=aid-6ad1c5c1b6253dbaefb1 * fix(agent-pane): the rail's context-menu host keeps its layout box, so the card tracks the rail b0fe9c1 gave the rail's ContextMenu host `display: contents` to keep it from adding a layout box between the rail and its preview. On WebKit that put the portaled card back out of step with the rail: `thread-minimap-left-rail-stays`' "an open card follows its rail on every painted inspector and resize frame" went red at 1084px, the card trailing by 1.048 px on one frame (card 116.866, rail 117.914), the same shape of drift 7141d0b had just fixed on base. The host sits inside .acpmux-minimap and wraps only the absolutely positioned rail; the preview card is its sibling, not its child, so the box was never between them and the rule bought nothing. Without it both engines hold the rule again. Measured on the fleet, same command each time: base tip 3a7653b 16/16; this branch before this commit 15/16 (that WebKit case); with only the ContextMenu wrapper removed 16/16; with the wrapper kept and this rule dropped 16/16. After it: the six minimap browser suites are 35 pass, 1 fail and the twelve jsdom suites 97 pass, 0 fail. The one browser failure is thread-minimap-motion's click-easing sample, which fails the same assertion on base tip (progress(40) 0.3 there, 0.341 here, both against < 0.12). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-6d1e976f71e5d3853c97 * test(agent-pane): guard minimap context host layout Agent-Session: https://cmux.com/deeplink/agent?id=aid-3e1080db909e7ceb2abe * test(agent-pane): attach to zero-size minimap host Agent-Session: https://cmux.com/deeplink/agent?id=aid-3e1080db909e7ceb2abe * test(agent-pane): keep right rail aligned through inspector motion Agent-Session: https://cmux.com/deeplink/agent?id=aid-3e1080db909e7ceb2abe * fix(agent-pane): clamp the right rail from its own edge Agent-Session: https://cmux.com/deeplink/agent?id=aid-3e1080db909e7ceb2abe * test(agent-pane): allow painted edge rounding Agent-Session: https://cmux.com/deeplink/agent?id=aid-3e1080db909e7ceb2abe * Type the rail card's side-aware style; map the session rail surface to its spec Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64 * Gallery: the prompt rail on the right edge, resting and hovered Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64 * Right rail: sit inside the VS Code minimap when it is on The VS Code minimap (agentPane.display.vscodeMinimap, off by default) draws at the pane's right edge, so a right rail at the same inset lay under it. useRailPlacement now reserves the minimap's width plus its edge on the right when the minimap is on and has its room, and measures the rail's compression and overlap from there. The left rail is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-d750cf10922c785efa64 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Follow-up to #23782 (the minimap hover card went glass).
What was wrong. After #23782 the card hovering a thread-minimap mark had the tooltip tint and
backdrop-filter: blur(20px) saturate(1.4), but the transcript text behind it showed through sharp. The result was tint without blur, which reads worse than the old solid card. The card was drawn inside the transcript scroller.acpmux-scroll, and that scroller carries the soft-edgemask-image(conversation.css). A masked ancestor is the card's backdrop root, so the blur had nothing to read. Removing the mask in a diagnostic capture made the blur work. Turning offcontain: strictchanged nothing.What changed (minimap card, both rails: compact and full map).
PreviewCard.tsx: the card is portaled into the scroller's parent (the stage), which has no mask. A zero-size anchor (.acpmux-minimap__anchor) stays in the rail, and the card's x and y are measured from it before paint, so the card lands exactly where it did. The wheel over the card is handed to the scroller, so it still scrolls the chat as it did when the card was inside it. Without a scroller, the card draws in place.ThreadMinimap.tsx,ScrollMap.tsx: passscroller={scroller.current}.threadMinimap.css: the card takes the rail's--acpmux-minimap-*tokens (and the borders-none rim) because it no longer inherits them from the rail. It sits on--layer-tooltip, like the chat's other hover cards. The scroller's fade mask is unchanged.Before and after (Linux gallery,
agent-pane.thread-minimap/ long-chat, compact rail, row 8 hovered, Chromium, 880 px):The card's position is pixel-identical before and after. Only the backdrop changes.
WebKit note. The gallery's headless WebKit (Playwright, Linux) draws no
backdrop-filterat all: a bare test page with a blurred card over text renders the text sharp there too, while Chromium blurs it. So the WebKit gallery stills cannot show the blur either way. The fix does not depend on the engine: the card has no masked, filtered or opaque ancestor any more. Its ancestors are only.acpmux-stage,.acpmux-mainand.acpmux-shell, which have no mask, filter, opacity orcontain.Other glass inside
.acpmux-scroll(audited). One more surface has the same problem and is left out of this PR: the Find in Chat pill (ChatFindBar, a direct child of the scroller; blur fromfindPill.css). It needs its own anchoring to the scroller's top-right, so it gets a separate PR. Every other glass surface is either portaled (link and PR hover cards, session hover cards, tooltips, hints, menus, popovers, context menus) or rendered outside the scroller (image viewer, jump pill, composer). The user bubble in the rows has no blur (--glass-backdrop: none).Tests.
thread-minimap-rail.test.tsxandthread-scroll-map-rail.test.tsxcheck that the open card is not a descendant of.acpmux-scroll, that it sits in the scroller's parent, and that the rail keeps the anchor. The rail test also checks that a wheel over the card scrolls the transcript. The descendant tests fail without the fix (2 fail) and pass with it.bun testfor thread-minimap-rail, thread-scroll-map-rail, thread-minimap-card-glass, hover-intent-cards, thread-minimap-feel and subtle-elevation: 56 pass, 1 skip (browser lane), 0 fail.bun run typecheckpasses.check:layersok.vp fmt --checkandvp lintare clean on the changed files.Agent session: cosmic-gray
🤖 Generated with Claude Code