Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions desktop/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ webkit2gtk = { version = "=2.0.2", features = ["v2_22"] }
block2 = { version = "0.6", default-features = false, features = ["std"] }
objc2 = { version = "0.6.4", default-features = false }
objc2-app-kit = { version = "0.3.2", default-features = false, features = ["NSEvent", "NSHapticFeedback", "NSMenu", "NSMenuItem", "NSStatusItem", "block2"] }
objc2-foundation = { version = "0.3.2", default-features = false, features = ["NSProcessInfo", "NSString"] }
objc2-foundation = { version = "0.3.2", default-features = false, features = ["NSDictionary", "NSError", "NSBundle", "NSObject", "NSProcessInfo", "NSString"] }
objc2-user-notifications = { version = "0.3.2", default-features = false, features = ["block2", "UNNotification", "UNNotificationContent", "UNNotificationRequest", "UNNotificationResponse", "UNNotificationSettings", "UNNotificationTrigger", "UNUserNotificationCenter"] }
keyring = { version = "3.6.3", default-features = false, features = ["apple-native", "vendored"], optional = true }
security-framework = { version = "3.7.0", features = ["OSX_10_15"] }
window-vibrancy = "0.6"
Expand Down
29 changes: 17 additions & 12 deletions desktop/src-tauri/src/commands/notifications.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Native (Linux) desktop-notification helper.
//! Native desktop-notification helpers.
//!
//! `tauri-plugin-notification` posts a notification by calling `notify_rust`'s
//! `show()` and then immediately dropping the returned `NotificationHandle`.
Expand All @@ -13,13 +13,15 @@
//! action, which we forward to the frontend so it can focus the window and
//! route to the notification target.

pub(crate) const NATIVE_NOTIFICATION_ACTIVATED_EVENT: &str = "native-notification-activated";

/// Show a desktop notification natively.
///
/// On Linux this uses the connection-preserving path described above. On other
/// platforms the bundled notification plugin already works correctly, so the
/// frontend never calls this and we simply report that it is unused.
/// Linux uses the connection-preserving D-Bus path described above. macOS uses
/// one application-lifetime `UNUserNotificationCenterDelegate`; it does not
/// allocate a listener or waiter for each notification.
#[tauri::command]
pub fn show_native_notification(
pub async fn show_native_notification(
app: tauri::AppHandle,
title: String,
body: Option<String>,
Expand All @@ -31,21 +33,24 @@ pub fn show_native_notification(
Ok(())
}

#[cfg(not(target_os = "linux"))]
#[cfg(target_os = "macos")]
{
let _ = app;
crate::macos_notifications::show(title, body, target).await
}

#[cfg(not(any(target_os = "linux", target_os = "macos")))]
{
let _ = (&app, &title, &body, &target);
Err("show_native_notification is only supported on Linux".to_string())
Err("show_native_notification is only supported on Linux and macOS".to_string())
}
}

#[cfg(target_os = "linux")]
mod linux {
use super::NATIVE_NOTIFICATION_ACTIVATED_EVENT;
use tauri::Emitter;

/// Emitted to the frontend when the user clicks a native notification. The
/// payload is the opaque target object the frontend passed in.
const ACTIVATE_EVENT: &str = "native-notification-activated";

pub fn show(
app: tauri::AppHandle,
title: String,
Expand Down Expand Up @@ -96,7 +101,7 @@ mod linux {

// The frontend focuses the window on activation (the same path
// every other platform uses), so we only forward the target.
let _ = app.emit(ACTIVATE_EVENT, target);
let _ = app.emit(NATIVE_NOTIFICATION_ACTIVATED_EVENT, target);
});
});
}
Expand Down
13 changes: 12 additions & 1 deletion desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ mod identity_storage;
mod initial_window;
mod key_backup;
mod linux_media;
#[cfg(target_os = "macos")]
mod macos_notifications;
mod managed_agents;
mod media_proxy;
#[cfg(feature = "mesh-llm")]
Expand Down Expand Up @@ -309,7 +311,10 @@ pub fn run() {
.setup(move |app| {
let app_handle = app.handle().clone();
#[cfg(target_os = "macos")]
tray_menu::init(&app_handle)?;
{
tray_menu::init(&app_handle)?;
macos_notifications::init(&app_handle)?;
}

// ── Phase 2: boot-time sentinel wipe ──────────────────────────────
// Must run before migrations and identity resolution so the wipe
Expand Down Expand Up @@ -720,6 +725,12 @@ pub fn run() {
remove_reaction,
get_event,
show_native_notification,
#[cfg(target_os = "macos")]
macos_notifications::take_pending_activations,
#[cfg(target_os = "macos")]
macos_notifications::notification_permission_state,
#[cfg(target_os = "macos")]
macos_notifications::request_notification_access,
upload_media,
pick_and_upload_media,
pick_and_upload_image,
Expand Down
Loading
Loading