Skip to content

Add sound support for desktop notifications in Tauri v2 #2678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: v2
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions plugins/notification/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## \[Unreleased]

- Added sound support for desktop notifications which was previously only available on mobile platforms.

## \[2.2.2]

- [`a1b3fa27`](https://github.com/tauri-apps/plugins-workspace/commit/a1b3fa27f11022c9b6622b4fab12d93239eb05de) ([#2515](https://github.com/tauri-apps/plugins-workspace/pull/2515) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Re-exported the `Geolocation`, `Haptics`, `Notification`, and `Os` structs so that they show up on docs.rs.
Expand Down
38 changes: 38 additions & 0 deletions plugins/notification/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,44 @@ export async function enqueueNotification(title, body) {
}
```

### Notification with Sound

You can add sound to your notifications on all platforms (desktop and mobile):

```javascript
import { sendNotification } from '@tauri-apps/plugin-notification'

// Basic notification with sound
sendNotification({
title: 'New Message',
body: 'You have a new message',
sound: 'notification.wav' // Path to sound file
})

// Platform-specific sounds
async function sendPlatformSpecificNotification() {
const platform = await import('@tauri-apps/api/os').then(os => os.platform())

let soundPath
if (platform === 'darwin') {
// On macOS: use system sounds or sound files in the app bundle
soundPath = 'Ping' // macOS system sound
} else if (platform === 'linux') {
// On Linux: use XDG theme sounds or file paths
soundPath = 'message-new-instant' // XDG theme sound
} else {
// On Windows: use file paths
soundPath = 'notification.wav'
}

sendNotification({
title: 'Platform-specific Notification',
body: 'This notification uses platform-specific sound',
sound: soundPath
})
}
```

## Contributing

PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
Expand Down
8 changes: 7 additions & 1 deletion plugins/notification/guest-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,13 @@ interface Options {
*/
groupSummary?: boolean
/**
* The sound resource name. Only available on mobile.
* The sound resource name or file path for the notification.
*
* Platform specific behavior:
* - On macOS: use system sounds (e.g., "Ping", "Blow") or sound files in the app bundle
* - On Linux: use XDG theme sounds (e.g., "message-new-instant") or file paths
* - On Windows: use file paths to sound files (.wav format)
* - On Mobile: use resource names
*/
sound?: string
/**
Expand Down
20 changes: 20 additions & 0 deletions plugins/notification/src/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ impl<R: Runtime> crate::NotificationBuilder<R> {
if let Some(icon) = self.data.icon {
notification = notification.icon(icon);
}
if let Some(sound) = self.data.sound {
notification = notification.sound(sound);
}
#[cfg(feature = "windows7-compat")]
{
notification.notify(&self.app)?;
Expand Down Expand Up @@ -102,6 +105,8 @@ mod imp {
title: Option<String>,
/// The notification icon.
icon: Option<String>,
/// The notification sound.
sound: Option<String>,
/// The notification identifier
identifier: String,
}
Expand Down Expand Up @@ -136,6 +141,13 @@ mod imp {
self
}

/// Sets the notification sound file.
#[must_use]
pub fn sound(mut self, sound: impl Into<String>) -> Self {
self.sound = Some(sound.into());
self
}

/// Shows the notification.
///
/// # Examples
Expand Down Expand Up @@ -177,6 +189,9 @@ mod imp {
} else {
notification.auto_icon();
}
if let Some(sound) = self.sound {
notification.sound_name(&sound);
}
#[cfg(windows)]
{
let exe = tauri::utils::platform::current_exe()?;
Expand Down Expand Up @@ -250,6 +265,7 @@ mod imp {
}
}

/// Shows the notification on Windows 7.
#[cfg(all(windows, feature = "windows7-compat"))]
fn notify_win7<R: tauri::Runtime>(self, app: &tauri::AppHandle<R>) -> crate::Result<()> {
let app_ = app.clone();
Expand All @@ -264,6 +280,10 @@ mod imp {
if let Some(icon) = app_.default_window_icon() {
notification.icon(icon.rgba().to_vec(), icon.width(), icon.height());
}
// Enable sound if specified
if self.sound.is_some() {
notification.sound(true);
}
let _ = notification.show();
});

Expand Down
2 changes: 1 addition & 1 deletion plugins/notification/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl<R: Runtime> NotificationBuilder<R> {
self
}

/// The sound resource name. Only available on mobile.
/// The sound resource name for the notification.
pub fn sound(mut self, sound: impl Into<String>) -> Self {
self.data.sound.replace(sound.into());
self
Expand Down
115 changes: 115 additions & 0 deletions plugins/notification/test/sound-notification.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tauri Notification Sound Test</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
padding: 20px;
max-width: 800px;
margin: 0 auto;
background-color: #f5f5f5;
}
.container {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #0066cc;
}
button {
background-color: #0066cc;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
margin: 5px;
cursor: pointer;
transition: background-color 0.2s;
}
button:hover {
background-color: #004999;
}
.info {
background-color: #e6f7ff;
border-left: 4px solid #0066cc;
padding: 10px;
margin-bottom: 20px;
}
pre {
background-color: #f1f1f1;
padding: 10px;
border-radius: 4px;
overflow-x: auto;
}
</style>
</head>
<body>
<div class="container">
<h1>Tauri Notifications with Sound</h1>

<div class="info">
<p>This demo shows how to use sound with Tauri notifications across different platforms.</p>
<p>Make sure you have the notification plugin installed and configured correctly.</p>
</div>

<h2>Test Notifications</h2>
<button id="systemSound">Show Notification with System Sound</button>
<button id="customSound">Show Notification with Custom Sound</button>
<button id="platformSpecific">Show Platform-Specific Sound Notification</button>

<h2>Example Code</h2>
<pre>
// Example with system sound (mainly for macOS)
await sendNotification({
title: 'Notification with System Sound',
body: 'This notification uses a system sound on macOS.',
sound: 'Ping' // macOS system sound
});

// Example with custom sound file
await sendNotification({
title: 'Notification with Custom Sound',
body: 'This notification uses a custom sound file.',
sound: 'notification.wav' // path to your sound file
});

// Example with different sounds based on platform
const platform = await import('@tauri-apps/api/os').then(os => os.platform());

let soundPath;
if (platform === 'darwin') {
soundPath = 'Blow'; // macOS system sound
} else if (platform === 'linux') {
soundPath = 'message-new-instant'; // XDG theme sound
} else {
soundPath = 'notification.wav'; // Custom sound file for Windows
}

await sendNotification({
title: 'Platform-specific Sound',
body: `This notification uses platform-specific sound settings for ${platform}.`,
sound: soundPath
});</pre>
</div>

<script src="sound-notification.js"></script>
<script>
document.getElementById('systemSound').addEventListener('click', () => {
window.showNotificationWithSystemSound();
});

document.getElementById('customSound').addEventListener('click', () => {
window.showNotificationWithCustomSound();
});

document.getElementById('platformSpecific').addEventListener('click', () => {
window.showNotificationWithPlatformSpecificSound();
});
</script>
</body>
</html>
64 changes: 64 additions & 0 deletions plugins/notification/test/sound-notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

/**
* This file demonstrates how to use sound with notifications in Tauri v2.
*
* On macOS:
* - Sound file should be in your application bundle
* - Use the sound name without extension
* - Or use system sounds like "Ping", "Basso", "Blow", "Bottle", "Frog", "Funk", "Glass", etc.
*
* On Linux:
* - Use a file path to a sound file (e.g., .wav file)
* - Or use XDG theme sounds by name (e.g., "message-new-instant")
*
* On Windows:
* - Use a file path to a sound file (e.g., .wav file)
*/

import { sendNotification } from '@tauri-apps/api/notification';

// Example with system sound (macOS)
async function showNotificationWithSystemSound() {
await sendNotification({
title: 'Notification with System Sound',
body: 'This notification uses a system sound on macOS.',
sound: 'Ping' // macOS system sound
});
}

// Example with custom sound file
async function showNotificationWithCustomSound() {
await sendNotification({
title: 'Notification with Custom Sound',
body: 'This notification uses a custom sound file.',
sound: 'notification.wav' // path to your sound file
});
}

// Example with different sounds based on platform
async function showNotificationWithPlatformSpecificSound() {
const platform = await import('@tauri-apps/api/os').then(os => os.platform());

let soundPath;
if (platform === 'darwin') {
soundPath = 'Blow'; // macOS system sound
} else if (platform === 'linux') {
soundPath = 'message-new-instant'; // XDG theme sound
} else {
soundPath = 'notification.wav'; // Custom sound file for Windows
}

await sendNotification({
title: 'Platform-specific Sound',
body: `This notification uses platform-specific sound settings for ${platform}.`,
sound: soundPath
});
}

// Export functions to be called from HTML
window.showNotificationWithSystemSound = showNotificationWithSystemSound;
window.showNotificationWithCustomSound = showNotificationWithCustomSound;
window.showNotificationWithPlatformSpecificSound = showNotificationWithPlatformSpecificSound;
Loading