macos: remove TerminalManager

All logic related to TerminalController is now in TerminalController.
This commit is contained in:
Mitchell Hashimoto
2025-06-06 15:19:05 -07:00
parent 3b77a16b63
commit 33d128bcff
7 changed files with 268 additions and 405 deletions

View File

@@ -87,9 +87,6 @@ class AppDelegate: NSObject,
/// The ghostty global state. Only one per process.
let ghostty: Ghostty.App = Ghostty.App()
/// Manages our terminal windows.
let terminalManager: TerminalManager
/// The global undo manager for app-level state such as window restoration.
lazy var undoManager = ExpiringUndoManager()
@@ -119,7 +116,6 @@ class AppDelegate: NSObject,
}
override init() {
terminalManager = TerminalManager(ghostty)
updaterController = SPUStandardUpdaterController(
// Important: we must not start the updater here because we need to read our configuration
// first to determine whether we're automatically checking, downloading, etc. The updater
@@ -202,6 +198,16 @@ class AppDelegate: NSObject,
name: .ghosttyBellDidRing,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(ghosttyNewWindow(_:)),
name: Ghostty.Notification.ghosttyNewWindow,
object: nil)
NotificationCenter.default.addObserver(
self,
selector: #selector(ghosttyNewTab(_:)),
name: Ghostty.Notification.ghosttyNewTab,
object: nil)
// Configure user notifications
let actions = [
@@ -253,8 +259,8 @@ class AppDelegate: NSObject,
// is possible to have other windows in a few scenarios:
// - if we're opening a URL since `application(_:openFile:)` is called before this.
// - if we're restoring from persisted state
if terminalManager.windows.count == 0 && derivedConfig.initialWindow {
terminalManager.newWindow()
if TerminalController.all.isEmpty && derivedConfig.initialWindow {
_ = TerminalController.newWindow(ghostty)
}
}
}
@@ -339,10 +345,10 @@ class AppDelegate: NSObject,
// This is possible with flag set to false if there a race where the
// window is still initializing and is not visible but the user clicked
// the dock icon.
guard terminalManager.windows.count == 0 else { return true }
guard TerminalController.all.isEmpty else { return true }
// No visible windows, open a new one.
terminalManager.newWindow()
_ = TerminalController.newWindow(ghostty)
return false
}
@@ -358,16 +364,17 @@ class AppDelegate: NSObject,
var config = Ghostty.SurfaceConfiguration()
if (isDirectory.boolValue) {
// When opening a directory, create a new tab in the main window with that as the working directory.
// When opening a directory, create a new tab in the main
// window with that as the working directory.
// If no windows exist, a new one will be created.
config.workingDirectory = filename
terminalManager.newTab(withBaseConfig: config)
_ = TerminalController.newTab(ghostty, withBaseConfig: config)
} else {
// When opening a file, open a new window with that file as the command,
// and its parent directory as the working directory.
config.command = filename
config.workingDirectory = (filename as NSString).deletingLastPathComponent
terminalManager.newWindow(withBaseConfig: config)
_ = TerminalController.newWindow(ghostty, withBaseConfig: config)
}
return true
@@ -456,10 +463,6 @@ class AppDelegate: NSObject,
menu.keyEquivalentModifierMask = .init(swiftUIFlags: shortcut.modifiers)
}
private func focusedSurface() -> ghostty_surface_t? {
return terminalManager.focusedSurface?.surface
}
// MARK: Notifications and Events
/// This handles events from the NSEvent.addLocalEventMonitor. We use this so we can get
@@ -592,6 +595,22 @@ class AppDelegate: NSObject,
}
}
@objc private func ghosttyNewWindow(_ notification: Notification) {
let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey]
let config = configAny as? Ghostty.SurfaceConfiguration
_ = TerminalController.newWindow(ghostty, withBaseConfig: config)
}
@objc private func ghosttyNewTab(_ notification: Notification) {
guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return }
guard let window = surfaceView.window else { return }
let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey]
let config = configAny as? Ghostty.SurfaceConfiguration
_ = TerminalController.newTab(ghostty, from: window, withBaseConfig: config)
}
private func setDockBadge(_ label: String? = "") {
NSApp.dockTile.badgeLabel = label
NSApp.dockTile.display()
@@ -627,7 +646,7 @@ class AppDelegate: NSObject,
// Config could change keybindings, so update everything that depends on that
syncMenuShortcuts(config)
terminalManager.relabelAllTabs()
TerminalController.all.forEach { $0.relabelTabs() }
// Config could change window appearance. We wrap this in an async queue because when
// this is called as part of application launch it can deadlock with an internal
@@ -756,8 +775,8 @@ class AppDelegate: NSObject,
//MARK: - GhosttyAppDelegate
func findSurface(forUUID uuid: UUID) -> Ghostty.SurfaceView? {
for c in terminalManager.windows {
for view in c.controller.surfaceTree {
for c in TerminalController.all {
for view in c.surfaceTree {
if view.uuid == uuid {
return view
}
@@ -811,7 +830,7 @@ class AppDelegate: NSObject,
}
@IBAction func newWindow(_ sender: Any?) {
terminalManager.newWindow()
_ = TerminalController.newWindow(ghostty)
// We also activate our app so that it becomes front. This may be
// necessary for the dock menu.
@@ -819,7 +838,7 @@ class AppDelegate: NSObject,
}
@IBAction func newTab(_ sender: Any?) {
terminalManager.newTab()
_ = TerminalController.newTab(ghostty)
// We also activate our app so that it becomes front. This may be
// necessary for the dock menu.
@@ -827,7 +846,7 @@ class AppDelegate: NSObject,
}
@IBAction func closeAllWindows(_ sender: Any?) {
terminalManager.closeAllWindows()
TerminalController.closeAllWindows()
AboutController.shared.hide()
}