diff --git a/src/content/docs/ja/learn/index.mdx b/src/content/docs/ja/learn/index.mdx new file mode 100644 index 0000000000..d21a1f98ac --- /dev/null +++ b/src/content/docs/ja/learn/index.mdx @@ -0,0 +1,114 @@ +--- +title: 学習要領 +sidebar: + order: 0 + label: 概要 +i18nReady: true +--- + +import { Card, CardGrid, LinkCard } from '@astrojs/starlight/components'; +import AwesomeTauri from '@components/AwesomeTauri.astro'; +import BookItem from '@components/BookItem.astro'; +import RoseRustBook from '@assets/learn/community/HTML_CSS_JavaScript_and_Rust_for_Beginners_A_Guide_to_Application_Development_with_Tauri.png'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +この「学習」編では、Tauri 関連のトピックに関する学習体験を端から端まで提供することを目的としています。 + +各チュートリアルは、特定のトピックについて説明し、ガイドや参考文書(リファレンス)から得た知識を応用できるようになるでしょう。 + +セキュリティ関連のトピックでは、アクセス権システムについて学ぶことができます。そこではシステムの使い方、拡張のし方、そしてあなた自身のアクセス権を記述するやり方について、実践的な知識が得られます。 + + + + + + + +独自の「スプラッシュスクリーン」(起動時表示画面)を作成する方法や、「Node.js サイドカー」を使用する方法については、以下を参照してください: + + + + + + +## その他の資料 + +この項には、この Web サイトに掲載されていない、コミュニティによって作成された学習資料を掲載しています。 + + + +### 書籍 + + + +### ガイドとチュートリアル + + + + + + + + +#### ビデオ・ガイド + + + + + + + + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/learn/sidecar-nodejs.mdx b/src/content/docs/ja/learn/sidecar-nodejs.mdx new file mode 100644 index 0000000000..99f7e60bd6 --- /dev/null +++ b/src/content/docs/ja/learn/sidecar-nodejs.mdx @@ -0,0 +1,202 @@ +--- +title: Node.js サイドカー +sidebar: + order: 1 +i18nReady: true +--- + +import CommandTabs from '@components/CommandTabs.astro'; +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; +import CTA from '@fragments/cta.mdx'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +この章では、Node.js アプリケーションを自己完結型バイナリにパッケージ化して、エンドユーザーが Node.js をインストールすることなく Tauri アプリケーションの「サイドカー」として利用できるようにします。 +このチュートリアル例は、デスクトップ・オペレーティング・システムにのみ適用可能です。 + +「Tauri サイドカー」の仕組みをより深く理解するために、まずは一般的な [サイドカー・ガイド] を読むことをお勧めします。 + +以下の事例では、コマンドライン [process.argv] から入力を読み取り、[console.log] を使用して出力を stdout(標準出力)に書き込む Node.js アプリケーションを作成します。
+「ローカルホスト・サーバー」、「stdin/stdout」(標準入出力)、「ローカル・ソケット」などといった代替のプロセス間通信システムを活用できます。 +これらはそれぞれに利点、欠点、セキュリティ上の懸念があることに注意してください。 + +## 事前準備(必要なもの) + +シェル・プラグインを使用してセットアップされた「既存の Tauri アプリケーション」。このシェル・プラグインは、ローカルでコンパイルおよび実行を行ないます。 + +:::tip[試作アプリの作成] + +あなたが上級ユーザーでない場合は、ここで提供されているオプションとフレームワークをそのまま使用することを**強く推奨**します。これはあくまで「試作(ラボ)」なので、作業終了後にはプロジェクトを削除できます。 + + + +- プロジェクト名: `node-sidecar-lab` +- フロントエンド用言語の選択: `Typescript / Javascript` +- パッケージ・マネージャーの選択: `pnpm` +- UI テンプレートの選択: `Vanilla` +- UI フレーバーの選択: `Typescript` +- モバイル用プロジェクトも設定しますか?: `yes` + +::: + +:::note +プラグインを正しく設定して初期化するには、まず[シェル・プラグイン・ガイド](/ja/plugin/shell/)に従ってください。 +プラグインの初期化と設定が行なわれていないと、以下の事例は機能しません。 +::: + +## ガイド + + + +1. ##### サイドカー・プロジェクトの初期化 + + サイドカー実装を格納する新しい Node.js プロジェクトを作成しましょう。 + **Tauri アプリケーションのルート・フォルダー** に新しいディレクトリを作成し(この事例では `sidecar-app` と呼びます)、そのディレクトリ内で、好みの Node.js パッケージ・マネージャーの `init` コマンドを実行します。 + + + + [pkg] コマンドを使用して、Node.js アプリケーションを自己完結型バイナリにコンパイルします。 + + + + **自己完結型バイナリ** 原文 a self contained binary: この語は本稿一行目にも記載あり。ただし、この「ガイド」項目内では a self contain**er** binary と記載されており、表記のゆらぎか誤記かは不明。翻訳では self contained の意味として表記を統一してあります。 + + + + それを開発依存関係としてインストールしましょう: + + + +1. ##### サイドカー・ロジックの記述 + + では、Tauri アプリケーションによって実行される JavaScript コードの作成を始めましょう。 + + この事例では、コマンドライン引数からコマンドを処理し、出力を stdout(標準出力)に書き出します。 + つまり、このプロセスは短命で、一度に一つのコマンドのみを処理します。 + もしあなたのアプリケーションが「長い存続時間」(長命のプロセス)を必要としている場合には、別の「プロセス間通信システム」の使用を検討してください。 + + `sidecar-app` ディレクトリに `index.js` ファイルを作成し、基本的な Node.js アプリを記述しましょう: + + ```js title=sidecar-app/index.js + const command = process.argv[2]; + + switch (command) { + case 'ping': + const message = process.argv[3]; + console.log(`pong, ${message}`); + break; + default: + console.error(`unknown command ${command}`); + process.exit(1); + } + ``` + +1. ##### サイドカーのパッケージ化 + + Node.js アプリケーションを自己完結型バイナリにパッケージ化するには、以下の `pkg` コマンドを実行します: + + + + これにより、Linux および macOS では `sidecar-app/app` バイナリが作成され、Windows では `sidecar-app/app.exe` 実行可能ファイルが作成されます。 + このファイル名を Tauri サイドカー・ファイル名で要求される形式に変更するには、次の Node.js スクリプトを使用します: + + ```js + import { execSync } from 'child_process'; + import fs from 'fs'; + + const ext = process.platform === 'win32' ? '.exe' : ''; + + const rustInfo = execSync('rustc -vV'); + const targetTriple = /host: (\S+)/g.exec(rustInfo)[1]; + if (!targetTriple) { + console.error('Failed to determine platform target triple'); + } + fs.renameSync( + `app${ext}`, + `../src-tauri/binaries/app-${targetTriple}${ext}` + ); + ``` + +1. ##### Tauriアプリケーションでのサイドカー設定 + + Node.js アプリケーションの準備ができたので、[`bundle > externalBin`] 配列を設定して、これを Tauri アプリケーションに接続します: + + ```json title="src-tauri/tauri.conf.json" + { + "bundle": { + "externalBin": ["binaries/app"] + } + } + ``` + + Tauri CLI は、サイドカー・バイナリが `src-tauri/binaries/app-` として存在する限り、サイドカー・バイナリのバンドルを処理します。 + + + + **target-triple** 「target」はアプリが対象とするプラットフォーム、「triple」は target の内容を示す三要素 --: 例 aarch64-apple-darwin(ARM64-apple-macOS)〔[参考](https://doc.rust-lang.org/nightly/rustc/platform-support.html)〕 + + + +1. ##### サイドカーの実行 + + サイドカー・バイナリは、Rust コードからでも、直接 JavaScript からでも実行できます。 + + + + + + Node.js サイドカーで `ping` コマンドを直接実行してみましょう: + + ```javascript + import { Command } from '@tauri-apps/plugin-shell'; + + const message = 'Tauri'; + + const command = Command.sidecar('binaries/app', ['ping', message]); + const output = await command.execute(); + const response = output.stdout; + ``` + + + + + + Tauri コマンド `pipe` を Node.js サイドカーにパイプ処理をしてみましょう: + + ```rust + #[tauri::command] + async fn ping(app: tauri::AppHandle, message: String) -> String { + let sidecar_command = app + .shell() + .sidecar("app") + .unwrap() + .arg("ping") + .arg(message); + let output = sidecar_command.output().unwrap(); + let response = String::from_utf8(output.stdout).unwrap(); + response + } + ``` + + + + + + + +[サイドカー・ガイド]: /ja/develop/sidecar/ +[process.argv]: https://nodejs.org/docs/latest/api/process.html#processargv +[console.log]: https://nodejs.org/api/console.html#consolelogdata-args +[pkg]: https://github.com/vercel/pkg +[`bundle > externalBin`]: /reference/config/#externalbin + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/learn/splashscreen.mdx b/src/content/docs/ja/learn/splashscreen.mdx new file mode 100644 index 0000000000..b05f29eb2c --- /dev/null +++ b/src/content/docs/ja/learn/splashscreen.mdx @@ -0,0 +1,271 @@ +--- +title: スプラッシュスクリーン(起動時表示画面) +sidebar: + order: 1 +tableOfContents: + minHeadingLevel: 2 + maxHeadingLevel: 5 +i18nReady: true +--- + +import { Image } from 'astro:assets'; +import step_1 from '@assets/learn/splashscreen/step_1.png'; +import step_3 from '@assets/learn/splashscreen/step_3.png'; +import { Steps, Tabs, TabItem } from '@astrojs/starlight/components'; +import ShowSolution from '@components/ShowSolution.astro'; +import CTA from '@fragments/cta.mdx'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +この「試作(ラボ)」では、Tauri アプリに基本的なスプラッシュスクリーン機能を実装します。 +やりかたは至って単純明快です。スプラッシュスクリーンは、実質的には、アプリがセットアップ関連の負荷の高いタスクを実行している間中、相応のコンテンツを表示する新しいウィンドウを描画し、セットアップが完了したらそのウィンドウを閉じるだけです。 + +## 事前準備 + +:::tip[試作アプリの作成] + +あなたが上級ユーザーでない場合は、ここで提供されているオプションとフレームワークを使用することを**強く推奨**します。これはあくまで「試作(ラボ)」なので、完了したらプロジェクトを削除できます。 + + + +- プロジェクト名: `splashscreen-lab` +- フロントエンド用言語の選択: `Typescript / Javascript` +- パッケージ・マネージャーの選択: `pnpm` +- UI テンプレートの選択: `Vanilla` +- UI フレーバーの選択: `Typescript` +- モバイル用プロジェクトも設定しますか?: `yes` + +::: + +## 作業手順 + + + +1. ##### 依存関係のインストールとプロジェクトの実行 + + プロジェクトの開発を始める前に、セットアップが意図したとおりに動作していることを確認するために、初期テンプレートをビルドして実行することが重要です。 + + {' '} + + + ```sh frame=none # 正しいディレクトリにいることを確認してください cd + splashscreen-lab # 依存関係をインストール pnpm install # + アプリのビルドと実行 pnpm tauri dev ``` + Successful run of the created template app. + + +1. ##### `tauri.conf.json` に新しいウィンドウを登録 + + 新しいウィンドウを追加する最も簡単な方法は、`tauri.conf.json` に直接追加することです。 + 起動時に動的にウィンドウを作成することもできますが、簡素化のために、そうはせずに直接登録することにします。 + `main` というラベルのウィンドウが「非表示」ウィンドウとして、`splashscreen` というラベルのウィンドウが「直接表示」されるウィンドウとして作成されていることを確認してください。その他のオプション項目はどれも、デフォルト設定のままでも、好みに応じて調整しても構いません。 + + + +```json +// src-tauri/tauri.conf.json +{ + "windows": [ + { + "label": "main", + "visible": false + }, + { + "label": "splashscreen", + "url": "/splashscreen" + } + ] +} +``` + + + +1. ##### スプラッシュスクリーンをホストする新しいページの作成 + + ページの作成を始める前に、表示するコンテンツをいくつか準備する必要があります。 + 新しいページをどのように展開するのかは、選択したフレームワークによって異なりますが、ほとんどのフレームワークにはページ・ナビゲーションを処理する「ルーター」という考え方があり、Tauri で普通に機能するはずです。そうであれば、あとは新しいスプラッシュスクリーン・ページを生成するだけです。 + あるいは、以下で行なうように、コンテンツをホストするための新しい `splashscreen.html` ファイルを作成します。 + + ここで重要なのは、「URL `/splashscreen`」にアクセスでき、スプラッシュスクリーンに表示したいコンテンツが表示されることです。この手順を完了したら、アプリをもう一度実行して確かめてみてください。 + + + +```html +// /splashscreen.html + + + + + + + Tauri App + + +
+

