mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-21 17:21:52 +00:00
macos: change config access to evented, derived config like libghostty
Previously, we would access the `ghostty.config` object from anywhere. The issue with this is that memory lifetime access to the underlying `ghostty_config_t` was messy. It was easy when the apprt owned every reference but since automatic theme changes were implemented, this isn't always true anymore. To fix this, we move to the same pattern we use internally in the core of ghostty: whenever the config changes, we handle an event, derive our desired values out of the config (copy them), and then let the caller free the config if they want to. This way, we can be sure that any information we need from the config is always owned by us.
This commit is contained in:
@@ -60,6 +60,9 @@ class BaseTerminalController: NSWindowController,
|
||||
/// The previous frame information from the window
|
||||
private var savedFrame: SavedFrame? = nil
|
||||
|
||||
/// The configuration derived from the Ghostty config so we don't need to rely on references.
|
||||
private var derivedConfig: DerivedConfig
|
||||
|
||||
struct SavedFrame {
|
||||
let window: NSRect
|
||||
let screen: NSRect
|
||||
@@ -74,6 +77,7 @@ class BaseTerminalController: NSWindowController,
|
||||
surfaceTree tree: Ghostty.SplitNode? = nil
|
||||
) {
|
||||
self.ghostty = ghostty
|
||||
self.derivedConfig = DerivedConfig(ghostty.config)
|
||||
|
||||
super.init(window: nil)
|
||||
|
||||
@@ -93,6 +97,11 @@ class BaseTerminalController: NSWindowController,
|
||||
selector: #selector(didChangeScreenParametersNotification),
|
||||
name: NSApplication.didChangeScreenParametersNotification,
|
||||
object: nil)
|
||||
center.addObserver(
|
||||
self,
|
||||
selector: #selector(ghosttyConfigDidChangeBase(_:)),
|
||||
name: .ghosttyConfigDidChange,
|
||||
object: nil)
|
||||
|
||||
// Listen for local events that we need to know of outside of
|
||||
// single surface handlers.
|
||||
@@ -191,6 +200,20 @@ class BaseTerminalController: NSWindowController,
|
||||
window.setFrame(newFrame, display: true)
|
||||
}
|
||||
|
||||
@objc private func ghosttyConfigDidChangeBase(_ notification: Notification) {
|
||||
// We only care if the configuration is a global configuration, not a
|
||||
// surface-specific one.
|
||||
guard notification.object == nil else { return }
|
||||
|
||||
// Get our managed configuration object out
|
||||
guard let config = notification.userInfo?[
|
||||
Notification.Name.GhosttyConfigChangeKey
|
||||
] as? Ghostty.Config else { return }
|
||||
|
||||
// Update our derived config
|
||||
self.derivedConfig = DerivedConfig(config)
|
||||
}
|
||||
|
||||
// MARK: Local Events
|
||||
|
||||
private func localEventHandler(_ event: NSEvent) -> NSEvent? {
|
||||
@@ -245,7 +268,7 @@ class BaseTerminalController: NSWindowController,
|
||||
func pwdDidChange(to: URL?) {
|
||||
guard let window else { return }
|
||||
|
||||
if ghostty.config.macosTitlebarProxyIcon == .visible {
|
||||
if derivedConfig.macosTitlebarProxyIcon == .visible {
|
||||
// Use the 'to' URL directly
|
||||
window.representedURL = to
|
||||
} else {
|
||||
@@ -255,7 +278,7 @@ class BaseTerminalController: NSWindowController,
|
||||
|
||||
|
||||
func cellSizeDidChange(to: NSSize) {
|
||||
guard ghostty.config.windowStepResize else { return }
|
||||
guard derivedConfig.windowStepResize else { return }
|
||||
self.window?.contentResizeIncrements = to
|
||||
}
|
||||
|
||||
@@ -563,4 +586,19 @@ class BaseTerminalController: NSWindowController,
|
||||
guard let surface = focusedSurface?.surface else { return }
|
||||
ghostty.resetTerminal(surface: surface)
|
||||
}
|
||||
|
||||
private struct DerivedConfig {
|
||||
let macosTitlebarProxyIcon: Ghostty.MacOSTitlebarProxyIcon
|
||||
let windowStepResize: Bool
|
||||
|
||||
init() {
|
||||
self.macosTitlebarProxyIcon = .visible
|
||||
self.windowStepResize = false
|
||||
}
|
||||
|
||||
init(_ config: Ghostty.Config) {
|
||||
self.macosTitlebarProxyIcon = config.macosTitlebarProxyIcon
|
||||
self.windowStepResize = config.windowStepResize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user