diff --git a/macos/Sources/App/macOS/AppDelegate.swift b/macos/Sources/App/macOS/AppDelegate.swift index b5023370b..c6816d50c 100644 --- a/macos/Sources/App/macOS/AppDelegate.swift +++ b/macos/Sources/App/macOS/AppDelegate.swift @@ -741,7 +741,7 @@ class AppDelegate: NSObject, func findSurface(forUUID uuid: UUID) -> Ghostty.SurfaceView? { for c in terminalManager.windows { - for view in c.controller.surfaceTree2 { + for view in c.controller.surfaceTree { if view.uuid == uuid { return view } diff --git a/macos/Sources/Features/QuickTerminal/QuickTerminalController.swift b/macos/Sources/Features/QuickTerminal/QuickTerminalController.swift index b338f8b47..0dcfce204 100644 --- a/macos/Sources/Features/QuickTerminal/QuickTerminalController.swift +++ b/macos/Sources/Features/QuickTerminal/QuickTerminalController.swift @@ -30,11 +30,11 @@ class QuickTerminalController: BaseTerminalController { init(_ ghostty: Ghostty.App, position: QuickTerminalPosition = .top, baseConfig base: Ghostty.SurfaceConfiguration? = nil, - surfaceTree2 tree2: SplitTree? = nil + surfaceTree tree: SplitTree? = nil ) { self.position = position self.derivedConfig = DerivedConfig(ghostty.config) - super.init(ghostty, baseConfig: base, surfaceTree2: tree2) + super.init(ghostty, baseConfig: base, surfaceTree: tree) // Setup our notifications for behaviors let center = NotificationCenter.default @@ -236,10 +236,10 @@ class QuickTerminalController: BaseTerminalController { // If our surface tree is empty then we initialize a new terminal. The surface // tree can be empty if for example we run "exit" in the terminal and force // animate out. - if surfaceTree2.isEmpty, + if surfaceTree.isEmpty, let ghostty_app = ghostty.app { let view = Ghostty.SurfaceView(ghostty_app, baseConfig: nil) - surfaceTree2 = SplitTree(view: view) + surfaceTree = SplitTree(view: view) focusedSurface = view } } diff --git a/macos/Sources/Features/Terminal/BaseTerminalController.swift b/macos/Sources/Features/Terminal/BaseTerminalController.swift index 028a4bece..3cc5843a5 100644 --- a/macos/Sources/Features/Terminal/BaseTerminalController.swift +++ b/macos/Sources/Features/Terminal/BaseTerminalController.swift @@ -42,8 +42,8 @@ class BaseTerminalController: NSWindowController, } /// The tree of splits within this terminal window. - @Published var surfaceTree2: SplitTree = .init() { - didSet { surfaceTreeDidChange(from: oldValue, to: surfaceTree2) } + @Published var surfaceTree: SplitTree = .init() { + didSet { surfaceTreeDidChange(from: oldValue, to: surfaceTree) } } /// This can be set to show/hide the command palette. @@ -86,7 +86,7 @@ class BaseTerminalController: NSWindowController, init(_ ghostty: Ghostty.App, baseConfig base: Ghostty.SurfaceConfiguration? = nil, - surfaceTree2 tree2: SplitTree? = nil + surfaceTree tree: SplitTree? = nil ) { self.ghostty = ghostty self.derivedConfig = DerivedConfig(ghostty.config) @@ -95,7 +95,7 @@ class BaseTerminalController: NSWindowController, // Initialize our initial surface. guard let ghostty_app = ghostty.app else { preconditionFailure("app must be loaded") } - self.surfaceTree2 = tree2 ?? .init(view: Ghostty.SurfaceView(ghostty_app, baseConfig: base)) + self.surfaceTree = tree ?? .init(view: Ghostty.SurfaceView(ghostty_app, baseConfig: base)) // Setup our notifications for behaviors let center = NotificationCenter.default @@ -167,7 +167,7 @@ class BaseTerminalController: NSWindowController, } } - /// Called when the surfaceTree2 variable changed. + /// Called when the surfaceTree variable changed. /// /// Subclasses should call super first. func surfaceTreeDidChange(from: SplitTree, to: SplitTree) { @@ -180,7 +180,7 @@ class BaseTerminalController: NSWindowController, /// Update all surfaces with the focus state. This ensures that libghostty has an accurate view about /// what surface is focused. This must be called whenever a surface OR window changes focus. func syncFocusToSurfaceTree() { - for surfaceView in surfaceTree2 { + for surfaceView in surfaceTree { // Our focus state requires that this window is key and our currently // focused surface is the surface in this view. let focused: Bool = (window?.isKeyWindow ?? false) && @@ -296,21 +296,21 @@ class BaseTerminalController: NSWindowController, @objc private func ghosttyCommandPaletteDidToggle(_ notification: Notification) { guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return } - guard surfaceTree2.contains(surfaceView) else { return } + guard surfaceTree.contains(surfaceView) else { return } toggleCommandPalette(nil) } @objc private func ghosttyMaximizeDidToggle(_ notification: Notification) { guard let window else { return } guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return } - guard surfaceTree2.contains(surfaceView) else { return } + guard surfaceTree.contains(surfaceView) else { return } window.zoom(nil) } @objc private func ghosttyDidCloseSurface(_ notification: Notification) { // The target must be within our tree guard let target = notification.object as? Ghostty.SurfaceView else { return } - guard let node = surfaceTree2.root?.node(view: target) else { return } + guard let node = surfaceTree.root?.node(view: target) else { return } // TODO: fix focus @@ -323,7 +323,7 @@ class BaseTerminalController: NSWindowController, // If the child process is not alive, then we exit immediately guard processAlive else { - surfaceTree2 = surfaceTree2.remove(node) + surfaceTree = surfaceTree.remove(node) return } @@ -337,7 +337,7 @@ class BaseTerminalController: NSWindowController, informativeText: "The terminal still has a running process. If you close the terminal the process will be killed." ) { [weak self] in if let self { - self.surfaceTree2 = self.surfaceTree2.remove(node) + self.surfaceTree = self.surfaceTree.remove(node) } } } @@ -345,7 +345,7 @@ class BaseTerminalController: NSWindowController, @objc private func ghosttyDidNewSplit(_ notification: Notification) { // The target must be within our tree guard let oldView = notification.object as? Ghostty.SurfaceView else { return } - guard surfaceTree2.root?.node(view: oldView) != nil else { return } + guard surfaceTree.root?.node(view: oldView) != nil else { return } // Notification must contain our base config let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey] @@ -369,7 +369,7 @@ class BaseTerminalController: NSWindowController, // Do the split do { - surfaceTree2 = try surfaceTree2.insert(view: newView, at: oldView, direction: splitDirection) + surfaceTree = try surfaceTree.insert(view: newView, at: oldView, direction: splitDirection) } catch { // If splitting fails for any reason (it should not), then we just log // and return. The new view we created will be deinitialized and its @@ -386,16 +386,16 @@ class BaseTerminalController: NSWindowController, guard let target = notification.object as? Ghostty.SurfaceView else { return } // Check if target surface is in current controller's tree - guard surfaceTree2.contains(target) else { return } + guard surfaceTree.contains(target) else { return } // Equalize the splits - surfaceTree2 = surfaceTree2.equalize() + surfaceTree = surfaceTree.equalize() } @objc private func ghosttyDidFocusSplit(_ notification: Notification) { // The target must be within our tree guard let target = notification.object as? Ghostty.SurfaceView else { return } - guard surfaceTree2.root?.node(view: target) != nil else { return } + guard surfaceTree.root?.node(view: target) != nil else { return } // Get the direction from the notification guard let directionAny = notification.userInfo?[Ghostty.Notification.SplitDirectionKey] else { return } @@ -413,10 +413,10 @@ class BaseTerminalController: NSWindowController, } // Find the node for the target surface - guard let targetNode = surfaceTree2.root?.node(view: target) else { return } + guard let targetNode = surfaceTree.root?.node(view: target) else { return } // Find the next surface to focus - guard let nextSurface = surfaceTree2.focusTarget(for: focusDirection, from: targetNode) else { + guard let nextSurface = surfaceTree.focusTarget(for: focusDirection, from: targetNode) else { return } @@ -427,15 +427,15 @@ class BaseTerminalController: NSWindowController, @objc private func ghosttyDidToggleSplitZoom(_ notification: Notification) { // The target must be within our tree guard let target = notification.object as? Ghostty.SurfaceView else { return } - guard let targetNode = surfaceTree2.root?.node(view: target) else { return } + guard let targetNode = surfaceTree.root?.node(view: target) else { return } // Toggle the zoomed state - if surfaceTree2.zoomed == targetNode { + if surfaceTree.zoomed == targetNode { // Already zoomed, unzoom it - surfaceTree2 = SplitTree(root: surfaceTree2.root, zoomed: nil) + surfaceTree = SplitTree(root: surfaceTree.root, zoomed: nil) } else { // Not zoomed or different node zoomed, zoom this node - surfaceTree2 = SplitTree(root: surfaceTree2.root, zoomed: targetNode) + surfaceTree = SplitTree(root: surfaceTree.root, zoomed: targetNode) } // Ensure focus stays on the target surface. We lose focus when we do @@ -458,8 +458,7 @@ class BaseTerminalController: NSWindowController, } private func localEventFlagsChanged(_ event: NSEvent) -> NSEvent? { - // Also update surfaceTree2 - var surfaces: [Ghostty.SurfaceView] = surfaceTree2.map { $0 } + var surfaces: [Ghostty.SurfaceView] = surfaceTree.map { $0 } // If we're the main window receiving key input, then we want to avoid // calling this on our focused surface because that'll trigger a double @@ -489,7 +488,7 @@ class BaseTerminalController: NSWindowController, // want to care if the surface is in the tree so we don't listen to titles of // closed surfaces. if let titleSurface = focusedSurface ?? lastFocusedSurface, - surfaceTree2.contains(titleSurface) { + surfaceTree.contains(titleSurface) { // If we have a surface, we want to listen for title changes. titleSurface.$title .sink { [weak self] in self?.titleDidChange(to: $0) } @@ -527,7 +526,7 @@ class BaseTerminalController: NSWindowController, func splitDidResize(node: SplitTree.Node, to newRatio: Double) { let resizedNode = node.resize(to: newRatio) do { - surfaceTree2 = try surfaceTree2.replace(node: node, with: resizedNode) + surfaceTree = try surfaceTree.replace(node: node, with: resizedNode) } catch { // TODO: log return @@ -687,13 +686,13 @@ class BaseTerminalController: NSWindowController, guard let window = self.window else { return true } // If we have no surfaces, close. - if surfaceTree2.isEmpty { return true } + if surfaceTree.isEmpty { return true } // If we already have an alert, continue with it guard alert == nil else { return false } // If our surfaces don't require confirmation, close. - if !surfaceTree2.contains(where: { $0.needsConfirmQuit }) { return true } + if !surfaceTree.contains(where: { $0.needsConfirmQuit }) { return true } // We require confirmation, so show an alert as long as we aren't already. confirmClose( @@ -729,7 +728,7 @@ class BaseTerminalController: NSWindowController, func windowDidChangeOcclusionState(_ notification: Notification) { let visible = self.window?.occlusionState.contains(.visible) ?? false - for view in surfaceTree2 { + for view in surfaceTree { if let surface = view.surface { ghostty_surface_set_occlusion(surface, visible) } diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index 29f2710fe..42eb7eca4 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -32,8 +32,7 @@ class TerminalController: BaseTerminalController { init(_ ghostty: Ghostty.App, withBaseConfig base: Ghostty.SurfaceConfiguration? = nil, - withSurfaceTree tree: Ghostty.SplitNode? = nil, - withSurfaceTree2 tree2: SplitTree? = nil + withSurfaceTree tree: SplitTree? = nil ) { // The window we manage is not restorable if we've specified a command // to execute. We do this because the restored window is meaningless at the @@ -45,7 +44,7 @@ class TerminalController: BaseTerminalController { // Setup our initial derived config based on the current app config self.derivedConfig = DerivedConfig(ghostty.config) - super.init(ghostty, baseConfig: base, surfaceTree2: tree2) + super.init(ghostty, baseConfig: base, surfaceTree: tree) // Setup our notifications for behaviors let center = NotificationCenter.default @@ -154,7 +153,7 @@ class TerminalController: BaseTerminalController { // If we have no surfaces in our window (is that possible?) then we update // our window appearance based on the root config. If we have surfaces, we // don't call this because the TODO - if surfaceTree2.isEmpty { + if surfaceTree.isEmpty { syncAppearance(.init(config)) } @@ -164,7 +163,7 @@ class TerminalController: BaseTerminalController { // This is a surface-level config update. If we have the surface, we // update our appearance based on it. guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return } - guard surfaceTree2.contains(surfaceView) else { return } + guard surfaceTree.contains(surfaceView) else { return } // We can't use surfaceView.derivedConfig because it may not be updated // yet since it also responds to notifications. @@ -239,7 +238,7 @@ class TerminalController: BaseTerminalController { window.isLightTheme = OSColor(surfaceConfig.backgroundColor).isLightColor // Sync our zoom state for splits - window.surfaceIsZoomed = surfaceTree2.zoomed != nil + window.surfaceIsZoomed = surfaceTree.zoomed != nil // If our window is not visible, then we do nothing. Some things such as blurring // have no effect if the window is not visible. Ultimately, we'll have this called @@ -282,9 +281,9 @@ class TerminalController: BaseTerminalController { // If it does, we match the focused surface. If it doesn't, we use the app // configuration. let backgroundColor: OSColor - if !surfaceTree2.isEmpty { + if !surfaceTree.isEmpty { if let focusedSurface = focusedSurface, - let treeRoot = surfaceTree2.root, + let treeRoot = surfaceTree.root, let focusedNode = treeRoot.node(view: focusedSurface), treeRoot.spatial().doesBorder(side: .up, from: focusedNode) { // Similar to above, an alpha component of "0" causes compositor issues, so @@ -293,7 +292,7 @@ class TerminalController: BaseTerminalController { } else { // We don't have a focused surface or our surface doesn't border the // top. We choose to match the color of the top-left most surface. - let topLeftSurface = surfaceTree2.root?.leftmostLeaf() + let topLeftSurface = surfaceTree.root?.leftmostLeaf() backgroundColor = OSColor(topLeftSurface?.backgroundColor ?? derivedConfig.backgroundColor) } } else { @@ -456,7 +455,7 @@ class TerminalController: BaseTerminalController { // If we have only a single surface (no splits) and there is a default size then // we should resize to that default size. - if case let .leaf(view) = surfaceTree2.root { + if case let .leaf(view) = surfaceTree.root { // If this is our first surface then our focused surface will be nil // so we force the focused surface to the leaf. focusedSurface = view @@ -604,7 +603,7 @@ class TerminalController: BaseTerminalController { return } - if surfaceTree2.contains(where: { $0.needsConfirmQuit }) { + if surfaceTree.contains(where: { $0.needsConfirmQuit }) { confirmClose( messageText: "Close Tab?", informativeText: "The terminal still has a running process. If you close the tab the process will be killed." @@ -641,7 +640,7 @@ class TerminalController: BaseTerminalController { guard let controller = tabWindow.windowController as? TerminalController else { return false } - return controller.surfaceTree2.contains(where: { $0.needsConfirmQuit }) + return controller.surfaceTree.contains(where: { $0.needsConfirmQuit }) } // If none need confirmation then we can just close all the windows. @@ -819,19 +818,19 @@ class TerminalController: BaseTerminalController { @objc private func onCloseTab(notification: SwiftUI.Notification) { guard let target = notification.object as? Ghostty.SurfaceView else { return } - guard surfaceTree2.contains(target) else { return } + guard surfaceTree.contains(target) else { return } closeTab(self) } @objc private func onCloseWindow(notification: SwiftUI.Notification) { guard let target = notification.object as? Ghostty.SurfaceView else { return } - guard surfaceTree2.contains(target) else { return } + guard surfaceTree.contains(target) else { return } closeWindow(self) } @objc private func onResetWindowSize(notification: SwiftUI.Notification) { guard let target = notification.object as? Ghostty.SurfaceView else { return } - guard surfaceTree2.contains(target) else { return } + guard surfaceTree.contains(target) else { return } returnToDefaultSize(nil) } diff --git a/macos/Sources/Features/Terminal/TerminalManager.swift b/macos/Sources/Features/Terminal/TerminalManager.swift index 28b969d36..805ae6e93 100644 --- a/macos/Sources/Features/Terminal/TerminalManager.swift +++ b/macos/Sources/Features/Terminal/TerminalManager.swift @@ -197,9 +197,9 @@ class TerminalManager { /// Creates a window controller, adds it to our managed list, and returns it. func createWindow(withBaseConfig base: Ghostty.SurfaceConfiguration? = nil, - withSurfaceTree2 tree2: SplitTree? = nil) -> TerminalController { + withSurfaceTree tree: SplitTree? = nil) -> TerminalController { // Initialize our controller to load the window - let c = TerminalController(ghostty, withBaseConfig: base, withSurfaceTree2: tree2) + let c = TerminalController(ghostty, withBaseConfig: base, withSurfaceTree: tree) // Create a listener for when the window is closed so we can remove it. let pubClose = NotificationCenter.default.publisher( @@ -268,7 +268,7 @@ class TerminalManager { func closeAllWindows() { var needsConfirm: Bool = false for w in self.windows { - if w.controller.surfaceTree2.contains(where: { $0.needsConfirmQuit }) { + if w.controller.surfaceTree.contains(where: { $0.needsConfirmQuit }) { needsConfirm = true break } diff --git a/macos/Sources/Features/Terminal/TerminalRestorable.swift b/macos/Sources/Features/Terminal/TerminalRestorable.swift index 6d5289955..5229dc46e 100644 --- a/macos/Sources/Features/Terminal/TerminalRestorable.swift +++ b/macos/Sources/Features/Terminal/TerminalRestorable.swift @@ -7,11 +7,11 @@ class TerminalRestorableState: Codable { static let version: Int = 3 let focusedSurface: String? - let surfaceTree2: SplitTree + let surfaceTree: SplitTree init(from controller: TerminalController) { self.focusedSurface = controller.focusedSurface?.uuid.uuidString - self.surfaceTree2 = controller.surfaceTree2 + self.surfaceTree = controller.surfaceTree } init?(coder aDecoder: NSCoder) { @@ -26,7 +26,7 @@ class TerminalRestorableState: Codable { return nil } - self.surfaceTree2 = v.value.surfaceTree2 + self.surfaceTree = v.value.surfaceTree self.focusedSurface = v.value.focusedSurface } @@ -84,7 +84,7 @@ class TerminalWindowRestoration: NSObject, NSWindowRestoration { // createWindow so that AppKit can place the window wherever it should // be. let c = appDelegate.terminalManager.createWindow( - withSurfaceTree2: state.surfaceTree2 + withSurfaceTree: state.surfaceTree ) guard let window = c.window else { completionHandler(nil, TerminalRestoreError.windowDidNotLoad) @@ -92,10 +92,10 @@ class TerminalWindowRestoration: NSObject, NSWindowRestoration { } // Setup our restored state on the controller - // Find the focused surface in surfaceTree2 + // Find the focused surface in surfaceTree if let focusedStr = state.focusedSurface { var foundView: Ghostty.SurfaceView? - for view in c.surfaceTree2 { + for view in c.surfaceTree { if view.uuid.uuidString == focusedStr { foundView = view break diff --git a/macos/Sources/Features/Terminal/TerminalView.swift b/macos/Sources/Features/Terminal/TerminalView.swift index 6c990d496..cb6f11bce 100644 --- a/macos/Sources/Features/Terminal/TerminalView.swift +++ b/macos/Sources/Features/Terminal/TerminalView.swift @@ -27,7 +27,7 @@ protocol TerminalViewDelegate: AnyObject { protocol TerminalViewModel: ObservableObject { /// The tree of terminal surfaces (splits) within the view. This is mutated by TerminalView /// and children. This should be @Published. - var surfaceTree2: SplitTree { get set } + var surfaceTree: SplitTree { get set } /// The command palette state. var commandPaletteIsShowing: Bool { get set } @@ -77,7 +77,7 @@ struct TerminalView: View { } TerminalSplitTreeView( - tree: viewModel.surfaceTree2, + tree: viewModel.surfaceTree, onResize: { delegate?.splitDidResize(node: $0, to: $1) }) .environmentObject(ghostty) .focused($focused) diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index 08c284b04..4a9dc0ea6 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -921,7 +921,7 @@ extension Ghostty { // we should only be returning true if we actually performed the action, // but this handles the most common case of caring about goto_split performability // which is the no-split case. - guard controller.surfaceTree2.isSplit else { return false } + guard controller.surfaceTree.isSplit else { return false } NotificationCenter.default.post( name: Notification.ghosttyFocusSplit,