Tauri used Splash!

+
+
It was super effective!
+
+
+ + +``` + + The splashscreen we just created. +
+ +1. ##### 起動タスクの開始 + + 一般的に、スプラッシュスクリーンは起動時の重いタスクを隠すことを意図しているため、アプリのフロントエンドとバックエンドでいくつかの重い処理を擬似実行させて見ましょう。 + + フロントエンドで重い起動処理を擬似実行するには、単純な `setTimeout` 関数を使用します。 + + 一方、バックエンドで重い操作を擬似実行する最も簡単な方法は、Tokio クレートを使用することです。これは、バックエンドで非同期ランタイムを提供するために Tauri が使用する Rust クレートです。Tauri がランタイムを提供する一方で、クレートから再エクスポートしない様々なユーティリティがあるため、そのようなユーティリティにアクセスするために、Tokio クレートをプロジェクトに追加する必要があります。これは Rust エコシステムではごく一般的なやりかたです。 + + 非同期関数では `std::thread::sleep` を使用しないでください。非同期関数は、並列ではなく同時実行環境で協調的に実行されます。つまり、Tokio タスクの代わりにこの `std::thread::sleep` 関数でスレッドをスリープ状態にすると、そのスレッドで実行するようにスケジュールされているすべてのタスクの実行がロックされ、アプリがフリーズします。 + + + +```sh frame=none +# `Cargo.toml`ファイルがある場所でこのコマンドを実行 +cd src-tauri +# Tokio crate の追加 +cargo add tokio +# 必要に応じてトップ・フォルダに戻り開発作業を継続 +# `tauri dev` がどこで実行するかを自動判断 +cd .. +``` + +```javascript +// src/main.ts +// 以下の内容は既存のコードの下にコピーして貼り付けることができますが、ファイル全体を置き換えないでください。 + +// TypeScript でスリープ機能を実装するためのユーティリティ関数 +function sleep(seconds: number): Promise { + return new Promise(resolve => setTimeout(resolve, seconds * 1000)); +} + +// Setup 関数 +async function setup() { + // 非常に重い起動処理タスクを擬似実行 + console.log('Performing really heavy frontend setup task...') + await sleep(3); + console.log('Frontend setup task complete!') + // フロントエンド・タスクを完了済みとして設定 + invoke('set_complete', {task: 'frontend'}) +} + +// 実質的に JavaScript のメイン関数 +window.addEventListener("DOMContentLoaded", () => { + setup() +}); +``` + +```rust +// /src-tauri/src/lib.rs +// 利用する機能をインポート +use std::sync::Mutex; +use tauri::async_runtime::spawn; +use tauri::{AppHandle, Manager, State}; +use tokio::time::{sleep, Duration}; + +// 起動関連タスクの完了を追跡するために使用する構造体を作成 +struct SetupState { + frontend_task: bool, + backend_task: bool, +} + +// バージョン 2 モバイル対応アプリでのメイン・エントリーポイント +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + // Tauri の起動前ではなく、起動フック部分にコードを記載してください! + tauri::Builder::default() + // Tauri で管理される `State` を登録する + // これには書き込みアクセスが必要なので、`Mutex`でラップします。 + .manage(Mutex::new(SetupState { + frontend_task: false, + backend_task: false, + })) + // 確認に使用するコマンドの追加 + .invoke_handler(tauri::generate_handler![greet, set_complete]) + // 起動関連タスクの実行に起動フックを使用 + // メインループの前に実行されるため、ウィンドウはまだ作成されません + .setup(|app| { + // 起動を非ブロッキング処理として生成し、実行中にウィンドウを生成・実行可能にします。 + spawn(setup(app.handle().clone())); + // フックは「Ok」という結果を要求します + Ok(()) + }) + // アプリを実行 + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} + +#[tauri::command] +fn greet(name: String) -> String { + format!("Hello {name} from Rust!") +} + +// 起動タスクの状態を設定するためのカスタム・タスク +#[tauri::command] +async fn set_complete( + app: AppHandle, + state: State<'_, Mutex>, + task: String, +) -> Result<(), ()> { + // 書き込みアクセスなしで状態をロック + let mut state_lock = state.lock().unwrap(); + match task.as_str() { + "frontend" => state_lock.frontend_task = true, + "backend" => state_lock.backend_task = true, + _ => panic!("invalid task completed!"), + } + // フロントエンド・バックエンド両方のタスクが完了したかどうかを確認 + if state_lock.backend_task && state_lock.frontend_task { + // 起動が完了したら、スプラッシュスクリーンを閉じてメインウィンドウを提示 + let splash_window = app.get_webview_window("splashscreen").unwrap(); + let main_window = app.get_webview_window("main").unwrap(); + splash_window.close().unwrap(); + main_window.show().unwrap(); + } + Ok(()) +} + +// 重い起動タスクを実行する非同期関数 +async fn setup(app: AppHandle) -> Result<(), ()> { + // 重い処理を 3 秒間擬似実行 + println!("Performing really heavy backend setup task..."); + sleep(Duration::from_secs(3)).await; + println!("Backend setup task completed!"); + // バックエンドタスクを完了済みとして設定 + // 入力引数を自分で処理する限り、コマンドは通常の関数として実行できます。 + set_complete( + app.clone(), + app.state::>(), + "backend".to_string(), + ) + .await?; + Ok(()) +} +``` + + + +1. ##### アプリケーションの実行 + + これでスプラッシュスクリーン・ウィンドウがポップアップ表示され、フロントエンドとバックエンドの両方でそれぞれ 3 秒間の重い起動タスクが実行され、その後スプラッシュスクリーンが消えてメイン・ウィンドウに切り替わります。 + +
+ +## 争点 + +##### スプラッシュスクリーンは必要ですか? + +一般的に、スプラッシュスクリーンを表示するということは、スプラッシュスクリーンを必要としないほどアプリの読み込み速度を上げることができなかったという敗北を認めることになります。 +実際、メイン・ウィンドウを直接表示して、メイン・ウィンドウの隅のどこかに小さなスピナー(進捗表示計)を表示し、バックグラウンドで起動タスクがまだ実行中であることをユーザーに通知する方がどちらかといえばよいでしょう。 + +ただし、そうは言っても、スプラッシュスクリーンを表示したいというスタイル上の選択があったり、特定のタスクが実行されるまでアプリを起動できなくしたいという特殊な事情がある場合もあります。 +スプラッシュスクリーンがあることは決して*間違って*いるというわけではありませんが、必ずしも必要とされない傾向にあり、ユーザーにアプリがあまり最適化されていないと感じさせる可能性があります。 + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/learn/system-tray.mdx b/src/content/docs/ja/learn/system-tray.mdx new file mode 100644 index 0000000000..b3b1b4c809 --- /dev/null +++ b/src/content/docs/ja/learn/system-tray.mdx @@ -0,0 +1,328 @@ +--- +title: システム・トレイ +sidebar: + order: 1 +tableOfContents: + maxHeadingLevel: 4 +i18nReady: true +--- + +import { Icon } from '@astrojs/starlight/components'; +import { Tabs, TabItem } from '@astrojs/starlight/components'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +Tauri では、あなたのアプリケーション用に「システム・トレイ」を作成およびカスタマイズできます。 +これにより、一般的なアクションにすばやくアクセスできるようになり、ユーザー・エクスペリエンスが向上します。 + +## 設定 + +まず初めに、`Cargo.toml` をアップデートし、「システム・トレイ」に必要な機能が含まれるようにします。 + +```toml title="src-tauri/Cargo.toml" +tauri = { version = "2.0.0", features = [ "tray-icon" ] } +``` + +## 使用方法 + +「トレイ API」は JavaScript と Rust の両方で利用できます。 + + + +**トレイ API** tray API: 以下、本稿での各関数へのリンクは、「英語版」のみです。 + + + +### トレイ・アイコンの生成 + + + +新しい「トレイ・アイコン」を作成するには、静的関数 [`TrayIcon.new`] を使用します。 + +```javascript +import { TrayIcon } from '@tauri-apps/api/tray'; + +const options = { + // この部分には、トレイ・メニュー(tray menu)、タイトル(title)、ツールチップ(tooltip)、イベント・ハンドラー(event handler)などを追加できます。 +}; + +const tray = await TrayIcon.new(options); +``` + +カスタマイズ・オプションの詳細については、リンク先 [`TrayIconOptions`] を参照してください。 + + + + + +```rust +use tauri::tray::TrayIconBuilder; + +tauri::Builder::default() + .setup(|app| { + let tray = TrayIconBuilder::new().build(app)?; + Ok(()) + }) + +``` + +カスタマイズ・オプションの詳細については、リンク先 [`TrayIconBuilder`] を参照してください。 + + + + +### トレイ・アイコンの変更 + +トレイの生成時には、アプリケーション・アイコンをトレイ・アイコンとして利用できます。 + + + + +```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); +``` + + + + + +```rust +let tray = TrayIconBuilder::new() + .icon(app.default_window_icon().unwrap().clone()) + .build(app)?; +``` + + + + +### メニューの追加 + +トレイをクリックしたときに表示される「メニュー」を追加するには、`menu` オプションを使用します。 + +:::note +デフォルトでは、このメニューは左クリックでも右クリックでも表示されます。 + +左クリックでメニューが表示されないようにするには、Rust 関数の [`menu_on_left_click(false)`][TrayIconBuilder::menu_on_left_click] を呼び出すか、 +JavaScript オプションの [`menuOnLeftClick`] を `false` に設定してください。 +::: + +{/* TODO: link to the menu plugin documentation page */} + + + + +```javascript +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); +``` + + + + + +```rust +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)?; +``` + + + + +#### メニュー・イベントへの応答 + + + +JavaScript では、「メニュー・クリック・イベント・リスナー」をメニュー項目に直接記述できます: + +- メニュー・クリック・ハンドラーを共有利用する場合 + + ```javascript + import { Menu } from '@tauri-apps/api/menu'; + + function onTrayMenuClick(itemId) { + // itemId === 'quit' + } + + const menu = await Menu.new({ + items: [ + { + id: 'quit', + text: 'Quit', + action: onTrayMenuClick, + }, + ], + }); + ``` + +- 専用のメニュー・クリック・ハンドラーを使用する場合 + + ```javascript + import { Menu } from '@tauri-apps/api/menu'; + + const menu = await Menu.new({ + items: [ + { + id: 'quit', + text: 'Quit', + action: () => { + console.log('quit pressed'); + }, + }, + ], + }); + ``` + + + + +[`TrayIconBuilder::on_menu_event`] メソッドを使用して、トレイ・メニュー・クリック・イベント・リスナーを記述します。 + +```rust +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); + } + }) +``` + + + + +### トレイ・イベントへの応答 + +「トレイ・アイコン」は、次のような「マウス・イベント」に対してイベントを発行します。 + +- クリック(Click): カーソルが左、右、または中央のシングル・クリックを受け取ったときに、マウスのクリックが解除されたかどうかの情報も含めて、トリガーされます。 +- ダブルクリック(DoubleClick): カーソルが左、右、または中央のダブルクリックを受け取ったときにトリガーされます。 +- 進入(Enter): カーソルがトレイ・アイコン領域に入ったときにトリガーされます +- 移動(Move): カーソルがトレイ・アイコン領域内を移動したときにトリガーされます +- 離脱(Leave): カーソルがトレイ・アイコン領域から離れた時にトリガーされます + + + + +```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); +``` + +「イベント・ペイロード」の詳細については、[`TrayIconEvent`][js TrayIconEvent] を参照してください。 + + + + + +```rust +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"); + // この例では、トレイがクリックされたときに「let」文がメインウィンドウを表示しアクティブ化します。 + let app = tray.app_handle(); + if let Some(window) = app.get_webview_window("main") { + let _ = window.show(); + let _ = window.set_focus(); + } + } + _ => { + println!("unhandled event {event:?}"); + } + }) +``` + +「イベント型」の詳細については、[`TrayIconEvent`][rust TrayIconEvent] を参照してください。 + + + + +[`TrayIcon.new`]: /reference/javascript/api/namespacetray/#new +[`TrayIconOptions`]: /reference/javascript/api/namespacetray/#trayiconoptions +[`TrayIconBuilder`]: https://docs.rs/tauri/2.0.0/tauri/tray/struct.TrayIconBuilder.html +[TrayIconBuilder::menu_on_left_click]: https://docs.rs/tauri/2.0.0/tauri/tray/struct.TrayIconBuilder.html#method.menu_on_left_click +[`menuOnLeftClick`]: /reference/javascript/api/namespacetray/#properties-1 +[`TrayIconBuilder::on_menu_event`]: https://docs.rs/tauri/2.0.0/tauri/tray/struct.TrayIconBuilder.html#method.on_menu_event +[js TrayIconEvent]: /reference/javascript/api/namespacetray/#trayiconevent +[rust TrayIconEvent]: https://docs.rs/tauri/2.0.0/tauri/tray/enum.TrayIconEvent.html + +
+ 【※ この日本語版は、「Jul 08, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/learn/window-customization.mdx b/src/content/docs/ja/learn/window-customization.mdx new file mode 100644 index 0000000000..835d6f5592 --- /dev/null +++ b/src/content/docs/ja/learn/window-customization.mdx @@ -0,0 +1,300 @@ +--- +title: ウィンドウのカスタマイズ +sidebar: + order: 1 +tableOfContents: + maxHeadingLevel: 4 +i18nReady: true +--- + +import { Icon } from '@astrojs/starlight/components'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +Tauri は、あなたのアプリのウィンドウ外観や操作性をカスタマイズするための豊富なオプションを提供しています。カスタム・タイトルバーの作成や、透明なウィンドウ、サイズ制限の適用などが可能になります。 + +## 設定 + +ウィンドウ設定を変更するには、次の三通りの方法があります: + +- [tauri.conf.json + を用いて](/reference/config/#windowconfig) +- [JavaScript API + を用いて](/reference/javascript/api/namespacewindow/#window) +- [Rust の Window + 構造体を用いて](https://docs.rs/tauri/2.0.0/tauri/window/struct.Window.html) + +## 使用法 + +- [カスタム・タイトルバーの作成](#カスタムタイトルバーの作成) +- [(macOS) カスタム・ウィンドウ背景色付きの透明なタイトルバー](#macos-カスタムウィンドウ背景色付きの透明なタイトルバー) + +### カスタム・タイトルバーの作成 + +このようなウィンドウ機能の一般的な用途は、カスタム・タイトルバーの作成です。この短いチュートリアルでは、その工程を順を追って説明します。 + +:::note +macOS では、カスタム・タイトルバーを使用すると、[ウィンドウの移動や配置](https://support.apple.com/ja-jp/guide/mac-help/mchlp2469/mac) といった、システム自身によって提供されているいくつかの機能が失われます。 +そのようなネイティブ機能を維持しながらタイトルバーをカスタマイズする別の方法として、タイトルバーを透明にしてウィンドウの背景色を設定する方法があります。そのやりかたについては、こちらの[(macOS) カスタムウィンドウ背景色を使用した透明なタイトルバー](#macos-transparent-titlebar-with-custom-window-background-color)をご覧ください。 +::: + +#### tauri.conf.json + +`tauri.conf.json` で `decorations` 項目を「`false`」に設定します。 + +```json title="tauri.conf.json" {4} +"tauri": { + "windows": [ + { + "decorations": false + } + ] +} +``` + +#### アクセス権 + +「セキュリティ機能 capability ファイル」でウィンドウに「アクセス権」を追加します。 + +デフォルトでは、すべてのプラグイン・コマンドのアクセス権はブロックされており、アクセスできません。「セキュリティ機能`capabilities`」設定でアクセス権リストを定義する必要があります。 + +詳細については「[セキュリティ・レベルの概要](/ja/security/capabilities/)」の章を参照してください。また、プラグイン権限を使用するには「[プラグイン・アクセス権の使用](/ja/learn/security/using-plugin-permissions/)」の章を参照してください。 + +```json title="src-tauri/capabilities/default.json" ins={6} +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "main-capability", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": ["core:window:default", "core:window:allow-start-dragging"] +} +``` + +| Permission | Description | +| -------------------------------------------- | -------------------------------------------------------------------------------- | +| `core:window:default` | plugin 用デフォルト・アクセス権。ただし、 `window:allow-start-dragging` を除く。 | +| `core:window:allow-close` | スコープ(適用範囲)の事前設定なしで close コマンドを有効にします。 | +| `core:window:allow-minimize` | スコープの事前設定なしで minimize コマンドを有効にします。 | +| `core:window:allow-start-dragging` | スコープの事前設定なしで start_dragging コマンドを有効にします。 | +| `core:window:allow-toggle-maximize` | スコープの事前設定なしで toggle_maximize コマンドを有効にします。 | +| `core:window:allow-internal-toggle-maximize` | スコープの事前設定なしで internal_toggle_maximize コマンドを有効にします。 | + +#### CSS + +この CSS サンプルを追加して、タイトルバーを画面の上部に表示し、ボタンのスタイルを設定します: + +```css +.titlebar { + height: 30px; + background: #329ea3; + user-select: none; + display: grid; + grid-template-columns: auto max-content; + position: fixed; + top: 0; + left: 0; + right: 0; +} +.titlebar > .controls { + display: flex; +} +.titlebar button { + appearance: none; + padding: 0; + margin: 0; + border: none; + display: inline-flex; + justify-content: center; + align-items: center; + width: 30px; + background-color: transparent; +} +.titlebar button:hover { + background: #5bbec3; +} +``` + +#### HTML + +以下を `` タグの最初に置いてください: + +```html +
+
+
+ + + +
+
+``` + +タイトルバーに隠れないように、残りのコンテンツを下に移動する必要があるかもしれないことに注意してください。 + +:::tip + +Windows で、カスタム仕様のインタラクション(応答操作)を必要としないタイトル・バーだけで十分な場合には、以下を使用すると + +```css +*[data-tauri-drag-region] { + app-region: drag; +} +``` + +タイトル・バーをタッチやペン入力で操作できるようになります。 + +::: + +#### JavaScript + +ボタンを機能させるには、以下のコード・スニペットを使用します: + +```javascript +import { getCurrentWindow } from '@tauri-apps/api/window'; + +// `"withGlobalTauri": true` を使用する場合は、 +// const { getCurrentWindow } = window.__TAURI__.window; を使用できます。 + +const appWindow = getCurrentWindow(); + +document + .getElementById('titlebar-minimize') + ?.addEventListener('click', () => appWindow.minimize()); +document + .getElementById('titlebar-maximize') + ?.addEventListener('click', () => appWindow.toggleMaximize()); +document + .getElementById('titlebar-close') + ?.addEventListener('click', () => appWindow.close()); +``` + +なお、Rust ベースのフロントエンドを使用しているのであれば、上記 HTML 項のコードを `index.html` ファイルの `