tauriでタスクトレイにアイコンを表示する
公式ドキュメントのコードをそのまま貼り付けるといくらか警告が出たので修正したものをこちらにメモしておきます.
TypeScript(JavaScript)でも同様のことができるみたいですが,ここではRustで実装します.
環境
執筆時の環境は以下の通りです.
| 項目 | 値 |
|---|---|
| OS | Mac OS Seqoia 15.4 |
| RAM | 16GB |
| cargo | 1.85.1 |
Mac OS なのでタスクトレイではなくメニューバーかもしれない.
準備
まずはsrc-tauri/Cargo.tomlのdependenciesにtray-iconを追加します.
[dependencies]
+tauri = { version = "2.0.0", features = [ "tray-icon" ] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
アイコンをタスクトレイに表示する
src-tauri/src/lib.rsを編集します.
useとtauri::Builder::default()にsetupを追加します.
setupの中の_trayは,ドキュメントではtrayとして宣言していますが,使用しない変数だと警告が出るので頭に_を付けています.
+use tauri::{
+ tray::TrayIconBuilder,
+};
// いろいろ
pub fn run() {
tauri::Builder::default()
+ .setup(|app| {
+ let _tray = TrayIconBuilder::new()
+ .icon(app.default_window_icon().unwrap().clone())
+ .build(app)?;
+ Ok(())
+ })
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
タスクトレイのアイコンにメニューをつける
useとsetupにそれぞれ追加します.
ドキュメントではsetupの中に.menu_on_left_click(true)を追加していますが,現在は非推奨のメソッド(deprecated method)らしいので.show_menu_on_left_click(true)を使います.
use tauri::{
menu::{Menu, MenuItem},
+ tray::TrayIconBuilder,
};
// いろいろ
pub fn run() {
tauri::Builder::default()
.setup(|app| {
+ let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
+ let menu = Menu::with_items(app, &[&quit_i])?;
let _tray = TrayIconBuilder::new()
.icon(app.default_window_icon().unwrap().clone())
+ .menu(&menu)
+ .show_menu_on_left_click(true)
.build(app)?;
Ok(())
})
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
メニューからプログラムを終了できるようにする
編集するのはrunの中のsetupだけです.
ここはドキュメント通りです.
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
let menu = Menu::with_items(app, &[&quit_i])?;
let _tray = TrayIconBuilder::new()
.icon(app.default_window_icon().unwrap().clone())
.menu(&menu)
.show_menu_on_left_click(true)
+ .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);
+ }
+ })
.build(app)?;
Ok(())
})
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
任意のアイコンに変更する
アイコンを表示したとき,以下の命令を追加していました.
let _tray = TrayIconBuilder::new()
+ .icon(app.default_window_icon().unwrap().clone())
ここで,TrayIconBuilder構造体のドキュメントを見てみましょう(3つたどるので結果だけ知りたい人は飛ばしてください).
ドキュメントでiconは以下のように定義されています.
pub fn icon(self, icon: Image<'_>) -> Self
Image構造体のドキュメントでは,PathからImageを生成するメソッドが挙げられています.
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self>
Path構造体のドキュメントでは,文字列からPathを生成するメソッドが挙げられています.
let path = Path::new("./foo/bar.txt");
したがって,上記を組み合わせれば任意のアイコンに変更できます.
なお,Image構造体はicoとpng形式のみサポートしているようです.この点には注意しましょう.
from_pathメソッドの実装では,以下のような定義があります.
#[cfg(any(feature = "image-ico", feature = "image-png"))]
そこで,features = [ "image-png" ]を追加します.
[dependencies]
+tauri = { version = "2.0.0", features = [ "tray-icon", "image-png" ] }tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Cargo.tomlにfeaturesを追記したら,アイコンの設定をします.
パスの基準はCargo.tomlがあるディレクトリです.ここではsrc-tauriにhoge.pngがあることを前提とします.
.
├── Cargo.lock
⋮
├── hoge.png
+use std::path::Path;
use tauri::{
image::Image,
menu::{Menu, MenuItem},
+ tray::TrayIconBuilder,
};
// いろいろ
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
let menu = Menu::with_items(app, &[&quit_i])?;
+ let path = Path::new("./hoge.png");
+ let image = Image::from_path(path).unwrap();
let _tray = TrayIconBuilder::new()
- .icon(app.default_window_icon().unwrap().clone())
+ .icon(image)
.menu(&menu)
.show_menu_on_left_click(true)
.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);
}
})
.build(app)?;
Ok(())
})
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
これでタスクトレイのアイコンが変わります.
ちなみに,画像をリサイズして長方形にするとアイコンが表示されなくなりました.
用意する画像は正方形にしましょう.