Conversation
Notifications triggered from inside Rio were delivered silently on macOS: they appeared in Notification Center but never showed a banner. A terminal notification is emitted by a program running inside the terminal, so Rio is the frontmost app when the notification is posted. Under the UserNotifications framework, a notification arriving while its own app is in the foreground is presented only if the center's delegate implements userNotificationCenter:willPresentNotification: and calls the completion handler with presentation options. Rio never installed a delegate, so every notification was delivered without being presented. Declare a minimal UNUserNotificationCenterDelegate that asks for Banner | List | Sound, and assign it in request_authorization(), which runs from Application::new before the event loop starts and therefore before the app finishes launching. UNNotification is added to the objc2-user-notifications features because willPresentNotification is gated on it and it is not implied by the features already enabled. Closes raphamorim#1831 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
KennethLj
force-pushed
the
fix/macos-notification-banner
branch
from
August 8, 2026 09:04
0f996cf to
a2ea99c
Compare
Author
|
Heads-up on the red check here: it is not caused by this PR. The failure is This branch touches only #1833 fixes the formatting on its own, and this should go green once that lands and this branch is rebased. Happy to rebase whenever suits you. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1831.
On macOS, notifications triggered from inside Rio (OSC 9 / OSC 777) are delivered but never presented: no banner appears, and the notification is only discoverable by opening Notification Center.
A terminal notification is emitted by a program running inside the terminal, so Rio is the frontmost app at the moment it is posted. Under the UserNotifications framework a notification arriving while its own app is in the foreground is presented only if the center's delegate implements
userNotificationCenter(_:willPresent:withCompletionHandler:)and calls the completion handler with presentation options.rio-notifiernever installed a delegate, so every notification was delivered without being presented.The change
rio-notifier/src/lib.rs: declare a minimalUNUserNotificationCenterDelegatethat asks forBanner | List | Sound, and assign it withsetDelegateinside the existingOnceinrequest_authorization(). The center holds its delegate weakly, so the object is deliberately leaked for the lifetime of the process.rio-notifier/Cargo.toml: addUNNotificationto theobjc2-user-notificationsfeatures —willPresentNotificationis gated on it and it is not implied by the features already enabled.No dependency bumps: everything needed already exists in the pinned
objc20.5.2 /objc2-user-notifications0.2.2.Apple's guidance is to assign the delegate before the app finishes launching.
request_authorization()is called fromApplication::new(frontends/rioterm/src/main.rs:242), which runs beforeapplication.run(window_event_loop)on line 248, so this is satisfied without touchingrioterm.Verification
Manually verified on macOS 26.6 (Apple Silicon), since there is no automated coverage for notification presentation.
A release build was bundled from
misc/osx/Rio.app, given its own bundle identifier, signed, installed to/Applicationsand launched through LaunchServices, then driven withprintf '\033]777;notify;BannerTest N;patched delegate\a'on a timer. The screen was captured every 3s and each frame checked for both the banner and the frontmost app in the menu bar.With the patched build frontmost, every fire produced a banner. Frames where focus had moved to another Rio window were discarded — a backgrounded app banners regardless of the delegate, so those prove nothing.
Worth noting for anyone reproducing this: an ad-hoc signed bundle is refused by the notification daemon (
requestAuthorizationreturnsgranted=falseand everyaddNotificationRequestreturns an error), so nothing is delivered at all and the result looks like a failure of the patch. A real signing identity is needed to test this.Notes
didReceiveNotificationResponse(focusing the window/tab when a notification is clicked) is deliberately out of scope; it seems better as a separate change.