Skip to content

cmux-next: backgrounds batch: collages, every Apple aerial, video playback and Chief picture motion settings - #22033

Closed
teamleaderleo wants to merge 152 commits into
feat-cmux-nextfrom
leo/next-backgrounds-batch
Closed

teamleaderleo wants to merge 152 commits into
feat-cmux-nextfrom
leo/next-backgrounds-batch

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

A reduced backgrounds batch for cmux-next. It carries:

Dropped, and why

Their settings, strings in every locale, ops, web UI and tests are gone. #22562 (merged into feat-cmux-next today) made the background aspect-fill the window, centered, with no framing logic, and deleted BackdropArtPlacement.swift, the visible-span math, the blurred fill and the pane-column reports, because framing made the picture jump while resizing. Both dropped features were built on that framing, so this PR follows #22562 and brings none of it back: WindowMaterialView.swift is base's version unchanged, and base's art blur (#22566) and one-background-or-shuffle (#22577, including Shuffle a Folder) stay as they are.

The string catalogs are base plus only the strings this batch uses (additions only). docs/mdm/com.manaflow.cmux.json and schemas/defaults/cmux-next.json are base's; the PR autofix regenerates them.

Changelog

  • Added: Collages: arrange several pictures as one window background.
  • Added: Every Apple aerial is offered as a background; ones not downloaded open the Wallpaper pane.
  • Added: Settings for when a video background plays and whether it plays on battery, and for when a Chief's animated picture moves.

