Skip to content

cmux-next: decode the backdrop painting off the main thread and fade it in - #18105

Merged
teamleaderleo merged 8 commits into
feat-cmux-nextfrom
next-launch-art-off-main
Oct 7, 2026
Merged

teamleaderleo merged 8 commits into
feat-cmux-nextfrom
next-launch-art-off-main

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

With a background painting set in cmux.json, the first window decoded the painting inside its first frame's commit, on the main thread. The wheat-field painting is 2400 x 1910 (about 18 MB decoded), and drawing it from the first frame cost that frame about 50 ms (#18087).

Now the painting decodes off the main thread and the first frame doesn't wait for it:

  • BackdropImageStore decodes each backdrop image once per process with ImageIO (kCGImageSourceShouldCacheImmediately) in a detached task, and shares the result.
  • WindowMaterialView.apply shows a decoded image at once. Otherwise it leaves the art hidden, so the window shows the theme's colors, and fades the painting in over 0.2 s when it's ready. A newer apply cancels a pending load.
  • Later windows (settings, secondary windows) take the decoded image at once.
  • BackdropArt.imageURL and BackdropSelection.imageURL give the file to decode. image() is unchanged for the wallpaper picker.

This is independent of #18087, and together they give a first frame at base speed in the cmux.json theme.

Numbers

Warm relaunches of Debug fleet builds on one capture mini: a fresh profile, a cmux.json with Apple System Colors Light and the wheat-field painting, and an agent chat in workspace 2. Values are ms since process start (first_window_frame_committed), with frames from window captures (sweep4a.py).

Build First window frame Frames
Base 391, 394, 395, 398, 416, 423 default theme, painting from about 510 ms
#18087 alone 446, 450, 471, 476 light theme and painting from the first paint
#18087 + this PR 389, 425 light theme from the first paint; the painting fading in at 297 ms and fully in by 761 ms; no black frame

The last row is a scratch build that also carries launch logging (build 8767ffae). The base's last two values (398, 416) are from the same session as that row.

Testing

Two tests in BackdropArtTests, committed red before the fix:

  • theFirstWindowsPaintingDecodesOffTheMainActorThenShows: apply shows no painting, then it shows once the load finishes.
  • aLaterWindowShowsTheDecodedPaintingAtOnce.

The existing tests that read the painting now wait for the load.

Each run used the same focused command on a fleet runner: ./scripts/ci/package-test-lane.sh suite Packages/macOS/CmuxNext <suites>.

Commit Result
f4f7af9 (red) failed: theFirstWindowsPaintingDecodesOffTheMainActorThenShows, 2 issues (the painting showed right after apply; nothing was cached)
22acdb8 (green) passed: BackdropArtTests, WindowMaterialTests, BackdropTextureTests, WindowKitTests, WindowTranslucencyTests, WindowRootMaterialTests, OneBackdropTests, WindowBackgroundLiveTests, BackdropArtSettingsTests

check-concurrency.sh and check-no-godfiles.sh --only swift pass. No user-facing strings changed, so no localization audit was needed.

Not run: a review sub-agent (lane rule: no sub-agents).

Changelog

Changed: cmux-next's background painting fades in after the first frame instead of delaying it.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Moves backdrop painting decoding off the main thread so the first window's first frame no longer waits for it; the painting now fades in over 0.2 s once ready.

  • A 2400 px painting cost the first frame about 50 ms when decoded during commit; BackdropImageStore now decodes it once per process in a detached ImageIO task and shares the result.
  • The first window shows the theme's colors until the painting is ready, then fades it in; later windows show the decoded painting immediately.
  • New imageURL properties feed the decoder; image() is unchanged for the wallpaper picker.
  • WindowMaterialView takes an injectable BackdropImageStore (default .shared) and a test await point (artLoaded()) for the pending load.

Written for commit 65f8e9a. Summary will update on new commits.

Review in cubic Turn on auto-fix


Note

Low Risk
UI/performance change in window backdrop rendering with no auth or data-path changes; main risk is transient visual behavior (fade, brief theme-only frame) or race on rapid backdrop changes, mitigated by task cancellation.

Overview
Moves backdrop painting decode off the main thread so the first window frame no longer blocks on large bundled JPEGs (~50 ms for the wheat-field asset); the window shows theme colors first, then fades the painting in over 0.2 s when decoding finishes.

