cmux-next: readability over a background comes from opacity, blur and glass, not the picture

Merged
TE
16d ago
+246-556

Leo: readability over the background isn't about the picture. It comes from how much opacity, blur and glass the window lays over it, and those should apply the same way whatever picture is behind them.

On the base, the picture decided:

  • The legibility floor. Over art, WindowBackdrop raised the tint to legibleTintOpacity. That's the least tint at which every text role kept WCAG contrast against the picture's measured darkest and lightest pixels (BackdropArtRange). For the bundled themes it is 0.82 to 1.0, so most of the Opacity slider changed nothing. #22378 then started the slider at the floor (windowOpacityFloor, sent as derived_min), with "Starts at 65% so text stays readable over this picture".
  • Each work's own tint. Unset, a painting replaced the theme's tint with its own preferredTintOpacity, around 0.3. minimumTintOpacity did the same in the other direction.
  • Frosted did nothing over art. Its blur is the window's behind-window radius, which blurs only the desktop. Opaque art hides the desktop.

Now:

  • Opacity is the tint, the same over every picture, and the slider's whole travel changes the window. It still stops at 95% (maximumWorkspaceTint). Unset, every picture gets the theme's wallpaperTintOpacity.
  • Frosted blurs the picture itself by its radius (WindowBackdrop.artBlurRadius, a CIGaussianBlur on the art and the video). Glass refracts it as before, and Clear Glass still shows the desktop through it.

Removed:

  • the floor (legibleTintOpacity, BackdropArtRange, ThemeScope.windowOpacityFloor, derived_min in the Settings host and page)
  • the per-work tint and range fields
  • the slider's narrowed range and its summary string
  • opacityFloor.test.tsx and the backdrops-opacity-floor gallery variant

This Workspace's Opacity, unset, follows All Workspaces. Its strings say so now ("Follows All Workspaces", "Use All Workspaces", "How much of the theme color covers the picture.") in place of "the work's own tint". pane-backgrounds-DESIGN.md is updated to match.

Builds on #22378 and #22379 (both merged). These open PRs build on the floor and would be superseded: #21783 (glass legibility floor) and #22530 (This Workspace's slider starts at the floor).

Tests

  • Committed first (6d6a1f5f638e):
    • ReadabilityOverArtTests (CmuxNextDesignTests) checks three things. Over every bundled work, your own image and a macOS wallpaper, the tint is exactly the Opacity asked for, from 0 to 0.9. Unset, every picture gets the same tint. Frosted puts a 20 pt Gaussian blur on the art, and None leaves it sharp.
    • sliderRows.test.tsx: over a picture the slider keeps its whole travel, even if a host still sends a floor.
  • Red on the base: bun test src/pages/settings/sliderRows.test.tsx gave 7 pass, 1 fail (min 0.65, expected 0). The Swift tests fail there by reading: the floor raises the tint, the works bring their own tints, and nothing blurs the art.
  • On the head:
    • bun test src/pages/settings gives 196 pass, 2 fail. The 2 failures are categories.test "every page row has exactly one home" and editors.test "every schema row renders the editor for its kind". They are about ui.animations.*, appearance.density* and browser.siteEngines, not these rows, so they look like stale schema exports, but I didn't run them on the base to confirm.
    • bun run typecheck passes.
  • Swift: this host is Linux with no Swift toolchain, so nothing compiled or ran here. CI's CmuxNext tests will be the first run.
  • python3 scripts/verify-local.py --affected origin/feat-cmux-next: everything passes except localization and package-groups, which fail the same way on the base.
  • Localization: three new settingsWindow.backdropPicker.workspaceOpacity* keys are translated in all 21 locales. localization_catalog.py check --catalog … reports nothing for them. Four keys whose text no longer holds are removed.

Changelog

  • Changed: In cmux NEXT, a background picture no longer sets how much the window covers it. Opacity is the tint over every picture, its whole slider works, and Frosted blurs the picture.

šŸ¤– 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

Readability over a background picture no longer depends on the picture. The window's Opacity is now the same tint over every picture, and Frosted blurs the picture itself instead of only the desktop.

  • Removed the legibility floor (legibleTintOpacity, BackdropArtRange, windowOpacityFloor, derived_min) that raised the tint over art to 0.82–1.0 and left most of the Opacity slider dead, plus each work's own unset tint and range.
  • The Opacity slider's full travel now changes the window; unset, every picture gets the theme's wallpaperTintOpacity.
  • Frosted applies a Gaussian blur to the art and video by the material's radius, with the picture clamped first so the blur leaves no translucent rim; Window Glass and Clear Glass behave as before.
  • This Workspace's Opacity, unset, follows All Workspaces, with updated strings in all 21 locales.
  • Hosts that still send derived_min are ignored; the slider keeps its full range.

Supersedes the open PRs #21783 and #22530, which built on the removed floor.