Skip to content

Fix macOS 27 SF Symbol rasterization crash - #5999

Merged
austinywang merged 4 commits into
mainfrom
issue-5841-macos27-sfsymbol-crash
Jun 13, 2026
Merged

austinywang merged 4 commits into
mainfrom
issue-5841-macos27-sfsymbol-crash

Conversation

@austinywang

@austinywang austinywang commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add a shared Image.cmuxSymbolRasterSize guard that clamps SF Symbol raster frames to at least 1pt and sizes symbols with resizable().scaledToFit().frame(...) instead of transient font metrics
  • apply the guard to the browser toolbar dev-tools surface that crashes on wrench.and.screwdriver, plus related browser toolbar/profile/theme icons, sidebar Help/metadata icons, right-sidebar header icons, and titlebar/update accessory icons
  • keep the Fix launch crash on macOS 27 from zero-size SF Symbol rasterization #5670 sidebar Help fix on the same guarded path so future small-symbol sites can opt into the same raster sizing behavior

Root cause

macOS 27 / CoreUI can reject SwiftUI SF Symbol rasterization when a font-sized symbol is laid out during a transient pre-visible/window layout pass and the target size collapses to 0x0. #5841 captured this for wrench.and.screwdriver in the browser toolbar after cmd-clicking a terminal link. #5890 reports the same CoreUI/SwiftUI vector glyph throw during initial main-window bootstrap.

This follows the #5670 precedent: use explicit positive symbol frames rather than relying on font metrics during those layout passes.

Reproduction

I did not fake a local repro: this machine is not on macOS 27, and the available evidence is the lldb/crash-report data in #5841 and #5890.

Tests

  • Added symbolRasterPointSizeClampsZeroAndNegativeInputs in the existing wired WorkspaceGroupTests.swift suite.
  • Not run locally per instruction; CI is the validation gate.

Fixes #5841
Fixes #5890
Refs #5670


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Prevents SF Symbol rasterization crashes on macOS 27 by clamping symbol sizes to at least 1 pt and sizing with explicit frames. Uses Image.cmuxSymbolRasterSize(...) across the app to avoid 0×0 pre-layout sizes.

Written for commit 046cecc. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Refactor

    • Standardized symbol icon rendering across browser panels, sidebars, and titlebar accessories using a unified sizing and weight approach.
  • Tests

    • Added test coverage for symbol size point clamping edge cases.

@vercel

vercel Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 12, 2026 10:13pm
cmux-staging Building Building Preview, Comment Jun 12, 2026 10:13pm

@coderabbitai

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR replaces font-based SF Symbol sizing with an explicit Image.cmuxSymbolRasterSize helper that clamps raster point sizes to a minimum (1pt) and renders symbols via resizable+scaledToFit frames to avoid zero-size rasterization on macOS 27.

Changes

Symbol Raster Size Migration via cmuxSymbolRasterSize

Layer / File(s) Summary
Core raster sizing helper and clamping logic
Sources/RenderableSystemSymbol.swift, cmuxTests/WorkspaceGroupTests.swift
RenderableSystemSymbol.clampedRasterPointSize(_:) enforces minimum finite raster sizes, and Image.cmuxSymbolRasterSize(_:weight:alignment:) creates resizable, scaled-to-fit symbol images with explicit frames. New test validates clamping for zero, negative, and positive inputs.
Browser panel toolbar and omnibar icon sizing
Sources/Panels/BrowserPanelView.swift
Multiple toolbar and omnibar icons (navigation, reload/stop, screenshot, focus, React Grab, DevTools, profile, theme, import hint, popover checkmarks, secure badge) switch from .font(.system(...)) to .cmuxSymbolRasterSize(...). Moves cmuxFlatSymbolColorRendering() to an Image extension.
Icon sizing in ContentView, sidebars, and update accessories
Sources/ContentView.swift, Sources/RightSidebarChromeStyle.swift, Sources/RightSidebarPanelView.swift, Sources/Update/UpdateTitlebarAccessory.swift
Applies .cmuxSymbolRasterSize(...) for the question icon and symbol helper, header chrome icons/button style, sidebar open/close header icons, and titlebar/notification icons in the update accessory.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • manaflow-ai/cmux#5670: Addresses the same zero-size SF Symbol rasterization crash by sizing symbols with explicit frames; closely related and overlapping at ContentView symbol sites.
  • manaflow-ai/cmux#5464: Also modifies BrowserPanelView icon sizing and metrics; overlaps with this PR's omnibar/toolbar changes.
  • manaflow-ai/cmux#5037: Extended RenderableSystemSymbol previously with symbol normalization/fallbacks; this PR adds clamping and raster-size rendering helper in the same module.

