cmux-next: collages: arrange several pictures as one background
Closed
TE
10d ago+10622+10622+01234567890123456789012345678901234567890123456789-5200-5200-0123456789012345678901234567890123456789
Phase 7 of the backgrounds plan: collages, approved by Leo through the coordinator.
Stacked on manaflow-ai/cmux#21743, which carries #21731's Settings page provider. Review only 8afeb67d5ed.
What changes
appearance.backgroundtakescollage:<id>(BackdropSelection.collage).- The id is letters, digits and dashes only (1–64), so it never names another path.
- The native
BackdropSelectionSetting.acceptsand the page'svalidate.tsboth take it. A schema sample and a refused sample (collage:../evil) are added, and the base-autofix regenerates the export.
- Storage:
Backgrounds/Collages/<id>.jsonholds the record (BackdropCollage: name, fill and layers back to front, each with a source, frame, opacity and corner radius).<id>.pngis the drawing, which the window shows like any picture. - Drawing:
BackdropCollages.renderdraws the fill, then each layer.- Each layer is decoded at about the size it's drawn and fills its frame centered.
- Rounding and opacity are applied, at 3200×2000.
- Saving: a saved edit gets a new id, and the old files go. That way the image cache, which is keyed by id, never shows an old drawing.
- Validation:
- Layers must be still pictures (art, macOS stills or your images), not videos, the desktop or another collage.
- Layers must sit on the canvas, with finite numbers, opacity from 0 to 1 and corner radius from 0 to 0.5, and there can be at most 12.
- A collage where nothing can be read is refused rather than saved as a bare fill.
- Picker: collages are listed as Your collages, right after your images. Each has ✎ to edit and × to remove; the one in use can't be removed, and its hand placement goes with it.
- Editor (Settings > Background > New Collage…):
- add pictures from the grid
- drag to move, and drag the corner handle to resize; edges snap to the canvas's halves and thirds
- arrow keys nudge (Shift moves further), and Delete removes
- Bring Forward, Send Backward, Rounded Corners and Remove Picture
- fill color and name
- starter layouts: side by side, three columns, mosaic
- Save draws the collage natively and sets it as the background
- Ops:
cmux.settings.backdrop.image.collage.save | get | delete, onBackdropImagesPageProvider. The page setsappearance.backgrounditself through the normal settings write. CmuxNextApp is unchanged.
Strings
19 page keys and 3 native keys, all in 21 locales.
Tests
CmuxNextDesignTests/BackdropCollagesTests:- id safety and round trip
- save draws 3200×2000, reads back and lists
- an edit replaces under a new id, and delete works
- every invalid layer kind is refused, and an unreadable-only collage is refused
- the catalog lists collages right after your images and never as images
CmuxNextPagesTests: collage save, get and delete; a malformed collage is refused; the in-use one can't be deleted.- Web:
collageLayout.test.ts: snapping, staying on the canvas, minimum size, layouts and restackinghostCards.test.tsx: New Collage adds two pictures, applies Side by Side, saves and setscollage:<id>, the in-use one can't be removed, and an edit saves withreplacing- all 133 settings tests pass
vp lint,vp fmtandtscare clean.
Verification
- Swift: not built locally. It'll go in the next next-batch run.
- Not dogfooded.
Not in this PR (follow-ups)
- Video layers. The spec's "one video plays at a time" needs the collage drawn live, not as one PNG.
- Placing a layer by hand inside the window. The editor places layers on its canvas.
- Rotation.
Changelog
Added: Collages: arrange several pictures as one background, with snapping, layouts, rounded corners and a fill color.
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Adds collages as a background: several pictures arranged on one 16:10 canvas, drawn natively to a PNG at 3200×2000 and set via appearance.background = collage:<id>.
Collages
- The Settings editor adds pictures from the grid, drags and resizes with snapping to halves and thirds, nudges with arrow keys, restacks layers, rounds corners, sets a fill color, and picks starter layouts.
- Collages live in
Backgrounds/Collages/as a JSON record plus a drawing; a saved edit gets a new id, and old files are removed only after the background switches. - Still pictures only; videos, the desktop and other collages are refused as layers.
- The picker lists collages as "Your collages" with edit and remove (never the one in use); ops are
cmux.settings.backdrop.image.collage.save | get | delete.
Carried from earlier phases
- The subject crop keeps art clear of the sidebar and chat.
- Placing a background by hand via a drag/zoom overlay (
cmux.settings.backdrop.image.adjust), saved per background and removed with the picture. - Adding your own image from an https link or file drop, with validation and removal; the page's file reads and disk usage run off the main actor.