Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
574970e
Extract window chrome from ContentView
azooz2003-bit Jun 15, 2026
2647334
Fix window chrome regression gates
azooz2003-bit Jun 16, 2026
2bc5573
Merge remote-tracking branch 'origin/main' into feat-contentview-decomp
azooz2003-bit Jun 16, 2026
b2d5420
Fix dictation text merger package lint
azooz2003-bit Jun 16, 2026
87001f3
Import CmuxAppKitSupportUI in pane-background test after chrome move
azooz2003-bit Jun 16, 2026
651798b
Pass windowBackgroundPolicy to moved shouldApply in glass test
azooz2003-bit Jun 16, 2026
b38499b
Merge remote-tracking branch 'origin/main' into feat-contentview-decomp
azooz2003-bit Jun 16, 2026
b372dd8
Fix re-sync test-target break + new-file concurrency warnings
azooz2003-bit Jun 16, 2026
b5d70eb
Merge remote-tracking branch 'origin/main' into feat-contentview-decomp
azooz2003-bit Jun 16, 2026
9a7220d
Link Bonsplit into cmuxTests target after re-sync
azooz2003-bit Jun 16, 2026
ccb90f8
Restore cmuxTests Bonsplit link dropped in re-sync
azooz2003-bit Jun 16, 2026
d52073e
Re-sync onto origin/main: relocate WindowChrome into Packages/macOS/C…
azooz2003-bit Jun 17, 2026
b26c4de
Merge remote-tracking branch 'origin/main' into feat-contentview-decomp
azooz2003-bit Jun 17, 2026
03c3581
WindowChrome: folder-separate by concern + package README (Aziz review)
azooz2003-bit Jun 17, 2026
09d888a
Add explicit import CmuxFoundation to WindowGlassEffect+Views
azooz2003-bit Jun 17, 2026
c65c49f
Add explicit import Foundation to WindowChromeSidebarPresetOption
azooz2003-bit Jun 17, 2026
795323d
WindowChrome: split AppWindowBackdropControllerDependencies into its …
azooz2003-bit Jun 17, 2026
dffbd4e
Merge remote-tracking branch 'origin/main' into feat-contentview-decomp
azooz2003-bit Jun 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions .github/swift-file-length-budget.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
# Reduce counts as files shrink. CI fails if tracked files exceed this budget.
34475 CLI/cmux.swift
17583 Sources/AppDelegate.swift
16578 Sources/ContentView.swift
15920 Sources/ContentView.swift
14225 Sources/TerminalController.swift
12645 Sources/Workspace.swift
12646 Sources/Workspace.swift
12115 cmuxTests/AppDelegateShortcutRoutingTests.swift
11718 Sources/GhosttyTerminalView.swift
11387 Sources/Panels/BrowserPanel.swift
11731 Sources/GhosttyTerminalView.swift
11388 Sources/Panels/BrowserPanel.swift
9331 cmuxTests/CLINotifyProcessIntegrationRegressionTests.swift
7931 Sources/Panels/BrowserPanelView.swift
7356 cmuxTests/WorkspaceUnitTests.swift
7221 cmuxTests/WorkspaceRemoteConnectionTests.swift
6317 cmuxTests/SessionPersistenceTests.swift
6222 cmuxTests/GhosttyConfigTests.swift
6223 cmuxTests/GhosttyConfigTests.swift
6154 Sources/TabManager.swift
6153 CLI/cmux_open.swift
6074 Sources/TextBoxInput.swift
Expand All @@ -24,10 +24,10 @@
4516 Sources/cmuxApp.swift
4467 Sources/Panels/FilePreviewPanel.swift
4401 cmuxTests/BrowserPanelTests.swift
4227 Sources/BrowserWindowPortal.swift
4225 Sources/BrowserWindowPortal.swift
3937 Sources/Feed/FeedPanelView.swift
3926 cmuxTests/TabManagerUnitTests.swift
3903 cmuxTests/WindowAndDragTests.swift
3896 cmuxTests/WindowAndDragTests.swift
3734 Packages/iOS/CmuxMobileTerminal/Sources/CmuxMobileTerminal/GhosttySurfaceView.swift
3699 cmuxTests/CLIGenericHookPersistenceTests.swift
3397 Sources/CmuxConfig.swift
Expand All @@ -42,7 +42,7 @@
2395 Sources/Mobile/MobileHostService.swift
2355 Sources/FileExplorerView.swift
2328 cmuxTests/CJKIMEInputTests.swift
2259 Sources/TerminalWindowPortal.swift
2257 Sources/TerminalWindowPortal.swift
2236 Sources/TerminalNotificationStore.swift
2117 cmuxTests/CmuxConfigTests.swift
2092 cmuxTests/ShortcutAndCommandPaletteTests.swift
Expand Down Expand Up @@ -185,7 +185,6 @@
558 Packages/macOS/CmuxGit/Sources/CmuxGit/Parsing/GitMetadataService+Config.swift
556 Sources/Panels/BrowserAutomation.swift
551 Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/BrowserSection.swift
547 Sources/Windowing/WindowGlassEffect.swift
541 Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Pane/ControlCommandCoordinator+Pane.swift
540 Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Coordinators/WorkspaceReorderCoordinator.swift
539 CLI/CMUXCLI+Themes.swift
Expand Down
8 changes: 8 additions & 0 deletions Packages/macOS/CmuxAppKitSupportUI/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,17 @@ let package = Package(
targets: ["CmuxAppKitSupportUI"]
),
],
dependencies: [
.package(path: "../CmuxFoundation"),
.package(path: "../CmuxWorkspaceWindow"),
],
targets: [
.target(
name: "CmuxAppKitSupportUI",
dependencies: [
"CmuxFoundation",
"CmuxWorkspaceWindow",
],
swiftSettings: [
.swiftLanguageMode(.v6),
.enableUpcomingFeature("ExistentialAny"),
Expand Down
86 changes: 86 additions & 0 deletions Packages/macOS/CmuxAppKitSupportUI/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# CmuxAppKitSupportUI

AppKit/SwiftUI support pieces for the macOS app, grouped by concern. Each top-level folder is
one concern: `WindowChrome/` (this is what the ContentView extraction added), plus the
pre-existing `AboutTitlebarDebug/`, `Mouse/`, `Popover/`, and `Scroll/`. Most types are small
`Sendable` value types or narrow `@MainActor` controllers, so resolution logic can be unit
tested without a live window.

## WindowChrome/

"Window chrome" is everything cmux paints around and behind the terminal: the window
background, the native titlebar backdrop, the sidebar material, the hairline borders, and the
macOS 26 glass effect. There are many small types because the chrome is resolved in stages so
each stage stays testable: read current state into a `*Snapshot`, resolve it into a
`*Plan`/`*Policy`, then a `@MainActor` controller applies the plan to a real `NSWindow` and
returns a `*Result`. The value types are pure and unit-tested; the AppKit mutation lives only
in the controllers.

Files are grouped into subfolders by the chrome concern they serve. One major public type per
file, named after the type.

### Appearance/
Resolves the window's overall appearance for one render pass.
- `WindowTerminalAppearanceSnapshot.swift`: current terminal colors/opacity chrome must match.
- `WindowAppearanceUserSettingsSnapshot.swift`: the user settings that influence appearance.
- `WindowAppearanceResolver.swift`: combines those two snapshots into a `WindowAppearanceSnapshot`.
- `WindowAppearanceSnapshot.swift`: the resolved appearance value (colors, opacity, rendering-mode helpers) for one pass.
- `WindowRootBackdropResolution.swift`: the root-backdrop result returned when a pane supplies its own color.

### Backdrop/
The window background fill and how it is applied to AppKit.
- `WindowBackdropRole.swift`: which chrome surface a backdrop targets (root, titlebar, etc.).
- `WindowBackdropPolicy.swift`: the rendering policy chosen for a surface.
- `WindowBackdropHostingPhase.swift`: which AppKit hosting strategy is used.
- `WindowBackdropGlassPlan.swift`: tint and glass style when the backdrop uses native glass.
- `WindowBackdropPlan.swift`: the full set of `NSWindow` mutations for a resolved backdrop.
- `WindowBackdropControllerDependencies.swift`: protocol of app-provided side effects the controller needs (injected).
- `WindowBackdropController.swift`: `@MainActor` type that applies a plan/snapshot to an `NSWindow`.
- `WindowBackdropApplicationResult.swift`: what changed after the controller ran.
- `WindowBackdropLayer.swift`: SwiftUI view that renders the resolved backdrop for one role.
- `LayerBackedBackdropColor.swift`: internal non-hit-testing AppKit color fill for transparent windows.

### Glass/
The macOS 26 `NSGlassEffectView` window glass, with an `NSVisualEffectView` fallback.
- `WindowGlassEffectStyle.swift`: the native glass style applied when glass is available.
- `WindowGlassSettingsSnapshot.swift`: persisted plus terminal-driven settings for the glass root.
- `WindowGlassEffectManaging.swift`: protocol seam for applying and inspecting the glass hierarchy.
- `WindowGlassEffect.swift`: `@MainActor` implementation of that seam (native glass + fallback).
- `WindowGlassEffect+Views.swift`: internal AppKit view helpers used by `WindowGlassEffect`.
- `GhosttyBackgroundBlur+WindowGlassEffectStyle.swift`: maps a Ghostty blur mode to a glass style.

### Titlebar/
The native AppKit titlebar.
- `NativeTitlebarBackdropCoordinator.swift`: `@MainActor` type that hides/restores the native titlebar backdrop.
- `TitlebarLeadingInsetReader.swift`: SwiftUI reader for the inset needed to clear traffic lights and accessories.

### Border/
The hairline borders between chrome surfaces.
- `WindowChromeBorderOrientation.swift`: orientation of a one-pixel border.
- `WindowChromeBorder.swift`: SwiftUI one-pixel border derived from the chrome background color.

### Color/
Color math shared across chrome.
- `WindowChromeColorResolver.swift`: separator color, compositing, and readable-scheme math.

### Sidebar/
The sidebar backdrop material and its persisted options.
- `SidebarBackdropSettingsSnapshot.swift`: persisted sidebar backdrop settings as a value.
- `SidebarBackdropMaterialPolicy.swift`: the resolved AppKit material settings for the sidebar.
- `SidebarVisualEffectBackground.swift`: internal wrapper view (native glass, falls back to visual effect).
- `WindowChromeSidebarPresetOption.swift`: `sidebarPreset` setting values.
- `WindowChromeSidebarMaterialOption.swift`: `sidebarMaterial` setting values.
- `WindowChromeSidebarBlendModeOption.swift`: `sidebarBlendMode` setting values.
- `WindowChromeSidebarStateOption.swift`: `sidebarState` setting values.
- `WindowChromeSidebarTintDefaults.swift`: legacy default sidebar tint constants.

### TerminalSurface/
How an individual terminal surface paints its own background.
- `GhosttyTerminalBackdropRenderingMode.swift`: who owns the terminal backdrop pixels.
- `TerminalSurfaceBackgroundFillOwner.swift`: which layer paints a surface background.
- `TerminalSurfaceBackgroundFillPlan.swift`: the resolved fill decision for one surface.

### Overlay/
Where window-level overlays are inserted in the AppKit hierarchy.
- `WindowContentOverlayInstallationTarget.swift`: the container/reference pair to install into.
- `WindowContentOverlayTargetResolver.swift`: resolves the insertion point for a window.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import AppKit
public import SwiftUI
import CmuxFoundation

/// Builds `WindowAppearanceSnapshot` values from injected terminal and user settings.
public struct WindowAppearanceResolver {
private let terminalAppearance: WindowTerminalAppearanceSnapshot

/// Creates a resolver with the current terminal appearance injected by the app.
public init(terminalAppearance: WindowTerminalAppearanceSnapshot) {
self.terminalAppearance = terminalAppearance
}

/// Resolves window appearance from explicit user settings.
public func current(settings: WindowAppearanceUserSettingsSnapshot) -> WindowAppearanceSnapshot {
WindowAppearanceSnapshot(
terminalBackgroundColor: terminalAppearance.backgroundColor,
terminalBackgroundOpacity: WindowAppearanceSnapshot.clampedOpacity(terminalAppearance.backgroundOpacity),
terminalBackgroundBlur: terminalAppearance.backgroundBlur,
terminalRenderingMode: WindowAppearanceSnapshot.terminalRenderingMode(
usesHostLayerBackground: terminalAppearance.usesHostLayerBackground
),
unifySurfaceBackdrops: settings.unifySurfaceBackdrops,
sidebarSettings: SidebarBackdropSettingsSnapshot(
materialRawValue: settings.sidebarMaterial,
blendModeRawValue: settings.sidebarBlendMode,
stateRawValue: settings.sidebarState,
tintHex: settings.sidebarTintHex,
tintHexLight: settings.sidebarTintHexLight,
tintHexDark: settings.sidebarTintHexDark,
tintOpacity: settings.sidebarTintOpacity,
cornerRadius: settings.sidebarCornerRadius,
blurOpacity: settings.sidebarBlurOpacity,
colorScheme: settings.colorScheme
),
windowGlassSettings: WindowGlassSettingsSnapshot(
sidebarBlendModeRawValue: settings.sidebarBlendMode,
isEnabled: settings.bgGlassEnabled,
tintHex: settings.bgGlassTintHex,
tintOpacity: settings.bgGlassTintOpacity,
terminalBackgroundBlur: terminalAppearance.backgroundBlur,
terminalGlassTintColor: terminalAppearance.backgroundColor.withAlphaComponent(
WindowAppearanceSnapshot.clampedOpacity(terminalAppearance.backgroundOpacity)
)
)
)
}

/// Resolves window appearance from a `UserDefaults` store.
public func currentFromUserDefaults(
defaults: UserDefaults,
colorScheme: ColorScheme
) -> WindowAppearanceSnapshot {
let tintDefaults = WindowChromeSidebarTintDefaults()
return current(settings: WindowAppearanceUserSettingsSnapshot(
unifySurfaceBackdrops: defaults.object(forKey: "sidebarMatchTerminalBackground") as? Bool ?? false,
colorScheme: colorScheme,
sidebarMaterial: defaults.string(forKey: "sidebarMaterial") ?? WindowChromeSidebarMaterialOption.sidebar.rawValue,
sidebarBlendMode: defaults.string(forKey: "sidebarBlendMode") ?? WindowChromeSidebarBlendModeOption.withinWindow.rawValue,
sidebarState: defaults.string(forKey: "sidebarState") ?? WindowChromeSidebarStateOption.followWindow.rawValue,
sidebarTintHex: defaults.string(forKey: "sidebarTintHex") ?? tintDefaults.hex,
sidebarTintHexLight: defaults.string(forKey: "sidebarTintHexLight"),
sidebarTintHexDark: defaults.string(forKey: "sidebarTintHexDark"),
sidebarTintOpacity: defaults.object(forKey: "sidebarTintOpacity") as? Double ?? tintDefaults.opacity,
sidebarCornerRadius: defaults.object(forKey: "sidebarCornerRadius") as? Double ?? 0.0,
sidebarBlurOpacity: defaults.object(forKey: "sidebarBlurOpacity") as? Double ?? 1.0,
bgGlassEnabled: defaults.object(forKey: "bgGlassEnabled") as? Bool ?? false,
bgGlassTintHex: defaults.string(forKey: "bgGlassTintHex") ?? "#000000",
bgGlassTintOpacity: defaults.object(forKey: "bgGlassTintOpacity") as? Double ?? 0.03
))
}
}
Loading
Loading