Inverted glass layout: Aside-style backdrop, opaque content cards - #303
Merged
Conversation
The window backdrop is now the sidebar's Liquid Glass surface: a full-window NSGlassEffectView underlay in the theme frame below the contentView, sampling the desktop through the standard transparent-window compositing path (no contentView replacement, no custom corner masks — AppKit owns the frame, which removes the transparent-corner class of bugs at the source). Terminal and browser panes are opaque elevated cards (12pt continuous radius, 8pt inset from edges and sidebar). The 0.82 glass opacity clamp is gone — the card is fully opaque by design. The sidebar renders flat on the backdrop with the system appearance, fixing the forced-dark sidebar in light mode; only pane pills keep terminal-derived contrast. Pane chrome portal now searches the theme frame for its host, minimal mode no longer pulls content under the titlebar in card layout, and a debug.viewtree socket command dumps the window's AppKit tree (frames, layer colors, effect-view state) for chrome-layering diagnosis.
The square corners were bonsplit's pane background painting the full pane rect; it is now clipped to the card shape. Sidebar paddings land on a 4pt grid (edges on 8): workspace rows, footer, quota rows; the off-grid scroll spacer is gone. Control clusters use 8pt top offset and gaps.
…right Both capsules share the tab strip's midline instead of stacking below the window top; the tab bar reserves their width so pills compress rather than slide under; capsules take the resting-pill surface so the strip's three backgrounds read as one material family.
…apsules Strip is 44pt (28pt pill + 8/8); selected pills and control capsules share labelColor@0.12 at full presence, quiet pills stay untinted glass.
…live resize A Safari-style + capsule follows the last pill (scrolls with tabs, pills compress around its reserved seat) wired to the pane's new-terminal-tab action, with EN/JA strings. Chrome geometry syncs immediately during live resize instead of coalescing — the one-turn lag read as icons trailing the window edge. Pill gap joins the 8pt grid.
The + is a plain 28pt ghost button, not a capsule peer of the pills. With the sidebar visible the card layout no longer reserves the legacy 32pt titlebar band (and skips the invisible titlebar overlay) — the strip owns the card top. Sidebar-hidden and fullscreen keep the band for the titlebar accessory controls.
Remove the Match Terminal Background toggle and its scheme-forcing modifier — the sidebar follows the system appearance by design, and the modifier was the last path that could force terminal-derived contrast onto it. Drop the dead sidebarBlendMode parameter from cmuxShouldApplyWindowGlass and update its test to the new contract (glass is stock when available; the legacy opt-in only gates the pre-26 fallback). Legacy key readers in fallback and debug paths stay untouched.
Each bonsplit pane is hosted by its own NSHostingController, which was still honoring the window's titlebar safe area — ~24pt of dead space above the tab strip in full-size-content windows. The pane owns its own top, so the hosting controller's safeAreaRegions are cleared.
Titlebar relayout snaps the buttons back to the stock corner on every resize tick; re-seat them synchronously per tick instead of only at didEndLiveResize.
Bare rows (no card surface) align to card-edge + row-inset (16pt), not the 8pt card-edge line; 8pt to the window bottom.
…coherence Update the two tests still asserting pre-inversion contracts (0.82 opacity clamp; contentView-replacement glass hierarchy) to the new ones: opaque cards stay opaque, and the backdrop installs as a theme-frame sibling below an untouched contentView and removes cleanly. Card corner rounding now shares the card-layout predicate (skipped under Reduce Transparency, which also disables the insets). The fallback sidebar restores terminal-derived label contrast when Match Terminal Background is on.
Resolves WindowPaneChromePortal: keep the single-row strip layout and adopt main's ensureAboveBars z-order helper from the portal-churn fix (#302).
…ss contract On macOS 26 the transparent window + glass backdrop are stock, so the transparency predicate returns true regardless of the legacy opt-in; the test now branches on availability. The backdrop test tracks the exact view apply() adds instead of type-matching, which also caught the theme frame's own titlebar material.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Flips the window's layering to match how native Tahoe apps (and Aside) treat a sidebar: the window backdrop is now a Liquid Glass surface sampling the desktop and following the system appearance, and the terminal/browser panes float on it as opaque rounded cards. This fixes the forced-dark sidebar in light mode at the root, and deletes the custom corner-mask machinery that caused every transparent-corner bug — the standard AppKit frame owns the window shape again.
Summary
NSGlassEffectViewunderlay in the theme frame below the contentView; standard transparent-window compositing, no contentView replacement, no masks. Stock on macOS 26 (cmuxShouldApplyWindowGlassreturns true when available; pre-26 keeps the legacy opt-in).inLiveResize, traffic lights re-seat per resize tick.Review order
Sources/WindowChrome.swift— the new backdrop architecture (large deletion)Sources/GhosttyTerminalSupport.swift+Sources/AppDelegate.swift— the gate/predicate changesSources/WindowPaneChromePortal.swift— strip layout, "+" button, live-resize syncvendor/bonsplit— pane safe area, bar heightTest plan