cmux-next: add your own background from a link, and manage your images

Merged
TE
18d ago
+2444-18

Phase 3 of the backgrounds plan (briefs/next-backgrounds-plan.md): an easier way to add your own background.

What changes

Settings > Background:

  • Add from a Link tile: paste an https link to an image or video.
    • It downloads into the backgrounds folder and becomes the background, the same way a picked file does.
    • A refused link says why:
      • not https
      • not an image or a video this Mac can play
      • too big: 50 MB for an image, 500 MB for a video
      • could not be downloaded
  • Your images gets:
    • what the images take on disk
    • Show in Finder
    • a remove (×) button on each image, shown on hover or focus. It's disabled on the background in use, so the window never goes blank.
  • Drop is no longer gated. Dropping an image or movie on Settings used to work only with experimentalAppearance on, even though the picker already said "Or drop an image anywhere on this page."

Checks before a file is copied in. This covers picked, dropped and linked files, through BackdropUserImages.adoptChecked:

  • a picture must decode (ImageIO)
  • a movie must be playable and have a video track (AVFoundation)

Before this, a broken file was copied in, listed, and then showed nothing.

Links:

  • BackdropUserImages.download takes https only.
  • A download delegate stops it once it passes the cap. The size is checked again on disk.
  • The file is named for its bytes: ImageIO's type for a picture, the server's movie MIME type, or the link's movie extension. Anything else is refused.

Where the code lives.

  • BackdropImagesPageProvider (CmuxNextPages) serves the new ops on the longest prefix, cmux.settings.backdrop.image.: link, remove, reveal and usage.
  • For a link, it downloads to a temp file and then calls the App's existing useBackdropImage, so the check and the settings write are shared with the picker.
  • SettingsBackdropImages moved to CmuxNextPages with it.
  • CmuxNextApp source lines go down by 3.

Strings

10 new settingsWindow.backdropPicker.* keys, all 21 locales, in CmuxNextSettingsWindow/Localizable.xcstrings. generated/strings.json is regenerated with gen-strings.mjs.

Tests

  • CmuxNextDesignTests/BackdropImportTests:
    • a broken .png is refused and never listed
    • adopt, usage and remove
    • only the folder's own images can be removed
    • http, file and ftp links are refused
    • a stubbed URLSession checks that PNG bytes behind an extensionless link are named .png, HTML behind .png is refused, and a 404 fails
  • CmuxNextPagesTests/BackdropImagesPageProviderTests: the ops, refusal codes, own-images-only remove and reveal, and folder reveal.
  • webviews/.../hostCards.test.tsx: the link form's refusals, adding sets and lists the image, the in-use image can't be removed and another can, and Show in Finder.

Verification

  • bun test src/pages/settings: 128 pass.
  • vp lint and vp fmt on the changed files: clean.
  • tsc: no errors in settings. The only 2 errors are files outside my sparse checkout.
  • lint-ios-package-conventions.sh: clean.
  • check-text-focus-rings.py: only the known base red (DaemonRecoveryControls.swift:98).
  • Swift: not built locally (no Mac in this lane), so CI is the first compile.
  • Not dogfooded.

Not in this PR

  • Hover-to-play video thumbnails in the picker. They need a video resource route in the App's SettingsBackdropThumbnails, and the App can't grow, so that waits for a slot.
  • The 4K / over-60 fps "uses more power" note. It needs async video probing in the catalog listing.
  • Built-in videos in art/manifest.json belong to phase 5, since they change the schema's accepted samples.

WINDOW

None. No settings schema, catalog or Package.swift change. The ops are page ops, not settings keys.

Changelog

Added: Add a background from a web link, and remove your own background images or show them in Finder.

🤖 Generated with Claude Code


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


Summary by cubic

Adds Settings > Background the ability to add your own background from an https link, and management for your own images: remove (not the one in use), size on disk, and Show in Finder. Picked, dropped, and linked files are checked to decode or play before they are copied in, and dropping no longer requires the experimental appearance flag.

  • Link downloads stream under a cap (50 MB images, 500 MB videos) checked against both the declared length and the running count, stay https-only (redirects off https are refused), and are refused with a reason when not playable or too large. A body that starts like a picture gets the picture cap regardless of the declared type.
  • Link names are sanitized (folders, colons, and leading dots stripped; the extension drops at the last dot) and kept in the download's folder; idle and total timeouts are covered, and the temporary folder is removed on every failure.
  • The new ops (link, remove, reveal, usage) are served by a new BackdropImagesPageProvider in CmuxNextPages, shrinking CmuxNextApp and importing every type it uses so the fleet compile passes. Removing the background in use is refused natively, and both folder size and Finder reveal run off the main thread.
  • Adds 10 new localized strings, a settings gallery entry for the link form, and tests covering import checks, page ops, and the link form.