はじめに
ウィンドウ系のアプリケーションの起動・再起動サイクルでストレスレスにする一つの要素として、ウィンドウの状態の再現性がある。
これは例えば、Qt/PySide (Qt for Python) の場合などは、自前で保存、再現のプログラムを書かなくてはならない。
もちろん、UI の状態保存・再現は別途行う必要はあるが、ウィンドウ状態の再現性はフレームワークでサポートしてほしいと常々思う。
では、Tauri ではどうやるのか?どう操作しているのか?が気になったのでそれを調べたまとめ。
前提: 環境
- Windows 11
- Rust v1.72.0
- Tauri v1.4
実装
デフォルトでは以下の用に、ウィンドウ位置もウィンドウサイズも保存してくれない。
これだと、好みの作業環境をウィンドウサイズを変更して作成していたりする場合などにも結構ストレスに感じてしまう。
プラグインの導入
ウィンドウ状態の保存を Tarui フレームワークとして取り込むためにはプラグインを導入する必要がある。
これが、window-state というもの。
[dependencies]
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
Tauri でグローバルシングルトンを実装する でも書いたが、公式プラグインの導入方法の一つ(例外もある)として、この plugins-workspace レポジトリからインストールすることを薦めていたりする。そのため、上記もそれに習ったインストール方法を活用している。(Cargo にそんな機能があったのをこの Tarui の検証で初めて知った… )
プラグインの有効化
プラグインの有効化にはウィンドウセットアップ時にプラグインを有効化する。
fn main() {
tauri::Builder::default()
+ .plugin(tauri_plugin_window_state::Builder::default().build())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
ウィンドウ保存のしくみ
Window 保存範囲
ウィンドウ保存の範囲は v1 の時点で以下のように構造体で定義されている。
これから読み解くと、ウィンドウの
- 横幅
- 縦幅
- ポジション(x,y)
- 最大化表示かどうか
- 表示状態かどうか
- ウィンドウ装飾が有効化どうか
- フルスクリーンかどうか
を保存するようになっている様子。
struct WindowState {
width: f64,
height: f64,
x: i32,
y: i32,
maximized: bool,
visible: bool,
decorated: bool,
fullscreen: bool,
}
保存形式とファイル位置
ウィンドウ保存は、ライブラリのソースから、Json 形式で保存されている事がわかる。
これは、ウィンドウ状態の構造体の derive マクロで serde::Deserialize
及び serde::Serialize
を使用していることからも分かる。
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize, PartialEq)]
struct WindowState {
...
}
この構造体で宣言済みのアトリビュートをどこに保存しているかだが、どうやらこれは Tarui のコンフィグ保存の仕組みを利用している様子。
保存場所は OS ごとに違うが、Windows の場合は、~/AppData/Roaming/<アプリのidentifier>
に .window-state
というファイル名で保存されているようだ。
これは、以下のソースコードとドキュメントからわかる。
どうやら、最悪リセットする場合はこのファイルを削除すればよさそうだ。
まとめ
ユーザーからもこういうウィンドウ操作の状態保存・再現に関する要望は頻繁に出てくる内容だし、かつ、自分が1ユーザーの時にもこのレベルの対応がされてないと結構ストレスに感じることが多い(毎度 DnD して最適な位置に持って行って、スケールして作業環境を構築するということを毎回強いられるものもある…)。
これで、ウィンドウ状態の保存・再現ができるようになったので、この対応をやるだけでもだいぶウィンドウ操作を前提にしたアプリケーションらしくなったのではと思う。