0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

tauriでタスクトレイにアイコンを表示する

Posted at

tauriでタスクトレイにアイコンを表示する

公式ドキュメントのコードをそのまま貼り付けるといくらか警告が出たので修正したものをこちらにメモしておきます.

TypeScript(JavaScript)でも同様のことができるみたいですが,ここではRustで実装します.

環境

執筆時の環境は以下の通りです.

項目
OS Mac OS Seqoia 15.4
RAM 16GB
cargo 1.85.1

Mac OS なのでタスクトレイではなくメニューバーかもしれない.

準備

まずはsrc-tauri/Cargo.tomldependenciestray-iconを追加します.

Cargo.toml
[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を編集します.
usetauri::Builder::default()setupを追加します.
setupの中の_trayは,ドキュメントではtrayとして宣言していますが,使用しない変数だと警告が出るので頭に_を付けています.

lib.rs
+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)を使います.

lib.rs
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だけです.
ここはドキュメント通りです.

lib.rs
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");
}

任意のアイコンに変更する

アイコンを表示したとき,以下の命令を追加していました.

lib.rust

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構造体はicopng形式のみサポートしているようです.この点には注意しましょう.
from_pathメソッドの実装では,以下のような定義があります.

tauri/image/mod.rs
#[cfg(any(feature = "image-ico", feature = "image-png"))]

そこで,features = [ "image-png" ]を追加します.

Cargo.toml
[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-taurihoge.pngがあることを前提とします.

.
├── Cargo.lock
⋮
├── hoge.png

lib.rs
+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");
}

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?