Testing

  • Red-then-green: BackdropCollagesTests.oneUnreadablePictureRefusesTheCollage and the new cases in BackdropImagesPageProviderTests.collagesSaveReadAndDelete are committed before the fix (f1d71c9), the fix is 0f0b9d8.

  • Fleet compile of CmuxNext with its tests and the app on the head (cmux-ci compile-check --package CmuxNext --app).

  • webviews: bun run check, bun test src/pages/settings (216 pass), scripts/web-lint.sh, scripts/cmux-next/prepush-gate.py.

  • Base merges: feat-cmux-next 056118f (conflict only in WebTheme.swift: base's workingLook / data-working-look and this PR's pictureMotion / data-picture-motion both kept), b857e19 (SettingsPageLayout.swift: base moved Chief Chat to the new Chief page, so the Chief Pictures group moves there with it; PageFactory.swift: base's side), then clean merges of 855674f, f7a4033, 74b91c1 and 4af74be. CmuxNextSettings/Localizable.xcstrings is base's text plus this PR's 12 keys (an earlier merge had reordered the whole file).

  • Settings exports and the defaults snapshot come from the PR autofix's pr-autofix-patch artifact (runs 39614862117 and 39653863256), applied as chore(next): PR autofix commits; the push job does not run on pull_request events.

  • Localization: Collage (da/de/es/fr/it/nb) and Name (de) are documented identities in scripts/localization-allowed-omissions.json; python3 scripts/localization_catalog.py check no longer reports these catalogs.

  • test/home-chief-picture-motion.test.tsx yields a turn instead of a 20 ms fixed wait (check:fixed-waits); bun test of it and of src/pages/settings pass (241 pass, 1 skip).

  • Fleet cmux-ci compile-check --app passed on e7c20a5, dd95462, cacbf8a, 63922e9, 4c2e4e0, 12703f0, 483b195 and 0244c52.

No capture: the visible changes are Settings web page rows and the collage editor (the gallery advisory run renders the settings page) and backdrop behavior (video playback, battery pause, picture motion), not new native chrome.

Observed / Not run

  • Observed: the checks above on huge-blue and the fleet; CI on the head.
  • Not run this pass: local bun run check / scripts/web-lint.sh (refused on cosmic-gray); CI's web lint ran them and passed (fast gates).
  • Not run: no live dogfood of a collage or an aerial in a tagged build in this pass.

Replaces the separate PRs #21746, #21789 and #21784 (their kept content lands here). #21743's hand placement is dropped as above.

🤖 Generated with Claude Code

Agent session: cosmic-gray

teamleaderleo and others added 30 commits October 18, 2026 14:55
…t chat

Every wide painting framed the same fixed point (0.5, 0.45), so with the sidebar
and a docked agent chat open the subject often sat under them, and wide or short
windows cut faces off. Each work now names its subject box in art/manifest.json,
and the art zooms, slides or shrinks (over a blurred fill) so that box lies in the
part of the window the columns leave visible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…out, not the App

CmuxNextApp may not grow (check-app-size). The sidebar and each workspace's
layout root now tell the window's backdrop where they cover the art
(WindowMaterialView.setCover), and the App is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…of sight

The first frame now fades in over the poster instead of cutting. A video no
one can see (hidden, minimized, covered, screens asleep) for a minute drops
its items, freeing the decoder and frame buffers, and resumes at the frame it
held when seen again. A video held for Low Power Mode or Reduce Motion is
still on screen and keeps its frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Settings > Background gets Add from a Link (https only, judged by its bytes,
50 MB image / 500 MB video caps), a remove button on each of your images (not
the one in use), what they take on disk, and Show in Finder. A picked, dropped
or linked file must decode or play before it is copied in. Dropping a file on
Settings no longer needs experimental appearance (the page already said to).
The ops live in BackdropImagesPageProvider (CmuxNextPages); CmuxNextApp shrinks.

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

Chief sheet: a still is placed in the circle (drag, zoom) and drawn at 512 px,
so a photo of any size fits the daemon's 1 MB; a GIF goes as it is, keeping its
motion; Use Default Picture clears it (chief.profile.avatar.set clear).
Chief Settings (the default Chief): Choose Picture… and Use Default Picture;
GIF and WebP pictures now show in the header and tile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r edge correctly

Review fixes for the subject crop:
- keepsSubject is measured on the final placement, never assumed.
- A shrunk or slid image keeps the subject in the span first (the cover clamp
  overrode it), and the shrink fit counts the subject's height too.
- No vertical fallback that cannot fail; portrait subjects are the head and
  upper body (top 70%%), which fit a 21:9 window.
- The catalog test asserts the subject frame lies in the visible span.
- Only a column that comes or goes springs the art; resizes and live window
  resizes move it at once. Fill filters are made per view.

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

Review fixes: the seek after a decoder release waits for the new item to be
ready (a seek sent before then can be dropped or undone by the looper) and uses
zero tolerance both ways, not the next keyframe. The players take their clock,
so the release deadline test steps a manual clock; the restore test checks the
time it came back at.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eir name in their folder

Review fixes for Add from a Link:
- The link's name is sanitized (no folders, colons or leading dots), and the
  renamed file must stay in the download's own folder (an encoded ../ climbed out).
- A delegate-driven data task replaces download(from:delegate:), whose task
  delegate never saw progress: the declared length and the running count are
  checked against the cap for the declared type, so a huge body never lands.
- Redirects off https are refused; timeouts are a minute idle, ten in all.
- The temporary folder is removed on every failure.
- Remove refuses the background in use natively, not just on the page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-ups to the Chief picture placement:
- A still's bytes and pixels (at most 50 megapixels) are checked before its
  preview decodes, and the drawing decodes it already scaled to the square.
- A GIF is capped at 1 MB on both sides (the daemon's cap), not 5 MB natively.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Settings > Background > Adjust Placement… fades the window's content and puts
an overlay over it: drag moves the picture, scroll or pinch zooms (1x-4x),
Reset goes back to the automatic subject framing, Done or Escape ends. The
placement (the point at the middle of the visible span, and the zoom) is kept
per background in background-placement.json, and every window follows it.
It starts from the framing on screen, so the first drag does not jump.
CmuxNextApp is unchanged: the op rides BackdropImagesPageProvider.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…me test holds still

Re-review fixes: the entry is stored before the readiness observation, so an
item already ready (reported inline) seeks and clears its pending restore
instead of leaving it set. The resume test restores while held in Low Power,
so a restart from 0 cannot reach the mark by playing; it checks 0.95-1.05 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…re they start

Re-review fixes: LinkDownload keeps its state in a Mutex and is plainly
Sendable (no new unchecked conformance for the crash ratchet). A cancel that
comes before the task exists marks the download, and the task is cancelled as
soon as it is made, instead of invalidating the session first (making a task
on an invalidated session raises). A body that starts like a picture gets the
picture cap whatever type the server declared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eep clear of panes)

appearance.backgroundVideo = play | whenActive | still (play),
appearance.backgroundVideoOnBattery = play | pause (play) and
appearance.backgroundAvoidPanes (on): Settings rows under Window Background,
agent-settable, parsed into DesignSettings.backdropPlayback by the applier.
Still Picture never plays and gives its decoder back; Only While cmux Is
Active follows the app; Pause watches the power source (IOKit). Turning
Keep Paintings Clear of Panes off frames art in the whole window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
home.chiefPictureMotion = always | hover | never (hover), a Home row and
agent-settable; Reduce Motion always holds pictures still. Pages get it as
data-picture-motion on <html> with the theme: a GIF or animated WebP avatar
shows its drawn first frame, and moves only always or while pointed at. The
native header shows the first frame unless Always. The sidebar tile is always
a still square copy, so a non-square GIF is no longer stretched there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ace window, saved in order

Review fixes for Adjust Placement:
- Compile: the store notification's object is compared by identity (the batch
  Swift run stopped on 'sending store risks causing data races').
