Skip to content

Fix titlebar SF Symbol raster sizing - #7074

Merged
austinywang merged 3 commits into
mainfrom
issue-7073-titlebar-icon-size
Jun 30, 2026
Merged

austinywang merged 3 commits into
mainfrom
issue-7073-titlebar-icon-size

Conversation

@austinywang

@austinywang austinywang commented Jun 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #7073.

Restores the requested square raster frame for AppKit-backed SF Symbols. The regression came from the CmuxSystemSymbolImage migration in d4342fbaec / #6728: titlebar callers still requested the same 12pt icon size, but RenderableSystemSymbol.configuredAppKitImage aspect-fit the configured AppKit image so non-square symbols rendered with a smaller intrinsic image inside the unchanged titlebar chrome.

Reproduction / confirmation

Confirmed from code and history rather than launching local builds, per the no-build/no-local-test constraint:

  • v0.64.17 rendered top-left titlebar symbols with Image(systemName: ...).symbolRenderingMode(.monochrome).cmuxSymbolRasterSize(config.iconSize, weight: ...).
  • cmuxSymbolRasterSize applied a system font at the requested point size and a fixed square frame.
  • Current main uses CmuxSystemSymbolImage(systemName: ..., pointSize: config.iconSize, weight: ...).
  • The AppKit path configured the symbol at the requested point size, then changed NSImage.size through fittedSymbolSize(..., maximumDimension: rasterSize), shrinking the intrinsic image for non-square symbols while the titlebar button/frame metrics stayed unchanged.

Observed from the code path: requested titlebar metrics remained 20pt buttons / 12pt icons, but the rendered image size was reduced for non-square symbols. Expected: AppKit-backed symbol rendering should preserve the requested square raster frame so the visible chrome matches the pre-regression sizing behavior.

Fix boundary

The fix belongs in RenderableSystemSymbol, not the titlebar callsite. The titlebar already passes the correct metric; the abstraction changed the meaning of pointSize when it aspect-fit the configured AppKit image. Keeping the AppKit image creation/cache preserves the macOS 27 crash fix, while removing the extra shrink restores the old cmuxSymbolRasterSize sizing contract for all callers that ask for a concrete symbol point size. Global font magnification remains opt-in through the existing appliesGlobalFontMagnification path.

Tests

  • Added a focused regression assertion in RenderableSystemSymbolTests that a non-square AppKit symbol keeps the requested square raster frame.
  • First commit is test-only and should fail against the previous aspect-fit behavior; second commit applies the fix.
  • Local tests/builds were not run, per instruction. CI is the validation path.

Localization

No user-facing strings changed, so no localization catalog updates were needed.


Summary by cubic

Fix titlebar SF Symbol sizing by removing extra aspect-fit scaling for AppKit images so non-square symbols render at their configured size and aspect ratio, restoring the pre-migration look. Closes #7073.

  • Bug Fixes
    • Stop downscaling AppKit symbols to a square raster; keep the configured dimensions and aspect ratio, with a square fallback only when the configured size is invalid.

Written for commit 2dac51a. Summary will update on new commits.

Review in cubic

@vercel

vercel Bot commented Jun 30, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cmux Canceled Canceled Jun 30, 2026 2:39am
cmux-staging Building Building Preview, Comment Jun 30, 2026 2:39am

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@austinywang, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e0a059b1-1fc1-423e-a4ba-ba1881794c0f

📥 Commits

Reviewing files that changed from the base of the PR and between 6011d04 and 2105c8c.

📒 Files selected for processing (2)
  • Sources/RenderableSystemSymbol.swift
  • cmuxTests/RenderableSystemSymbolTests.swift
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-7073-titlebar-icon-size

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.

@greptile-apps

