mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-14 03:25:50 +00:00
macos: further simplication of AppDelegate bell state
This commit is contained in:
@@ -151,9 +151,6 @@ class AppDelegate: NSObject,
|
||||
/// Signals
|
||||
private var signals: [DispatchSourceSignal] = []
|
||||
|
||||
/// Current bell state keyed by terminal controller identity.
|
||||
private var windowBellStates: [ObjectIdentifier: Bool] = [:]
|
||||
|
||||
/// Cached permission state for dock badges.
|
||||
private var canShowDockBadgeForBell: Bool = false
|
||||
|
||||
@@ -234,12 +231,6 @@ class AppDelegate: NSObject,
|
||||
name: NSWindow.didBecomeKeyNotification,
|
||||
object: nil
|
||||
)
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(windowWillClose),
|
||||
name: NSWindow.willCloseNotification,
|
||||
object: nil
|
||||
)
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(quickTerminalDidChangeVisibility),
|
||||
@@ -773,14 +764,6 @@ class AppDelegate: NSObject,
|
||||
syncFloatOnTopMenu(notification.object as? NSWindow)
|
||||
}
|
||||
|
||||
@objc private func windowWillClose(_ notification: Notification) {
|
||||
guard let window = notification.object as? NSWindow,
|
||||
let controller = window.windowController as? BaseTerminalController else { return }
|
||||
|
||||
windowBellStates[ObjectIdentifier(controller)] = nil
|
||||
syncDockBadgeToTrackedBellState()
|
||||
}
|
||||
|
||||
@objc private func quickTerminalDidChangeVisibility(_ notification: Notification) {
|
||||
guard let quickController = notification.object as? QuickTerminalController else { return }
|
||||
self.menuQuickTerminal?.state = if quickController.visible { .on } else { .off }
|
||||
@@ -813,15 +796,14 @@ class AppDelegate: NSObject,
|
||||
}
|
||||
|
||||
@objc private func terminalWindowHasBell(_ notification: Notification) {
|
||||
guard let controller = notification.object as? BaseTerminalController,
|
||||
let hasBell = notification.userInfo?[Notification.Name.terminalWindowHasBellKey] as? Bool else { return }
|
||||
|
||||
windowBellStates[ObjectIdentifier(controller)] = hasBell
|
||||
guard notification.object is BaseTerminalController else { return }
|
||||
syncDockBadgeToTrackedBellState()
|
||||
}
|
||||
|
||||
private func syncDockBadgeToTrackedBellState() {
|
||||
let anyBell = windowBellStates.values.contains(true)
|
||||
let anyBell = NSApp.windows
|
||||
.compactMap { $0.windowController as? BaseTerminalController }
|
||||
.contains { $0.bell }
|
||||
let wantsBadge = ghostty.config.bellFeatures.contains(.attention) && anyBell
|
||||
|
||||
if wantsBadge && !canShowDockBadgeForBell && !hasRequestedDockBadgeAuthorization {
|
||||
|
||||
@@ -51,6 +51,9 @@ class BaseTerminalController: NSWindowController,
|
||||
/// Set if the terminal view should show the update overlay.
|
||||
@Published var updateOverlayIsVisible: Bool = false
|
||||
|
||||
/// True when any surface in this controller currently has an active bell.
|
||||
@Published private(set) var bell: Bool = false
|
||||
|
||||
/// Whether the terminal surface should focus when the mouse is over it.
|
||||
var focusFollowsMouse: Bool {
|
||||
self.derivedConfig.focusFollowsMouse
|
||||
@@ -137,7 +140,7 @@ class BaseTerminalController: NSWindowController,
|
||||
// Initialize our initial surface.
|
||||
guard let ghostty_app = ghostty.app else { preconditionFailure("app must be loaded") }
|
||||
self.surfaceTree = tree ?? .init(view: Ghostty.SurfaceView(ghostty_app, baseConfig: base))
|
||||
|
||||
|
||||
// Setup our bell state for the window
|
||||
setupBellNotificationPublisher()
|
||||
|
||||
@@ -1206,6 +1209,17 @@ class BaseTerminalController: NSWindowController,
|
||||
func windowWillClose(_ notification: Notification) {
|
||||
guard let window else { return }
|
||||
|
||||
// Emit a final bell-state transition so any observers can clear state
|
||||
// without separately tracking NSWindow lifecycle events.
|
||||
if bell {
|
||||
bell = false
|
||||
NotificationCenter.default.post(
|
||||
name: .terminalWindowBellDidChangeNotification,
|
||||
object: self,
|
||||
userInfo: [Notification.Name.terminalWindowHasBellKey: false]
|
||||
)
|
||||
}
|
||||
|
||||
// I don't know if this is required anymore. We previously had a ref cycle between
|
||||
// the view and the window so we had to nil this out to break it but I think this
|
||||
// may now be resolved. We should verify that no memory leaks and we can remove this.
|
||||
@@ -1486,8 +1500,10 @@ extension BaseTerminalController {
|
||||
bellStateCancellable = surfaceValuesPublisher(valueKeyPath: \.bell, publisherKeyPath: \.$bell)
|
||||
.map { $0.values.contains(true) }
|
||||
.removeDuplicates()
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] hasBell in
|
||||
guard let self else { return }
|
||||
bell = hasBell
|
||||
NotificationCenter.default.post(
|
||||
name: .terminalWindowBellDidChangeNotification,
|
||||
object: self,
|
||||
|
||||
Reference in New Issue
Block a user