macos: move title setting into a function to better encapsulate

This commit is contained in:
Mitchell Hashimoto
2024-12-12 16:43:10 -08:00
parent e35bd431f4
commit 4fdf5eb12b
2 changed files with 23 additions and 20 deletions

View File

@ -947,20 +947,7 @@ extension Ghostty {
guard let surface = target.target.surface else { return } guard let surface = target.target.surface else { return }
guard let surfaceView = self.surfaceView(from: surface) else { return } guard let surfaceView = self.surfaceView(from: surface) else { return }
guard let title = String(cString: v.title!, encoding: .utf8) else { return } guard let title = String(cString: v.title!, encoding: .utf8) else { return }
surfaceView.setTitle(title)
surfaceView.titleChangeTimer?.invalidate()
surfaceView.titleChangeTimer = Timer.scheduledTimer(
withTimeInterval: surfaceView.titleChangeDelay,
repeats: false
) { _ in
// We must set this in a dispatchqueue to avoid a deadlock on startup on some
// versions of macOS. I unfortunately didn't document the exact versions so
// I don't know when its safe to remove this.
DispatchQueue.main.async {
surfaceView.title = title
}
}
default: default:
assertionFailure() assertionFailure()
@ -1095,7 +1082,10 @@ extension Ghostty {
guard let surface = target.target.surface else { return } guard let surface = target.target.surface else { return }
guard let surfaceView = self.surfaceView(from: surface) else { return } guard let surfaceView = self.surfaceView(from: surface) else { return }
let backingSize = NSSize(width: Double(v.width), height: Double(v.height)) let backingSize = NSSize(width: Double(v.width), height: Double(v.height))
surfaceView.cellSize = surfaceView.convertFromBacking(backingSize) DispatchQueue.main.async { [weak surfaceView] in
guard let surfaceView else { return }
surfaceView.cellSize = surfaceView.convertFromBacking(backingSize)
}
default: default:
assertionFailure() assertionFailure()

View File

@ -12,11 +12,7 @@ extension Ghostty {
// The current title of the surface as defined by the pty. This can be // The current title of the surface as defined by the pty. This can be
// changed with escape codes. This is public because the callbacks go // changed with escape codes. This is public because the callbacks go
// to the app level and it is set from there. // to the app level and it is set from there.
@Published var title: String = "👻" @Published private(set) var title: String = "👻"
// A small delay that is introduced before a title change to avoid flickers
var titleChangeDelay: TimeInterval = 0.075
var titleChangeTimer: Timer?
// The current pwd of the surface as defined by the pty. This can be // The current pwd of the surface as defined by the pty. This can be
// changed with escape codes. // changed with escape codes.
@ -114,6 +110,9 @@ extension Ghostty {
// This is set to non-null during keyDown to accumulate insertText contents // This is set to non-null during keyDown to accumulate insertText contents
private var keyTextAccumulator: [String]? = nil private var keyTextAccumulator: [String]? = nil
// A small delay that is introduced before a title change to avoid flickers
private var titleChangeTimer: Timer?
// We need to support being a first responder so that we can get input events // We need to support being a first responder so that we can get input events
override var acceptsFirstResponder: Bool { return true } override var acceptsFirstResponder: Bool { return true }
@ -343,6 +342,20 @@ extension Ghostty {
NSCursor.setHiddenUntilMouseMoves(!visible) NSCursor.setHiddenUntilMouseMoves(!visible)
} }
func setTitle(_ title: String) {
// This fixes an issue where very quick changes to the title could
// cause an unpleasant flickering. We set a timer so that we can
// coalesce rapid changes. The timer is short enough that it still
// feels "instant".
titleChangeTimer?.invalidate()
titleChangeTimer = Timer.scheduledTimer(
withTimeInterval: 0.075,
repeats: false
) { [weak self] _ in
self?.title = title
}
}
// MARK: - Notifications // MARK: - Notifications
@objc private func onUpdateRendererHealth(notification: SwiftUI.Notification) { @objc private func onUpdateRendererHealth(notification: SwiftUI.Notification) {