Poem

🐰
I nibble code at morning light,
Clamp tiny sizes, set them right.
Symbols render, no more fright,
Frames keep pixels warm and bright. ✨

🚥 Pre-merge checks | ✅ 20 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (20 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix macOS 27 SF Symbol rasterization crash' directly and clearly summarizes the primary change: addressing a macOS 27 crash caused by SF Symbol rasterization at zero-size frames.
Linked Issues check ✅ Passed The PR fully addresses both #5841 and #5890 by implementing the proposed fix: introducing Image.cmuxSymbolRasterSize that uses explicit positive frames (resizable().scaledToFit().frame(...)) with clamping to prevent zero-size SF Symbol rasterization crashes across multiple UI surfaces.
Out of Scope Changes check ✅ Passed All changes are within scope: the PR introduces a shared clamping helper, applies it to browser toolbar/profile/theme icons, sidebar Help/metadata icons, right-sidebar headers, and titlebar icons as specified in #5841, and maintains consistency with the #5670 sidebar fix.
Cmux Swift Actor Isolation ✅ Passed Added cmuxSymbolRasterSize + clampedRasterPointSize for SF Symbol frames; no new async/background UI access, Sendable/shared mutable references, or misplaced @MainActor/MainActor-by-default isolation.
Cmux Swift Blocking Runtime ✅ Passed PR #5999 diff only adds clampedRasterPointSize + Image.cmuxSymbolRasterSize (resizable/scaledToFit/frame) and a DEBUG cache reset; no sleeps/waits/semaphores/NSLock/DispatchQueue.main.sync introduced.
Cmux Expensive Synchronous Load ✅ Passed PR-related Swift files only change SF Symbol raster sizing; no diff evidence of adding/moving RestorableAgentSessionIndex.load() sync calls onto main/interactive paths (no SharedLiveAgentIndex.sh...
Cmux Cache Substitution Correctness ✅ Passed PR #5999 only adjusts SwiftUI SF Symbol raster sizing (adds Image.cmuxSymbolRasterSize + clampedRasterPointSize test); diff shows no persistence/history/undo/snapshot cache substitutions.
Cmux No Hacky Sleeps ✅ Passed PR #5999 only changes 7 Swift files (.swift filter in GitHub diff) and the diff contains no sleep()/setTimeout/setInterval, so runtime-no-hacky-sleeps rules aren’t violated.
Cmux Algorithmic Complexity ✅ Passed PR changes only SwiftUI SF Symbol raster sizing: RenderableSystemSymbol.clampedRasterPointSize uses constant max/min/isFinite and cmuxSymbolRasterSize builds a resizable frame—no loops, scans, sort...
Cmux Swift Concurrency ✅ Passed PR #5999 changes only SwiftUI SF Symbol raster sizing/clamping; searched the PR diff for legacy async markers (DispatchQueue/Task/Combine/completion) and found none.
Cmux Swift @Concurrent ✅ Passed Reviewed PR-mentioned Swift changes (RenderableSystemSymbol.swift, etc.) for @concurrent and “nonisolated async”; none found. New symbol raster helpers are synchronous.
Cmux Swift File And Package Boundaries ✅ Passed RenderableSystemSymbol.swift is a small, focused UI symbol-rendering helper (82 lines; only AppKit/SwiftUI imports) adding clampedRasterPointSize and Image.cmuxSymbolRasterSize; other changes are i...
Cmux Swift Logging ✅ Passed PR #5999 diff contains no occurrences of print/debugPrint/dump/NSLog/Logger (checked via full-page searches on the GitHub “Files changed” view).
Cmux User-Facing Error Privacy ✅ Passed Scanned the PR’s listed files for user-facing alert/error/recovery copy (Text/NSAlert); only generic, localized messages appear. Changes are symbol raster sizing + clamping, no sensitive vendor/pro...
Cmux Full Internationalization ✅ Passed PR #5999 diff only updates SwiftUI SF Symbol raster sizing and a test; no new unlocalized user-facing Swift text—Text uses String(localized:defaultValue:) (e.g., browser.import.hint.toolbar, notifi...
Cmux Swiftui State Layout ✅ Passed PR #5999 only adds Image/enum helpers to clamp SF Symbol raster frames and reapplies sizing; no new @Observable/@Published/@State, GeometryReader, Lazy/List/ForEach store refs, or render-time state...
Cmux Architecture Rethink ✅ Passed Inspectable changes add Image.cmuxSymbolRasterSize + clampedRasterPointSize using resizable().scaledToFit().frame, with no sleeps/polling/locks/observers/extra entrypoints added; test covers 0/nega...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed Affected Swift files only change SF Symbol raster sizing; none add user-visible NSWindow/NSPanel/WindowGroup declarations or .identifier = NSUserInterfaceItemIdentifier("cmux...) that lint_auxili...
Cmux Source Artifacts ✅ Passed git diff main..HEAD shows only 7 modified Swift source/test files; none are logs/caches/build output or reside in forbidden scratch/DerivedData-style paths per source-control-artifacts rules.
Description check ✅ Passed Pull request description comprehensively covers summary, root cause, testing approach, and fixed issues, with all key template sections present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-5841-macos27-sfsymbol-crash

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Introduces a shared Image.cmuxSymbolRasterSize(_:weight:) guard that clamps SF Symbol raster frames to a minimum of 1 pt and sizes symbols via resizable().scaledToFit().frame(...) instead of transient font metrics, preventing the macOS 27 CoreUI crash triggered when a symbol is rasterized during a pre-visible layout pass at 0×0.

  • RenderableSystemSymbol.clampedRasterPointSize handles all degenerate inputs (zero, negative, NaN, ±infinity) and is tested by the new RenderableSystemSymbolTests suite covering the full contract.
  • Browser toolbar, sidebar Help/metadata, right-sidebar header, and titlebar/notification icons are all migrated from .font(.system(size:weight:)) to cmuxSymbolRasterSize, consistently eliminating the crash-prone pattern across every identified surface.
  • cmuxFlatSymbolColorRendering is narrowed from a View extension to an Image extension (safe at all call sites because Image.symbolRenderingMode(_:) returns Image), and HeaderChromeIconStyle.symbol() is added to centralize right-sidebar header icon construction so the button style no longer needs to own sizing.

Confidence Score: 5/5

Safe to merge — the change is a targeted, well-tested rasterization guard with no production logic side-effects beyond symbol frame sizing.

The clamping logic is straightforward and fully covered by the new test suite (zero, negative, NaN, ±infinity). All identified crash-path call sites are migrated to the new helper. The narrowing of cmuxFlatSymbolColorRendering to an Image extension is correct at every call site because the preceding Image.symbolRenderingMode(_:) returns Image. The HeaderChromeIconStyle.symbol() factory accounts for all current callers of RightSidebarHeaderIconButtonStyle. No actor isolation, concurrency, or state mutation concerns are introduced.

No files require special attention.

Important Files Changed

Filename Overview
Sources/RenderableSystemSymbol.swift Adds clampedRasterPointSize (guards against zero, negative, NaN, and ±infinity) and Image.cmuxSymbolRasterSize extension using resizable+scaledToFit+frame. Implementation is correct and well-guarded.
Sources/Panels/BrowserPanelView.swift Replaces all .font(.system(size:weight:)) calls with cmuxSymbolRasterSize across navigation, dev-tools, profile/theme, secure badge, and import icons. Also narrows cmuxFlatSymbolColorRendering from View to Image extension, which is safe given call-site ordering (symbolRenderingMode returns Image).
Sources/RightSidebarChromeStyle.swift Adds HeaderChromeIconStyle.symbol() factory that calls cmuxSymbolRasterSize, and removes .font() from RightSidebarHeaderIconButtonStyleBody. Both callers in RightSidebarPanelView were updated; no unguarded callers remain in the visible diff.
Sources/RightSidebarPanelView.swift Header icon buttons updated to use HeaderChromeIconStyle.symbol(). ModeBarButton mode-tab icons still use .font(), but are on a visibly-mounted layout path, not the pre-visible crash path targeted by this fix.
Sources/Update/UpdateTitlebarAccessory.swift TitlebarControlsView icon and NotificationsPopoverView icons migrated to cmuxSymbolRasterSize. Covers the window-bootstrap crash path noted in #5890.
cmuxTests/RenderableSystemSymbolTests.swift New Swift Testing suite pins the full clamping contract: zero, negative, normal positive, NaN, +infinity, and -infinity inputs all verified. Correctly uses @testable import conditional on module name.
cmux.xcodeproj/project.pbxproj Adds RenderableSystemSymbolTests.swift to the test target with a new PBX file/build reference. Mechanical change; no issues.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Image(systemName:)"] --> B["cmuxSymbolRasterSize(pointSize, weight)"]
    B --> C["clampedRasterPointSize(pointSize)"]
    C --> D{isFinite?}
    D -- No --> E["return 1 (minimumRasterPointSize)"]
    D -- Yes --> F["max(1, pointSize)"]
    E --> G["rasterSize ≥ 1 pt"]
    F --> G
    G --> H[".resizable()"]
    H --> I[".scaledToFit()"]
    I --> J[".fontWeight(weight)"]
    J --> K[".frame(rasterSize × rasterSize)"]
    K --> L["Safe SwiftUI View — no 0×0 raster"]

    style E fill:#f9f,stroke:#c33
    style F fill:#9f9,stroke:#393
    style L fill:#9cf,stroke:#369
Loading

Reviews (3): Last reviewed commit: "fix: address SF Symbol review feedback" | Re-trigger Greptile

Comment thread cmuxTests/WorkspaceGroupTests.swift Outdated
Comment thread cmuxTests/WorkspaceGroupTests.swift
@austinywang
austinywang merged commit 5d79094 into main Jun 13, 2026
24 checks passed
hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request Jun 14, 2026
PRs included:
- AppDelegate decomposition: CmuxSession session-snapshot repository (manaflow-ai#6030)
- Fix Cmd+T cwd after session restore (manaflow-ai#6055)
- Speed up iOS terminal scroll rendering (manaflow-ai#6035)
- Preserve Pi sessions across workspace restore (manaflow-ai#5607)
- Scope Biome checks to maintained JS sources (manaflow-ai#6008)
- Fix manaflow-ai#5917: restore OSC 11 pane-local backgrounds (manaflow-ai#5997)
- Expose stable window title templates (manaflow-ai#6059)
- Honor macos-option-as-alt left/right
- Fix macOS 27 SF Symbol rasterization crash (manaflow-ai#5999)
- CmuxRemote* family: extract Workspace remote/cloud-VM connectivity
- Fix iOS workspace swipe-delete confirmation crash (manaflow-ai#6051)
- TabManager decomposition Wave 3+4 sub-models
- Sidebar row cleanups: branchless frame anchor
- CmuxIPCService: extract AppDelegate multi-window CLI routing
- CmuxSidebarGit: extract TabManager git-metadata + PR-polling subsystem
- CmuxTerminalCore: extract terminal core leaf

Fork-side adjustments:
- ghostty submodule: cherry-pick mouse-modifier-state fix onto our renderer-realized branch
- Workspace.swift: take theirs (upstream extracted ~7700 lines into CmuxCore.Remote/CmuxRemoteSession packages); restore fork's renameTopLevelLayoutTabContaining/closeTopLevelLayoutTabContaining + surfaceTmuxClientTTYNames + WorkspaceLayoutTab integration
- TabManager.swift: take theirs; re-add static allocatePortOrdinal()
- BrowserPanelView, RenderableSystemSymbol: keep fork's cmuxSymbolPixelSize extension on top of upstream's cmuxSymbolRasterSize
- Add CmuxWorkspaces / CMUXSessionDaemon / CmuxCommandPalette imports to TerminalController, Workspace, SessionPersistence
- Sources/Workspace+P43Stubs.swift: thin shims for SplitEqualizer, WorkspaceRemoteSessionController.PortScanKickReason, WorkspaceGroupNewWorkspacePlacementSettings (legacy types fork TC still calls; replace with package APIs in P44+)
- Sources/GhosttySurfaceSizeDeferralReason.swift: restore fork-only enum (deleted by upstream)
- Sources/StableLayout/SessionBlueprintExportAction.swift: parked debug action (depends on legacy SessionPersistenceStore, gone)
- Sources/GhosttyTerminalView.swift: stub ghostty_surface_select_cursor_line_compat (needs zig 0.15.2 xcframework rebuild)
- pbxproj: keep-both, drop stale ProcessPipeReader/SplitEqualizer/Panels/BrowserProxyEndpoint refs, fix SurfaceHibernationPolicy UUID collision
- Drop fork's WorkspaceRemoteConfiguration.swift + WorkspaceRemoteSSHBatchCommandBuilder.swift (extracted to CmuxCore package)
@austinywang austinywang mentioned this pull request Jun 15, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — 046cecca Deployed Jun 12, 2026 by vercel[bot]
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.

Do not work on MacOS 27 Crash on macOS 27 when cmd-clicking a link (browser toolbar SF Symbol rasterized at 0×0)

1 participant