- Saves run on one serial queue, in order; an unreadable file is kept beside.
- The overlay opens in the workspace window (WindowManager.active), never the
  Settings window; one at a time app-wide; it ends when its window shows
  another background, and fades views added while it is open.
- Keyboard: arrows nudge (Shift: further), + and - zoom, 0 resets.
- A drag past an edge has no dead travel; windows only re-place for their own
  background's change; removing a picture drops its placement; the page's
  'no picture' note clears when the background changes.
- init(coder:) returns nil instead of fatalError (crash ratchet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ace-background

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextDesign/BackdropArtPlacement.swift
#	Packages/macOS/CmuxNext/Sources/CmuxNextDesign/WindowMaterialView.swift
#	Packages/macOS/CmuxNext/Tests/CmuxNextDesignTests/BackdropArtPlacementTests.swift
…leo/next-background-settings

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextDesign/BackdropVideoView.swift
…stores its setting

Review fixes: IOPSGetProvidingPowerSourceType follows the Get rule, so its
string is taken unretained (taking it retained over-released it). The framing
test puts appearance.backgroundAvoidPanes back whatever happens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…en the Wallpaper pane

The picker listed only the aerials idleassetsd had already downloaded. Now every
aerial in entries.json is a moving wallpaper: one not on disk is named by the
file idleassetsd will write, marked not downloaded, and drawn as a cloud tile
that opens System Settings > Wallpaper (as a not-downloaded Apple still does),
where macOS downloads it. cmux never downloads Apple's files itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
appearance.background takes collage:<id>, a collage saved as
Backgrounds/Collages/<id>.json and drawn at 3200x2000 to <id>.png, which the
window shows like any picture. Settings > Background > New Collage… opens an
editor: add pictures from the grid, drag to move, drag the corner handle to
resize (edges snap to halves and thirds), arrows nudge, layer order, rounded
corners, a fill color and a name, starter layouts (side by side, three
columns, mosaic). Saving draws it natively and makes it the background; your
collages can be edited (a new id each save) or removed (never the one in use).
The page ops ride BackdropImagesPageProvider; CmuxNextApp is unchanged.
Still pictures only for now; video layers are a follow-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dow comes forward

Re-review fix: the center's clamp had its bounds swapped, so for art that
covers the window every drag or arrow pinned it to an edge. The bounds are
now [middle / size, (middle - view + size) / size], and the test checks the
exact travel of a drag and the stop at the edge. Placing brings the target
window forward again, so from a separate Settings window keys reach it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… their motion

Re-review fixes: MessagesLab's header redraws the picture into its clipped
disc, where a GIF cannot move, so the native header always shows the first
frame and home.chiefPictureMotion governs the Home pages' pictures (which also
drops the Reduce Motion observer that viewDidMoveToWindow cleared). A square
GIF tile is kept as is again; only a non-square one gets a still square copy.
The page's still-frame cache keeps at most 64.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… read once

