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");
}
これでタスクトレイのアイコンが変わります.
ちなみに,画像をリサイズして長方形にするとアイコンが表示されなくなりました.
用意する画像は正方形にしましょう.