電卓やランチャー、ログイン画面のように「レイアウトを崩されたくない」ウィンドウでは、枠をドラッグして大きさを変えられないようにします。tauri.conf.json の resizable: false で起動時から固定でき、実行中に setResizable()(JS)や set_resizable()(Rust)で切り替えることもできます。「最小サイズと最大サイズを同値にする」方法でも見た目は固定できますが、最大化ボタンやスナップの扱いが変わるので、違いも押さえておきます。
前提条件
プラグインは不要です。JS から切り替える場合、core:window:allow-set-resizable と core:window:allow-set-maximizable は core:window:default に含まれないため src-tauri/capabilities/default.json に追加します。設定ファイルで固定するだけなら権限は不要です。
{
"permissions": [
"core:default",
"core:window:allow-set-resizable",
"core:window:allow-set-maximizable"
]
}
起動時から固定する設定です。resizable: false にすると最大化ボタンも自動で無効になります。
{
"app": {
"windows": [
{ "label": "main", "width": 360, "height": 520, "resizable": false }
]
}
}
1. フロントエンドから実装する (TypeScript)
setResizable(false) で固定し、isResizable()(core:window:default に含まれる)で状態を確認できます。
import { getCurrentWindow } from '@tauri-apps/api/window';
const win = getCurrentWindow();
// モーダルな設定画面を開いている間だけ固定する例
export async function lockSize() {
await win.setResizable(false);
console.log('resizable:', await win.isResizable()); // false
}
export async function unlockSize() {
await win.setResizable(true);
}
// リサイズは許可しつつ最大化ボタンだけ無効にする
export async function disableMaximize() {
await win.setMaximizable(false); // resizable が false のときは無視される
}
min/max サイズで固定する方法との違い
最小・最大サイズの制限 で minWidth = maxWidth、minHeight = maxHeight にしても枠ドラッグでサイズは変わりませんが、次の点が異なります。
| 項目 | resizable: false | min = max で固定 |
|---|---|---|
| 最大化ボタン | 自動で無効 | 有効のまま(押すと OS 依存の挙動) |
| 枠上のカーソル | 通常の矢印 | リサイズカーソルが出る環境あり |
| Windows のスナップ (Win + 矢印) | 無効 | 有効だがサイズは変わらない |
プログラムからの setSize() | 可能 | 範囲外の値は丸められる |
素直に固定するなら resizable: false、「ユーザー操作は禁止したいが最大化は許したい」特殊なケースだけ min/max、と考えれば迷いません。
2. バックエンドから実装する (Rust)
Window / WebviewWindow の set_resizable(bool) と set_maximizable(bool) を使います。ラベル指定で別ウィンドウも固定できます。新規作成時は WebviewWindowBuilder の .resizable(false) / .maximizable(false) です。
use tauri::Manager;
#[tauri::command]
fn set_window_resizable(app: tauri::AppHandle, label: String, resizable: bool) -> Result<(), String> {
let window = app
.get_webview_window(&label)
.ok_or_else(|| format!("window '{}' not found", label))?;
window.set_resizable(resizable).map_err(|e| e.to_string())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![set_window_resizable])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
import { invoke } from '@tauri-apps/api/core';
await invoke('set_window_resizable', { label: 'main', resizable: false });
動作確認
npm run tauri dev で起動し、ウィンドウの端にマウスを合わせてもリサイズカーソルにならず、ドラッグしても大きさが変わらないことを確認します。lockSize() / unlockSize() をボタンに割り当てると、押すたびに最大化ボタンの有効/無効が切り替わるのが見て分かります。コンソールには resizable: false が出ます。
固定中でも setSize() によるプログラムからの変更は通ります。「ユーザー操作を禁止する」設定であって「サイズを不変にする」設定ではありません。
よくあるエラーと対処法
window.set_resizable not allowed. Permissions associated with this command: core:window:allow-set-resizableという趣旨のエラー: 権限未追加です。追加してtauri devを再起動します。setMaximizable(false)を呼んでも変化がない: すでにresizable: falseなら無視されます。Linux ではそもそもサポート外です。- サブウィンドウだけ固定したいのに main が固定された:
app.windows[]の要素でlabelを省略すると"main"扱いです。対象要素に正しいlabelを付けます。 - 固定後に
setSize()で拡大したらコンテンツが切れた: 固定はレイアウトの保証ではありません。CSS の固定幅とウィンドウサイズを揃えてください。
OS ごとの違いと注意点
- Windows:
resizable: falseでは最大化ボタンが無効になるため、タイトルバーのダブルクリックでも最大化されず、Win + 矢印のスナップも効きません。自作タイトルバー(win-006)でもダブルクリック最大化は発生しません。 - macOS: ズーム(緑)ボタンがグレーアウトします。フルスクリーン化はメニューの「フルスクリーンにする」から行われるため、必要なら
setFullscreen側の権限で制御します。 - Linux:
maximizableはサポート外で、resizable: falseの反映もウィンドウマネージャー任せです。タイル型 WM ではサイズ固定が無視されることがあります。 - 別モニターへ移動してスケール倍率が変わると、固定していても物理サイズは変わります。これは正常動作です。
