fix(mac): transcript visual restoration — reuse corruption, card chrome, hover meta - #462
Merged
Merged
Conversation
…ption Two reuse bugs made the AppKit transcript degrade as rows recycled: clearContent used removeArrangedSubview, which only stops managing a view — it stays mounted at its last frame, so every reconfigure stranded the previous row's content on screen (stray bars, overlapped decision options), and recycled wrapping text fields kept their previous row's preferredMaxLayoutWidth, so reused fields re-wrapped at whatever narrow column they last had (one-word-per-line approvals, checkpoints, commands). Remove strands explicitly, reset the wrap width on configure, and give un-assigned fields a deterministic single-line intrinsic to compress from. Restore the visual chrome the port dropped: tool, approval, checkpoint, plan, reasoning, decision, usage-limit, and session-exit rows get their rounded card backing (state-tinted fill, hairline border, accent rail on decisions/failures) matching the SwiftUI islands; the user bubble regains its accent hairline; disclosure headers tint like plain headers; the transcript fade veil returns under scrolled-away tails; and the content column returns to 840pt. Permanent timestamp lines and Copy/Edit/Retry button rows collapse into one hover-revealed meta line per row. Buttons stay enabled — keyboard, accessibility, and programmatic activation are unaffected — while hidden chrome ignores mouse hits so an invisible button can't swallow a click. Card-backed rows carry their extra insets in the height estimate so first paint no longer clips until the measured height commits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ayout, calibrate estimates The activity-dock probe surfaces (pinned and detached) were registered by the retired SwiftUI scroll view and died with it — the dock rendered but the default sweep's three mount checks failed on every run since the port. Register both surfaces on the ChatScreen overlay that hosts the dock now. Code blocks measured their height with per-line font math that undershoots TextKit's typographic line height; measure the laid-out text instead (code never wraps, so the height is width-independent and bounded by maximumCodeCharacters). The markdown fragment measure path also still clamped content to the pre-restoration 800pt column. Approval, decision, and checkpoint rows render caption/choice/control lines that never appear in their estimate text; count them so first paint stops clipping until the measured height commits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
|
Follow-ups from the PR description are now fixed in this branch:
Full mac suite green (1107+296+36); the one |
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.
Problem
The AppKit-ported chat log looked broken and cluttered:
clearContent()usedremoveArrangedSubview, which only unmanages a view; it stays insubviews, drawn at its stale frame. Every reconfigure stranded previous content on screen: stray bars, ghost rows, decision options drawn on top of each other. Separately, recycledNativeWrappingTextFields kept the previous row'spreferredMaxLayoutWidth, so reused fields wrapped at ~70px — approvals, checkpoints, and commands rendered one word per line.Fix
Reuse correctness
removeFromSuperviewon recycle, recursive for stacks).Chrome restoration (matching the retired SwiftUI renderer's
TranscriptStylevocabulary)ChatTranscriptFadeEdge(gradient-masked material) restored under scrolled-away tails.Declutter
HoverChromeStackView.hitTestso invisible buttons can't swallow clicks.Verification
pnpm run test:mac).pnpm run verify --all: 5 steps pass.activity-dockmount-check failures that already fail onmain; before/after captures show cards complete on first paint, full-width wrapping, no ghost content, hover chrome hidden at rest.Follow-ups (not this PR)
activity-dockprobe mount-check failures onmain.🤖 Generated with Claude Code