Render sidebar symbols and the account avatar exactly like the Vault icons (Intel/macOS 15 follow-up)

Merged
AU
2mo ago
+465-234

Summary

Follow-up to #12126. The sidebar footer icons (Sign In, Help, phone) and the signed-in account avatar came back after that fix but disappeared again after a while on Intel Macs running macOS 15 (the popover, freshly created, still showed the avatar while the long-lived sidebar button went blank).

#12126 still let SwiftUI own pixels of those icons: symbols were drawn as a SwiftUI .foreground fill masked by the hosted AppKit view, and the avatar's hosted image view sat under a SwiftUI clipShape. Both paint at first and go blank later on these machines. The Vault icons (#10764) never did, because they take a different path: CmuxResolvedIconImage with the tint baked into the bitmap by the shared renderer plus a fallback source, with no SwiftUI mask or clip anywhere near the hosted view.

This PR puts every CmuxSystemSymbolImage and the account avatar on exactly that path.

  • CmuxSystemSymbolImage now takes an explicit tint: Color, bridged to a dynamic NSColor (NSColor(Color) resolves .primary/.secondary/.opacity per appearance and bridges equal colors to equal NSColors, keeping the hosted view's render key stable) and baked into the bitmap like SessionIndexResolvedSystemSymbolImage, with a same-symbol fallback source. CmuxHostedSystemSymbolImage no longer uses Rectangle().fill(.foreground).mask(...).
  • Every call site passes the color it used to inherit from .foregroundStyle / .foregroundColor. The right-sidebar header, titlebar control and pill button styles apply their hover/pressed dimming as view .opacity so the label color they set is a plain color the symbol can bake (same visual result).
  • StackAccountAvatarImageLoader clips the center-cropped picture to a circle inside the bitmap; StackAccountAvatarView draws it through CmuxResolvedIconImage with a tinted person.crop.circle.fill fallback (mirroring SessionIndexAgentIconImage) and no clipShape around the hosted view. The ring stays a vector overlay.
  • Verified with a small swiftc probe on the affected Intel Mac that a SwiftUI .colorScheme(.dark) subtree override sets darkAqua on hosted platform views while the window stays aqua, so baked dynamic tints resolve correctly inside themed chrome.

Two-commit regression-first history:

  1. 58ebc60ab3 — failing tests only (CmuxHostedSystemSymbolImageTests tint + fallback contract and Color→NSColor bridge, StackAccountAvatarImageLoaderTests circular clip, new StackAccountAvatarViewTests + pbxproj wiring)
  2. eb1611808d — production fix

No user-facing strings, shortcuts, settings, or localization catalogs changed (localization audit: only symbol tint plumbing and comments changed; no String(localized:) keys added or removed).

Testing

  • Universal (arm64 + x86_64) tagged Debug build of b227ac454f (pre-rewrite cb9ae22d14) succeeded on a fleet Mac (./scripts/reload.sh with ARCHS = arm64 x86_64). The later commits only touch tint call sites and the titlebar style; they were syntax-checked with swiftc -parse and CI's ci-status is green on the head.
  • The focused cmux-unit run on that fleet Mac could not start (Failed to establish communication with the test runner, a testmanagerd helper error on the headless host); the three new/updated suites are wired into cmux-unit (scripts/lint-pbxproj-test-wiring.sh ok) and run in CI.
  • swiftc probes on the reporter's Intel Mac (macOS 15.7): NSColor(Color) bridges .primary/.secondary/.opacity to appearance-aware dynamic colors with stable equality; a .colorScheme(.dark) subtree override sets darkAqua on hosted platform views while the window stays aqua.
  • No dogfood build was run on the Intel Mac for this PR at the reporter's request; the change puts the affected icons on the exact path the Vault icons (#10764) have used without regressions.

Demo Video

  • Video URL or attachment: none (no dogfood pass requested).

Review Trigger (Copy/Paste as PR comment)

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

Checklist

  • I tested the change locally (fleet build + swiftc probes; see Testing)
  • I added or updated tests for behavior changes
  • I updated docs/changelog if needed
  • I requested bot reviews after my latest commit (copy/paste block above or equivalent)
  • All code review bot comments are resolved
  • All human review comments are resolved

🤖 Generated with Claude Code

https://claude.ai/code/session_0164VYciR8F15gDbX3Cy3Tdg

Summary by CodeRabbit

  • Visual Improvements

    • Profile avatars now appear as circular images with cleaner cropping and transparent corners.
    • System icons render with more consistent tint colors across sidebars, toolbars, panels, notifications, and other interface areas.
    • Icon colors remain accurate across different appearances and interaction states.
  • Bug Fixes

    • Improved system-symbol rendering on supported macOS configurations.
    • Added a person-symbol fallback when a profile avatar cannot be displayed.