CmuxNext: the sidebar shares the main pane's surface (old look under Appearance)
The sidebar now draws the main pane's own background. Until now the sidebar, the gutter and the titlebar around the curved main pane were shaded darker (black at 28% in dark themes, 4.5% in light ones), so the sidebar read as a separate panel. Leo asked to try one surface by default and keep the old look as an option.
- Default,
appearance.sidebarSurface: "same": no shade around the main pane. The pane outlines (the defaultbordersseparation) and the sidebar's edge line (on hover, or always withsidebar.border) keep the sidebar and the panes apart. Over glass or a translucent window, the sidebar and the panes share the same glass. "separate": the old shaded sidebar, unchanged. It's under Settings > Appearance > Sidebar > Sidebar Background, and switching it repaints open windows live.- No line between them: when no pane outline draws (
layout.paneSeparationcards, dividers or none, orappearance.borders: "none") and the sidebar edge line is off (thesidebar.borderdefault), nothing would separate the sidebar from the panes. The shared surface keeps a faint step there instead: 35% of the old shade (about 10% black in dark themes, 1.6% in light ones).
Hover, selection and accent fills are the foreground or accent at a low alpha over whatever surface is underneath, so they read the same on the unshaded sidebar. Group header fills already mix from sidebarBackground, which is the unshaded surface.
The setting is SidebarSurface in CmuxNextDesign, DesignSettings.sidebarSurface, and Metrics.mainPaneChromeShade. It's parsed by SidebarSurfaceSetting, whose diagnostics come from the placement parse so CmuxConfigSnapshot.swift doesn't grow. Agents may change it (settable table).
Before / after
One fleet build of this head (9f29761a2498), on a capture slot, with the setting switched live over the app socket. Each strip shows Separate (the base look), the new default, and the new default under appearance.borders: "none". Sampled backgrounds: dark sidebar 22 → 30 (pane 30), with borders none 27; light sidebar 244 → 255 (pane 255), with borders none 251.


In the default, the pane outlines are enough to separate the sidebar from the panes. Under borders none they aren't, so the faint step stays there.
Testing
SidebarSurfaceTests (CmuxNextAppTests) opens a WindowRootView in a window, loads cmux.json through CmuxConfigSnapshot.parse and SettingsApplier (with ActionRegistry.standard()), and compares the window's color at the sidebar's center with the color at the main pane's center:
- by default (
bordersseparation, so pane outlines draw), the sidebar matches the main pane; - under
"separate", the sidebar is the old shaded color; - switching same → separate → same → key removed repaints the open window each time;
- a bad value keeps the default and reports an
invalidValuediagnostic; - under
borders: "none", and underlayout.paneSeparation: "cards", the sidebar is darker than the pane and lighter than the separate look.
Fleet runs of scripts/ci/run-swift-testing-suites.sh Packages/macOS/CmuxNext, which is where SidebarSurfaceTests ran:
- Red, step 706bf59cb084, at the first tests-only commit 089ac08e3b94: 4 of 5 fail (the separate case already matches base); the other 243 suites passed.
- Red, step 436a1109afd8, at the review's tests-only commit 0bf081b51ee8 (the cards case): only
withoutPaneOutlinesTheSidebarKeepsAFaintStepfails, with the sidebar equal to the pane. The other 243 suites passed. - Green, step e924cd24fe4c, at the merged head 40a51033f76d: all 6
SidebarSurfaceTestspass; 247 of 248 suites pass. The one red isPaneToolbarTests.eachPaneKindOffersItsOwnActionsAndAChatHasNoMore, which expects Split Right/Down in the "…" menu. Base #20128 removed them from that menu, and this PR doesn't touch the toolbar. - Before the review fix, green step 4c95e4d621c4 at 9f29761a2498 passed all 244 suites.
The settings exports (schemas/settings/settings-schema.json, docs/mdm/*) were regenerated by the fleet export-settings-artifacts.sh at the merged head 97caf7be8b59, after merging feat-cmux-next 38e84dbe90b8; then gen-strings.mjs ran. The catalog and exports only add lines against base. Guards run against the merge base: check-concurrency, check-theme-scope, check-system-blue, check-motion and check-no-godfiles.sh --base passed. lint-ios-package-conventions.sh and crash_ratchet.py report only findings in files this PR doesn't touch (CommandRetentionSetting, AgentPageMoveCover, AgentPaneCrashNoticeDebug; TerminalLinkFilter, ClosedRetention, ClosedHistoryRetention). bun run check didn't run: the only web change is the generated strings.json. Hosted react-apps-check is red in three agent-pane tests (agent-pane-follow-live, agent-pane-no-capsules, model-chip-fresh-chat). This PR doesn't touch them or anything they import.
Localization audit: 4 new keys in CmuxNextSettings/Localizable.xcstrings (settings.sidebar.surface, .help, settings.choice.sidebarSurface.same, .separate), translated in all 21 locales. No other user-facing text changed.
Changelog
Changed: The sidebar now uses the same background as the main pane; Settings > Appearance keeps the separate sidebar.
🤖 Generated with Claude Code