greptile-apps Bot commented Jun 30, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes a sizing regression introduced by the CmuxSystemSymbolImage migration: non-square SF Symbols in the titlebar were being aspect-fit down to a smaller intrinsic size by fittedSymbolSize, causing them to appear too small inside the unchanged 16×16 layout frame.

  • Bug fix in RenderableSystemSymbol.configuredAppKitImage: replaces fittedSymbolSize (which scaled the longer dimension to rasterSize) with symbolImageSize, which returns AppKit's natural configured size directly and only falls back to a square at rasterSize for invalid/zero input.
  • Test update: renames and rewrites the regression test to verify that a non-square symbol (arrow.left.and.right) preserves AppKit's configured size rather than being scaled down; unit test for the helper function is updated to match the new pass-through semantics.

Confidence Score: 5/5

Safe to merge — the change is a well-scoped, one-line fix in a non-concurrent image-sizing helper, and the test target explicitly validates the before/after behavior on a known non-square symbol.

The logic change is minimal and easy to reason about: one aspect-fit computation is replaced with a direct size pass-through, keeping the existing guard for degenerate inputs. The helper function is pure and isolated; the cache layer, actor isolation, and fallback path are all untouched. The regression test added in the same PR directly exercises the corrected code path and would have failed against the previous behavior, giving clear CI coverage for the invariant being restored.

No files require special attention.

Important Files Changed

Filename Overview
Sources/RenderableSystemSymbol.swift Replaces aspect-fit sizing (fittedSymbolSize) with a pass-through helper (symbolImageSize) that returns AppKit's natural configured size; invalid/zero sizes still fall back to a square at rasterSize.
cmuxTests/RenderableSystemSymbolTests.swift Updates unit tests to match the new symbolImageSize contract; adds a focused regression test confirming a non-square symbol preserves AppKit's configured size rather than being scaled down.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["configuredAppKitImage(systemName:pointSize:weight:)"] --> B["clampedRasterPointSize(pointSize) → rasterSize"]
    B --> C{Cache hit?}
    C -- Yes --> D["return cached NSImage"]
    C -- No --> E["NSImage(systemSymbolName:)"]
    E --> F["SymbolConfiguration(pointSize: rasterSize, weight:)"]
    F --> G["baseImage.withSymbolConfiguration(configuration)"]
    G --> H["symbolImageSize(configuredImage.size, fallbackDimension: rasterSize)"]
    H --> I{naturalSize valid?}
    I -- "width/height > 0 and finite" --> J["return naturalSize (AppKit's configured size)"]
    I -- "invalid / zero / NaN" --> K["return NSSize(fallbackDimension × fallbackDimension)"]
    J --> L["image.size = result"]
    K --> L
    L --> M["cache & return image"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["configuredAppKitImage(systemName:pointSize:weight:)"] --> B["clampedRasterPointSize(pointSize) → rasterSize"]
    B --> C{Cache hit?}
    C -- Yes --> D["return cached NSImage"]
    C -- No --> E["NSImage(systemSymbolName:)"]
    E --> F["SymbolConfiguration(pointSize: rasterSize, weight:)"]
    F --> G["baseImage.withSymbolConfiguration(configuration)"]
    G --> H["symbolImageSize(configuredImage.size, fallbackDimension: rasterSize)"]
    H --> I{naturalSize valid?}
    I -- "width/height > 0 and finite" --> J["return naturalSize (AppKit's configured size)"]
    I -- "invalid / zero / NaN" --> K["return NSSize(fallbackDimension × fallbackDimension)"]
    J --> L["image.size = result"]
    K --> L
    L --> M["cache & return image"]
Loading

Reviews (2): Last reviewed commit: "Preserve AppKit symbol aspect ratio" | Re-trigger Greptile

@austinywang
austinywang merged commit e3c4357 into main Jun 30, 2026
29 checks passed

This branch was successfully deployed

1 active deployment
Preview – cmux — 2dac51a3 Deployed Jun 30, 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.

Regression: top-left titlebar icons render smaller after 0.64.17

1 participant