src/content/docs/learn/system-tray.mdx
import { Icon } from '@astrojs/starlight/components'; import { Tabs, TabItem } from '@astrojs/starlight/components';
Tauri allows you to create and customize a system tray for your application. This can enhance the user experience by providing quick access to common actions.
First of all, update your Cargo.toml to include the necessary feature for the system tray.
tauri = { version = "2.0.0", features = [ "tray-icon" ] }
The tray API is available in both JavaScript and Rust.
import { TrayIcon } from '@tauri-apps/api/tray';
const options = {
// here you can add a tray menu, title, tooltip, event handler, etc
};
const tray = await TrayIcon.new(options);
See TrayIconOptions for more information on the customization options.
use tauri::tray::TrayIconBuilder;
tauri::Builder::default()
.setup(|app| {
let tray = TrayIconBuilder::new().build(app)?;
Ok(())
})
See TrayIconBuilder for more information on customization options.
When creating the tray you can use the application icon as the tray icon:
<Tabs syncKey="lang"> <TabItem label="JavaScript">import { TrayIcon } from '@tauri-apps/api/tray';
import { defaultWindowIcon } from '@tauri-apps/api/app';
const options = {
icon: await defaultWindowIcon(),
};
const tray = await TrayIcon.new(options);
let tray = TrayIconBuilder::new()
.icon(app.default_window_icon().unwrap().clone())
.build(app)?;
To attach a menu that is displayed when the tray is clicked, you can use the menu option.
:::note By default the menu is displayed on both left and right clicks.
To prevent the menu from popping up on left click, call the menu_on_left_click(false) Rust function
or set the menuOnLeftClick JavaScript option to false.
:::
import { TrayIcon } from '@tauri-apps/api/tray';
import { Menu } from '@tauri-apps/api/menu';
const menu = await Menu.new({
items: [
{
id: 'quit',
text: 'Quit',
},
],
});
const options = {
menu,
menuOnLeftClick: true,
};
const tray = await TrayIcon.new(options);
use tauri::{
menu::{Menu, MenuItem},
tray::TrayIconBuilder,
};
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
let menu = Menu::with_items(app, &[&quit_i])?;
let tray = TrayIconBuilder::new()
.menu(&menu)
.menu_on_left_click(true)
.build(app)?;
Using a shared menu click handler
import { Menu } from '@tauri-apps/api/menu';
function onTrayMenuClick(itemId) {
// itemId === 'quit'
}
const menu = await Menu.new({
items: [
{
id: 'quit',
text: 'Quit',
action: onTrayMenuClick,
},
],
});
Using a dedicated menu click handler
import { Menu } from '@tauri-apps/api/menu';
const menu = await Menu.new({
items: [
{
id: 'quit',
text: 'Quit',
action: () => {
console.log('quit pressed');
},
},
],
});
use tauri::tray::TrayIconBuilder;
TrayIconBuilder::new()
.on_menu_event(|app, event| match event.id.as_ref() {
"quit" => {
println!("quit menu item was clicked");
app.exit(0);
}
_ => {
println!("menu item {:?} not handled", event.id);
}
})
The tray icon emits events for the following mouse events:
:::note Linux: Unsupported. The event is not emitted even though the icon is shown and will still show a context menu on right click. :::
<Tabs> <TabItem label="JavaScript">import { TrayIcon } from '@tauri-apps/api/tray';
const options = {
action: (event) => {
switch (event.type) {
case 'Click':
console.log(
`mouse ${event.button} button pressed, state: ${event.buttonState}`
);
break;
case 'DoubleClick':
console.log(`mouse ${event.button} button pressed`);
break;
case 'Enter':
console.log(
`mouse hovered tray at ${event.rect.position.x}, ${event.rect.position.y}`
);
break;
case 'Move':
console.log(
`mouse moved on tray at ${event.rect.position.x}, ${event.rect.position.y}`
);
break;
case 'Leave':
console.log(
`mouse left tray at ${event.rect.position.x}, ${event.rect.position.y}`
);
break;
}
},
};
const tray = await TrayIcon.new(options);
See TrayIconEvent for more information on the event payload.
use tauri::{
Manager,
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent}
};
TrayIconBuilder::new()
.on_tray_icon_event(|tray, event| match event {
TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Up,
..
} => {
println!("left click pressed and released");
// in this example, let's show and focus the main window when the tray is clicked
let app = tray.app_handle();
if let Some(window) = app.get_webview_window("main") {
let _ = window.unminimize();
let _ = window.show();
let _ = window.set_focus();
}
}
_ => {
println!("unhandled event {event:?}");
}
})
See TrayIconEvent for more information on the event type.
For detailed information about creating menus, including menu items, submenus, and dynamic updates, see the Window Menu documentation.