Skip to content

Commit 470f558

Browse files
committed
Add sound support for desktop notifications in Tauri v2
1 parent 98e268a commit 470f558

File tree

7 files changed

+249
-2
lines changed

7 files changed

+249
-2
lines changed

plugins/notification/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## \[Unreleased]
4+
5+
- Added sound support for desktop notifications which was previously only available on mobile platforms.
6+
37
## \[2.2.2]
48

59
- [`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.

plugins/notification/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,44 @@ export async function enqueueNotification(title, body) {
104104
}
105105
```
106106

107+
### Notification with Sound
108+
109+
You can add sound to your notifications on all platforms (desktop and mobile):
110+
111+
```javascript
112+
import { sendNotification } from '@tauri-apps/plugin-notification'
113+
114+
// Basic notification with sound
115+
sendNotification({
116+
title: 'New Message',
117+
body: 'You have a new message',
118+
sound: 'notification.wav' // Path to sound file
119+
})
120+
121+
// Platform-specific sounds
122+
async function sendPlatformSpecificNotification() {
123+
const platform = await import('@tauri-apps/api/os').then(os => os.platform())
124+
125+
let soundPath
126+
if (platform === 'darwin') {
127+
// On macOS: use system sounds or sound files in the app bundle
128+
soundPath = 'Ping' // macOS system sound
129+
} else if (platform === 'linux') {
130+
// On Linux: use XDG theme sounds or file paths
131+
soundPath = 'message-new-instant' // XDG theme sound
132+
} else {
133+
// On Windows: use file paths
134+
soundPath = 'notification.wav'
135+
}
136+
137+
sendNotification({
138+
title: 'Platform-specific Notification',
139+
body: 'This notification uses platform-specific sound',
140+
sound: soundPath
141+
})
142+
}
143+
```
144+
107145
## Contributing
108146

109147
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.

plugins/notification/guest-js/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,13 @@ interface Options {
7171
*/
7272
groupSummary?: boolean
7373
/**
74-
* The sound resource name. Only available on mobile.
74+
* The sound resource name or file path for the notification.
75+
*
76+
* Platform specific behavior:
77+
* - On macOS: use system sounds (e.g., "Ping", "Blow") or sound files in the app bundle
78+
* - On Linux: use XDG theme sounds (e.g., "message-new-instant") or file paths
79+
* - On Windows: use file paths to sound files (.wav format)
80+
* - On Mobile: use resource names
7581
*/
7682
sound?: string
7783
/**

plugins/notification/src/desktop.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ impl<R: Runtime> crate::NotificationBuilder<R> {
3939
if let Some(icon) = self.data.icon {
4040
notification = notification.icon(icon);
4141
}
42+
if let Some(sound) = self.data.sound {
43+
notification = notification.sound(sound);
44+
}
4245
#[cfg(feature = "windows7-compat")]
4346
{
4447
notification.notify(&self.app)?;
@@ -102,6 +105,8 @@ mod imp {
102105
title: Option<String>,
103106
/// The notification icon.
104107
icon: Option<String>,
108+
/// The notification sound.
109+
sound: Option<String>,
105110
/// The notification identifier
106111
identifier: String,
107112
}
@@ -136,6 +141,13 @@ mod imp {
136141
self
137142
}
138143

144+
/// Sets the notification sound file.
145+
#[must_use]
146+
pub fn sound(mut self, sound: impl Into<String>) -> Self {
147+
self.sound = Some(sound.into());
148+
self
149+
}
150+
139151
/// Shows the notification.
140152
///
141153
/// # Examples
@@ -177,6 +189,9 @@ mod imp {
177189
} else {
178190
notification.auto_icon();
179191
}
192+
if let Some(sound) = self.sound {
193+
notification.sound_name(&sound);
194+
}
180195
#[cfg(windows)]
181196
{
182197
let exe = tauri::utils::platform::current_exe()?;
@@ -250,6 +265,7 @@ mod imp {
250265
}
251266
}
252267

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

plugins/notification/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<R: Runtime> NotificationBuilder<R> {
132132
self
133133
}
134134

135-
/// The sound resource name. Only available on mobile.
135+
/// The sound resource name for the notification.
136136
pub fn sound(mut self, sound: impl Into<String>) -> Self {
137137
self.data.sound.replace(sound.into());
138138
self
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Tauri Notification Sound Test</title>
7+
<style>
8+
body {
9+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
10+
padding: 20px;
11+
max-width: 800px;
12+
margin: 0 auto;
13+
background-color: #f5f5f5;
14+
}
15+
.container {
16+
background-color: white;
17+
padding: 20px;
18+
border-radius: 8px;
19+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
20+
}
21+
h1 {
22+
color: #0066cc;
23+
}
24+
button {
25+
background-color: #0066cc;
26+
color: white;
27+
border: none;
28+
padding: 10px 15px;
29+
border-radius: 4px;
30+
margin: 5px;
31+
cursor: pointer;
32+
transition: background-color 0.2s;
33+
}
34+
button:hover {
35+
background-color: #004999;
36+
}
37+
.info {
38+
background-color: #e6f7ff;
39+
border-left: 4px solid #0066cc;
40+
padding: 10px;
41+
margin-bottom: 20px;
42+
}
43+
pre {
44+
background-color: #f1f1f1;
45+
padding: 10px;
46+
border-radius: 4px;
47+
overflow-x: auto;
48+
}
49+
</style>
50+
</head>
51+
<body>
52+
<div class="container">
53+
<h1>Tauri Notifications with Sound</h1>
54+
55+
<div class="info">
56+
<p>This demo shows how to use sound with Tauri notifications across different platforms.</p>
57+
<p>Make sure you have the notification plugin installed and configured correctly.</p>
58+
</div>
59+
60+
<h2>Test Notifications</h2>
61+
<button id="systemSound">Show Notification with System Sound</button>
62+
<button id="customSound">Show Notification with Custom Sound</button>
63+
<button id="platformSpecific">Show Platform-Specific Sound Notification</button>
64+
65+
<h2>Example Code</h2>
66+
<pre>
67+
// Example with system sound (mainly for macOS)
68+
await sendNotification({
69+
title: 'Notification with System Sound',
70+
body: 'This notification uses a system sound on macOS.',
71+
sound: 'Ping' // macOS system sound
72+
});
73+
74+
// Example with custom sound file
75+
await sendNotification({
76+
title: 'Notification with Custom Sound',
77+
body: 'This notification uses a custom sound file.',
78+
sound: 'notification.wav' // path to your sound file
79+
});
80+
81+
// Example with different sounds based on platform
82+
const platform = await import('@tauri-apps/api/os').then(os => os.platform());
83+
84+
let soundPath;
85+
if (platform === 'darwin') {
86+
soundPath = 'Blow'; // macOS system sound
87+
} else if (platform === 'linux') {
88+
soundPath = 'message-new-instant'; // XDG theme sound
89+
} else {
90+
soundPath = 'notification.wav'; // Custom sound file for Windows
91+
}
92+
93+
await sendNotification({
94+
title: 'Platform-specific Sound',
95+
body: `This notification uses platform-specific sound settings for ${platform}.`,
96+
sound: soundPath
97+
});</pre>
98+
</div>
99+
100+
<script src="sound-notification.js"></script>
101+
<script>
102+
document.getElementById('systemSound').addEventListener('click', () => {
103+
window.showNotificationWithSystemSound();
104+
});
105+
106+
document.getElementById('customSound').addEventListener('click', () => {
107+
window.showNotificationWithCustomSound();
108+
});
109+
110+
document.getElementById('platformSpecific').addEventListener('click', () => {
111+
window.showNotificationWithPlatformSpecificSound();
112+
});
113+
</script>
114+
</body>
115+
</html>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
2+
// SPDX-License-Identifier: Apache-2.0
3+
// SPDX-License-Identifier: MIT
4+
5+
/**
6+
* This file demonstrates how to use sound with notifications in Tauri v2.
7+
*
8+
* On macOS:
9+
* - Sound file should be in your application bundle
10+
* - Use the sound name without extension
11+
* - Or use system sounds like "Ping", "Basso", "Blow", "Bottle", "Frog", "Funk", "Glass", etc.
12+
*
13+
* On Linux:
14+
* - Use a file path to a sound file (e.g., .wav file)
15+
* - Or use XDG theme sounds by name (e.g., "message-new-instant")
16+
*
17+
* On Windows:
18+
* - Use a file path to a sound file (e.g., .wav file)
19+
*/
20+
21+
import { sendNotification } from '@tauri-apps/api/notification';
22+
23+
// Example with system sound (macOS)
24+
async function showNotificationWithSystemSound() {
25+
await sendNotification({
26+
title: 'Notification with System Sound',
27+
body: 'This notification uses a system sound on macOS.',
28+
sound: 'Ping' // macOS system sound
29+
});
30+
}
31+
32+
// Example with custom sound file
33+
async function showNotificationWithCustomSound() {
34+
await sendNotification({
35+
title: 'Notification with Custom Sound',
36+
body: 'This notification uses a custom sound file.',
37+
sound: 'notification.wav' // path to your sound file
38+
});
39+
}
40+
41+
// Example with different sounds based on platform
42+
async function showNotificationWithPlatformSpecificSound() {
43+
const platform = await import('@tauri-apps/api/os').then(os => os.platform());
44+
45+
let soundPath;
46+
if (platform === 'darwin') {
47+
soundPath = 'Blow'; // macOS system sound
48+
} else if (platform === 'linux') {
49+
soundPath = 'message-new-instant'; // XDG theme sound
50+
} else {
51+
soundPath = 'notification.wav'; // Custom sound file for Windows
52+
}
53+
54+
await sendNotification({
55+
title: 'Platform-specific Sound',
56+
body: `This notification uses platform-specific sound settings for ${platform}.`,
57+
sound: soundPath
58+
});
59+
}
60+
61+
// Export functions to be called from HTML
62+
window.showNotificationWithSystemSound = showNotificationWithSystemSound;
63+
window.showNotificationWithCustomSound = showNotificationWithCustomSound;
64+
window.showNotificationWithPlatformSpecificSound = showNotificationWithPlatformSpecificSound;

0 commit comments

Comments
 (0)