Problem
On macOS 26 (Tahoe, Darwin 25.x), the current NotificationWatcher.swift does not detect any notifications. The AXObserver watching kAXWindowCreatedNotification on the com.apple.notificationcenterui process never fires — Apple changed how notification banners are rendered internally, so the Accessibility event is no longer emitted.
This means system notification haptics don't work at all on macOS 26, even though the Logi Options+ Smart Action and HapticEngine are working fine.
Root Cause
AXObserverCreate + kAXWindowCreatedNotification on the NotificationCenter process relied on macOS creating an AX-visible window for each notification banner. As of macOS 26, this no longer happens.
Fix
Replace the AXObserver approach with a /usr/bin/log stream watcher. The macOS unified log reliably emits an "Adding notification to storage" message in the NotificationCenter process for every delivered notification — including native app notifications (Claude, Mail, etc.) and Safari web notifications (_WEB_CENTER_: entries like Google Chat).
Replacement NotificationWatcher.swift
import Foundation
class NotificationWatcher {
static let shared = NotificationWatcher()
private var process: Process?
func start() {
DispatchQueue.global(qos: .utility).async {
self.startLogStream()
}
}
private func startLogStream() {
let proc = Process()
proc.executableURL = URL(fileURLWithPath: "/usr/bin/log")
proc.arguments = [
"stream",
"--predicate",
"process == \"NotificationCenter\" AND composedMessage CONTAINS \"Adding notification to storage\""
]
let pipe = Pipe()
proc.standardOutput = pipe
proc.standardError = FileHandle.nullDevice
pipe.fileHandleForReading.readabilityHandler = { handle in
let data = handle.availableData
guard !data.isEmpty, let line = String(data: data, encoding: .utf8) else { return }
for entry in line.components(separatedBy: .newlines) where entry.contains("Adding notification to storage") {
if UserDefaults.standard.bool(forKey: "systemNotificationsEnabled") == false {
continue
}
print("Notification Detected: \(entry)")
let pattern = UserDefaults.standard.string(forKey: "notificationPattern") ?? "pulse"
if pattern != "none" {
HapticEngine.shared.playPattern(pattern)
}
}
}
do {
try proc.run()
self.process = proc
print("Listening for notifications via log stream...")
proc.waitUntilExit()
} catch {
print("Failed to start log stream: \(error)")
}
}
}
Testing
Tested on macOS 26.4.1 (Build 25E253) with MX Master 4. Confirmed via log stream that the following notification sources all produce the "Adding notification to storage" event:
- Safari web notifications —
_WEB_CENTER_:web.mail.google.com (Google Chat)
- Claude desktop —
com.anthropic.claudefordesktop
- Apple Mail —
com.apple.mail
All triggered haptic feedback successfully after the fix.
Notes
- This also removes the dependency on
Cocoa and ApplicationServices imports (only Foundation is needed)
- The
AXObserver approach may still work on older macOS versions, so a version check fallback could be considered
- The
log stream approach requires no additional entitlements beyond the existing Accessibility permission
Problem
On macOS 26 (Tahoe, Darwin 25.x), the current
NotificationWatcher.swiftdoes not detect any notifications. TheAXObserverwatchingkAXWindowCreatedNotificationon thecom.apple.notificationcenteruiprocess never fires — Apple changed how notification banners are rendered internally, so the Accessibility event is no longer emitted.This means system notification haptics don't work at all on macOS 26, even though the Logi Options+ Smart Action and HapticEngine are working fine.
Root Cause
AXObserverCreate+kAXWindowCreatedNotificationon the NotificationCenter process relied on macOS creating an AX-visible window for each notification banner. As of macOS 26, this no longer happens.Fix
Replace the AXObserver approach with a
/usr/bin/log streamwatcher. The macOS unified log reliably emits an"Adding notification to storage"message in theNotificationCenterprocess for every delivered notification — including native app notifications (Claude, Mail, etc.) and Safari web notifications (_WEB_CENTER_:entries like Google Chat).Replacement
NotificationWatcher.swiftTesting
Tested on macOS 26.4.1 (Build 25E253) with MX Master 4. Confirmed via
log streamthat the following notification sources all produce the"Adding notification to storage"event:_WEB_CENTER_:web.mail.google.com(Google Chat)com.anthropic.claudefordesktopcom.apple.mailAll triggered haptic feedback successfully after the fix.
Notes
CocoaandApplicationServicesimports (onlyFoundationis needed)AXObserverapproach may still work on older macOS versions, so a version check fallback could be consideredlog streamapproach requires no additional entitlements beyond the existing Accessibility permission