cmux-next Settings: over a picture the Opacity slider starts where it changes the window

Merged
TE
16d ago
+212-7

Over a background picture, most of the Opacity slider on Settings > Appearance did nothing. The window's tint never drops below the legibility floor (WindowBackdrop.legibleTintOpacity, the least tint at which text stays readable over the picture). For the bundled themes that floor is 0.82 to 1.0 (numbers from #21783), and the slider runs 0 to 95%. Dragging below the floor changed nothing on screen, and for light themes the whole slider did nothing. This is the "the knob, the slider still doesn't work" report. #22267 fixed where the thumb rests and how a release is written, but the dead travel was still there.

Now the app reports the floor, and the slider starts there:

  • ThemeScope.shownWindowOpacityFloor (CmuxNextDesign) is the floor the active window paints over its picture. It's nil without a picture or in an opaque window.
  • The host lists send it as derived_min["appearance.backgroundOpacity"], next to #22267's derived.
  • Over a picture, the wallpaper card's Opacity slider starts at the floor, rounded up onto the 5% grid, and still stops at 95%. Its summary line reads "Starts at 65% so text stays readable over this picture". Without a picture it keeps the full 0 to 100%.

A stored value below the floor still loads. The window paints the floor, as before, and the thumb sits at the left end. #21783, which lowers the floor for iOS-style glass, needs no change here: the slider follows whatever floor the app reports.

Tests

  • Committed first (2056bb25e0e), red on the base: bun test src/pages/settings/sliderRows.test.tsx gives 7 pass, 1 fail ("over a background picture the slider starts at the legibility floor the app reports": the min was "0", expected "0.65").
  • On the head, the same command passes 8 of 8. The full bun test src/pages/settings passes 171, with 1 skipped bench and 0 failures. All of these ran on Huge Blue.
  • Swift: WindowBackgroundOpacityTests.overArtTheSliderStartsAtTheLegibilityFloor checks that the floor matches the painted backdrop's legibleTintOpacity, that it's nil without art, and that a tint asked for below the floor paints the floor. It hasn't run yet: there's no local Swift build, so CI will be its first compile.

Proof

New gallery variant pages.settings/backdrops-opacity-floor, captured from the gallery build in headless Chromium on Huge Blue (Linux). The slider runs 65% to 95%, and the summary says why:

Before (base, with a picture behind the window): the slider runs 0 to 95%, and below the floor (about 82%) it changes nothing.

before

After, dark and light:

after dark

after light

Observed / Not run

  • Observed: the web tests above, red then green, bun run check (Oxlint, Oxfmt, type check; the only failure is the check:text-focus base finding in Swift files this PR doesn't touch), and the gallery capture.
  • Not run: the Swift test, and the live app. Nothing here changes how the window paints. The new floor value comes from the same WindowBackdrop math that shownWindowOpacity already uses.

Localization: one new key, settingsWindow.backdropPicker.opacityFloor, in CmuxNextSettingsWindow/Localizable.xcstrings, with all 21 locales (machine translated). Each one stays under 60 characters with the percentage filled in.

Changelog

Fixed: Over a background picture, the Opacity slider starts where it begins to change the window, instead of having travel that did nothing.

🤖 Generated with Claude Code