macos: command finished notifications always show up

This commit is contained in:
Mitchell Hashimoto
2026-02-26 13:40:34 -08:00
parent f4ddddc4b7
commit a5909dfa1d
2 changed files with 25 additions and 5 deletions

View File

@@ -433,10 +433,17 @@ extension Ghostty {
/// Determine if a given notification should be presented to the user when Ghostty is running in the foreground.
func shouldPresentNotification(notification: UNNotification) -> Bool {
let userInfo = notification.request.content.userInfo
// We always require the notification to be attached to a surface.
guard let uuidString = userInfo["surface"] as? String,
let uuid = UUID(uuidString: uuidString),
let surface = delegate?.findSurface(forUUID: uuid),
let window = surface.window else { return false }
// If we don't require focus then we're good!
let requireFocus = userInfo["requireFocus"] as? Bool ?? true
if !requireFocus { return true }
return !window.isKeyWindow || !surface.focused
}
@@ -1374,7 +1381,8 @@ extension Ghostty {
private static func showDesktopNotification(
_ surfaceView: SurfaceView,
title: String,
body: String) {
body: String,
requireFocus: Bool = true) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { _, error in
if let error = error {
@@ -1384,7 +1392,11 @@ extension Ghostty {
center.getNotificationSettings { settings in
guard settings.authorizationStatus == .authorized else { return }
surfaceView.showUserNotification(title: title, body: body)
surfaceView.showUserNotification(
title: title,
body: body,
requireFocus: requireFocus
)
}
}
@@ -1452,7 +1464,12 @@ extension Ghostty {
body = "Command took \(formattedDuration) and exited with code \(v.exit_code)."
}
showDesktopNotification(surfaceView, title: title, body: body)
showDesktopNotification(
surfaceView,
title: title,
body: body,
requireFocus: false
)
}
default:

View File

@@ -1632,14 +1632,17 @@ extension Ghostty {
}
/// Show a user notification and associate it with this surface
func showUserNotification(title: String, body: String) {
func showUserNotification(title: String, body: String, requireFocus: Bool = true) {
let content = UNMutableNotificationContent()
content.title = title
content.subtitle = self.title
content.body = body
content.sound = UNNotificationSound.default
content.categoryIdentifier = Ghostty.userNotificationCategory
content.userInfo = ["surface": self.id.uuidString]
content.userInfo = [
"surface": self.id.uuidString,
"requireFocus": requireFocus,
]
let uuid = UUID().uuidString
let request = UNNotificationRequest(