Adds BackdropImageStore: a process-wide cache that decodes each selection once via ImageIO in a detached task and shares NSImage instances across windows. WindowMaterialView.apply uses cached bitmaps synchronously when available; otherwise it starts a cancellable load and updates the art layer when ready. BackdropArt / BackdropSelection expose imageURL for decoding; synchronous image() behavior for the picker is preserved.

Tests now await artLoaded() and add coverage for deferred decode vs. instant display when already cached.

Reviewed by Cursor Bugbot for commit 65f8e9a. Bugbot is set up for automated code reviews on this repo. Configure here.

teamleaderleo and others added 3 commits October 6, 2026 14:28
… main actor (red)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t in (green)

The first window's painting decoded inside its first frame's commit; a
2400 px painting cost that frame about 50 ms. BackdropImageStore now decodes
it once per process off the main actor; the window shows the theme's colors
until it is ready, then fades the painting in. Later windows take it at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 6, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: c7799fae-5665-4a6d-9858-fb8effde64b6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Not verified: macOS jobs did not run: compile and app tests were skipped on 65f8e9a372; ci-status is green without them.

CI passes on 65f8e9a372 (run 37561928143 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ade45cf. Configure here.

fade.toValue = 1
fade.duration = 0.2
return fade
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fade ignores motion-off setting

Low Severity

The painting fade is a hardcoded 0.2s CABasicAnimation and never consults Motion. When motion speed is off, MotionPolicy requires opacity changes to apply in one frame, but the backdrop still animates.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ade45cf. Configure here.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Exact-head Swift test run on 65f8e9a3728 has three reds:

  • zshCompletesCommandsFromItsOwnCommandTable() (AgentPaneShellCompletionTests.swift:49)
  • shiftCommandGIsFindPreviousInABrowser() (BrowserChromeKeysTests.swift:57)
  • withTheSidebarHiddenTheStripStartsAfterTheToggle() (StaticSidebarToggleTests.swift:95)

The first two are inherited from feat-cmux-next commits 8251d62d6a8 and 741ec540a2d; the sidebar red is also present on the base run at https://github.com/manaflow-ai/cmux/actions/runs/37559207798. Release compile, generated files, static checks, path routing, and macOS placement are green on this exact head.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

merge-override: Swift test reds are inherited base failures documented with green Release compile and generated files on this exact head

@teamleaderleo
teamleaderleo merged commit ee88da2 into feat-cmux-next Oct 7, 2026
56 of 58 checks passed
@teamleaderleo
teamleaderleo deleted the next-launch-art-off-main branch October 7, 2026 03:14
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37566149610 at bae93f9 failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 1 merged since: #18105.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37566936732 at 53a924d failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 1 merged since: #18105.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37566318678 at 10e4d81 failed: cmux-next checks (god files, concurrency, crash safety, l10n), cmux-next generated files.
Those jobs last passed at 86019f6. This pull request is one of 1 merged since: #18105.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37567938071 at f43f800 failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 3 merged since: #18105, #18198, #18165.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37567471217 at 2a1b504 failed: cmux-next checks (god files, concurrency, crash safety, l10n), cmux-next generated files.
Those jobs last passed at 86019f6. This pull request is one of 2 merged since: #18105, #18198.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37567159145 at abada68 failed: cmux-next checks (god files, concurrency, crash safety, l10n), cmux-next generated files.
Those jobs last passed at 86019f6. This pull request is one of 1 merged since: #18105.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37568316271 at 169c1da failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 3 merged since: #18105, #18198, #18165.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37568445230 at 3c11c5a failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 3 merged since: #18105, #18198, #18165.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37568512187 at e8aa5c1 failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 3 merged since: #18105, #18198, #18165.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37569422881 at 552e7cb failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 4 merged since: #18105, #18198, #18165, #18205.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37569270312 at f60b3d7 failed: cmux-next checks (god files, concurrency, crash safety, l10n), cmux-next generated files.
Those jobs last passed at 86019f6. This pull request is one of 4 merged since: #18105, #18198, #18165, #18205.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37569941713 at 46215de failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 4 merged since: #18105, #18198, #18165, #18205.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37569551101 at 5976099 failed: cmux-next checks (god files, concurrency, crash safety, l10n), cmux-next generated files.
Those jobs last passed at 86019f6. This pull request is one of 4 merged since: #18105, #18198, #18165, #18205.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/37570246034 at e8a5696 failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at 86019f6. This pull request is one of 5 merged since: #18105, #18203, #18198, #18165, #18205.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

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.

1 participant