Re-review fixes: an aerial id names a file, so only letters, digits and dashes
are kept (an id like ../../x was joined into a path outside Customer). The file
is parsed once per modification time instead of once or twice per row, and
each asset on its own, so one without an id or a name drops only itself.

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

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Default changes

This pull request changes 3 defaults at 68dd4f422726 (what everyone gets without configuring anything):

  • setting.appearance.backgroundVideo: (none) -> "play"
  • setting.appearance.backgroundVideoOnBattery: (none) -> "play"
  • setting.home.chiefPictureMotion: (none) -> "hover"

Needs a call. It passes only with an approving review on this commit from @lawrencecchen or @austinywang (the call owners in .github/defaults-call-owners.json, never the author). The needs a call label alone does not pass, and a new push needs a new approval.

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next crash-class rules / cmux-next crash-class rules is red on 9 of 9 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next guards / cmux-next localization debt ratchet is red on 17 of 18 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

Applies the pr-autofix-patch artifact of run 39653863256 on 47af3f2:
the regenerated settings exports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-af2e-7471-8e77-d62753886e4f&host=cosmic-gray
…keep them

The localization debt ratchet counts a translation equal to English; these are the
standard nouns (Collage in da/de/es/fr/it/nb, Name in de), so they are documented
identities instead of new debt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-af2e-7471-8e77-d62753886e4f&host=cosmic-gray
Keeps both sides of scripts/localization-allowed-omissions.json and rebuilds the
CmuxNextSettings and CmuxNextSettingsWindow catalogs as base's text plus only
this PR's new keys (scripts/merge-xcstrings.py).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-af2e-7471-8e77-d62753886e4f&host=cosmic-gray
@cursor

cursor Bot commented Oct 21, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

teamleaderleo and others added 3 commits October 21, 2026 13:06
Applies the cmux-next PR autofix patch artifact of run 39662992057.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-af2e-7471-8e77-d62753886e4f&host=cosmic-gray
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The base merge reordered the catalog; rebuild it with scripts/merge-xcstrings.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-af2e-7471-8e77-d62753886e4f&host=cosmic-gray
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 21, 2026 20:08 — with GitHub Actions Inactive
@teamleaderleo teamleaderleo added needs a call Finished and held for a team design or product decision (see #13742 and the gallery in #15427) and removed needs a call Finished and held for a team design or product decision (see #13742 and the gallery in #15427) labels Oct 21, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Orphaned: no activity for 14 h, and no lane holds a lease on it. The orphan sweep could not merge feat-cmux-next in: conflicts in Packages/macOS/CmuxNext/Sources/CmuxNextDesign/Windows/WebTheme.swift, Packages/macOS/CmuxNext/Sources/CmuxNextSettings/Localizable.xcstrings, Packages/macOS/CmuxNext/Sources/CmuxNextSettingsWindow/Localizable.xcstrings, schemas/settings-export/settings-schema.sources.sha256. Listed for a lane to resolve.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by nx-settings on big-red

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Superseded by #21784 (Apple aerial backgrounds), #21789 (collage backgrounds), and #21746 (background video and Chief picture settings). The current feat-cmux-next base already contains the shared wallpaper picker foundation; those focused PRs own the remaining slices.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Superseded by #21784, #21789, and #21746.

This branch was previously deployed

3 inactive (1 outdated) deployments
cmux-tui-merge-tree — 68dd4f42 Deployed Oct 21, 2026 by teamleaderleo
ci-routing-agent — 68dd4f42 Deployed Oct 21, 2026 by teamleaderleo
artifacts — d8a91d36 Deployed Oct 20, 2026 by manaflow-cmux-pr-autofix[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant