macos: set title of terminal window immediately if configured (#6056)

Fixes #5934 for macOS

If a `title` config is set, this change sets the title immediately on
windowDidLoad to ensure that the window appears with the correct title
right away.

If there is any reason to set another title, the `set_title` apprt
action will come on another event loop tick (due to our usage of
notifications) but that's okay since that's already how it works. This
is just to say that setting this here won't break any shell integration
or anything.
This commit is contained in:
Mitchell Hashimoto
2025-03-02 13:48:33 -08:00
committed by GitHub
2 changed files with 20 additions and 0 deletions

View File

@ -413,6 +413,14 @@ class BaseTerminalController: NSWindowController,
override func windowDidLoad() { override func windowDidLoad() {
guard let window else { return } guard let window else { return }
// If there is a hardcoded title in the configuration, we set that
// immediately. Future `set_title` apprt actions will override this
// if necessary but this ensures our window loads with the proper
// title immediately rather than on another event loop tick (see #5934)
if let title = derivedConfig.title {
window.title = title
}
// We always initialize our fullscreen style to native if we can because // We always initialize our fullscreen style to native if we can because
// initialization sets up some state (i.e. observers). If its set already // initialization sets up some state (i.e. observers). If its set already
// somehow we don't do this. // somehow we don't do this.
@ -617,17 +625,20 @@ class BaseTerminalController: NSWindowController,
} }
private struct DerivedConfig { private struct DerivedConfig {
let title: String?
let macosTitlebarProxyIcon: Ghostty.MacOSTitlebarProxyIcon let macosTitlebarProxyIcon: Ghostty.MacOSTitlebarProxyIcon
let windowStepResize: Bool let windowStepResize: Bool
let focusFollowsMouse: Bool let focusFollowsMouse: Bool
init() { init() {
self.title = nil
self.macosTitlebarProxyIcon = .visible self.macosTitlebarProxyIcon = .visible
self.windowStepResize = false self.windowStepResize = false
self.focusFollowsMouse = false self.focusFollowsMouse = false
} }
init(_ config: Ghostty.Config) { init(_ config: Ghostty.Config) {
self.title = config.title
self.macosTitlebarProxyIcon = config.macosTitlebarProxyIcon self.macosTitlebarProxyIcon = config.macosTitlebarProxyIcon
self.windowStepResize = config.windowStepResize self.windowStepResize = config.windowStepResize
self.focusFollowsMouse = config.focusFollowsMouse self.focusFollowsMouse = config.focusFollowsMouse

View File

@ -132,6 +132,15 @@ extension Ghostty {
return v return v
} }
var title: String? {
guard let config = self.config else { return nil }
var v: UnsafePointer<Int8>? = nil
let key = "title"
guard ghostty_config_get(config, &v, key, UInt(key.count)) else { return nil }
guard let ptr = v else { return nil }
return String(cString: ptr)
}
var windowSaveState: String { var windowSaveState: String {
guard let config = self.config else { return "" } guard let config = self.config else { return "" }
var v: UnsafePointer<Int8>? = nil var v: UnsafePointer<Int8>? = nil