feat(windows): persist size + position across restarts via tauri-plugin-window-state
Without this, every secondary window (preview overlay, task float, transcript viewer) opened at whatever spot Tauri / the compositor picked, which was especially noticeable on Wayland where placement hints are advisory. Main window's position was also lost on restart. Registering tauri_plugin_window_state in the builder gives automatic per-window-label save + restore. State lives in app-data/window-state.json; fresh installs still fall back to the builder defaults (no changes to inner_size on any of the four windows). Covers OpenWhispr issue #605 and the broader UX pain. No frontend changes — the plugin is purely backend. Regenerated ACL manifests / desktop + linux schemas pick up the plugin registration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ tauri-plugin-opener = "2"
|
|||||||
tauri-plugin-dialog = "2"
|
tauri-plugin-dialog = "2"
|
||||||
tauri-plugin-global-shortcut = "2"
|
tauri-plugin-global-shortcut = "2"
|
||||||
tauri-plugin-updater = "2"
|
tauri-plugin-updater = "2"
|
||||||
|
tauri-plugin-window-state = "2"
|
||||||
|
|
||||||
# Serialisation
|
# Serialisation
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -2545,6 +2545,48 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "updater:deny-install",
|
"const": "updater:deny-install",
|
||||||
"markdownDescription": "Denies the install command without any pre-configured scope."
|
"markdownDescription": "Denies the install command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n\n#### This default permission set includes:\n\n- `allow-filename`\n- `allow-restore-state`\n- `allow-save-window-state`",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:default",
|
||||||
|
"markdownDescription": "This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n\n#### This default permission set includes:\n\n- `allow-filename`\n- `allow-restore-state`\n- `allow-save-window-state`"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the filename command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:allow-filename",
|
||||||
|
"markdownDescription": "Enables the filename command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the restore_state command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:allow-restore-state",
|
||||||
|
"markdownDescription": "Enables the restore_state command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the save_window_state command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:allow-save-window-state",
|
||||||
|
"markdownDescription": "Enables the save_window_state command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the filename command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:deny-filename",
|
||||||
|
"markdownDescription": "Denies the filename command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the restore_state command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:deny-restore-state",
|
||||||
|
"markdownDescription": "Denies the restore_state command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the save_window_state command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:deny-save-window-state",
|
||||||
|
"markdownDescription": "Denies the save_window_state command without any pre-configured scope."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2545,6 +2545,48 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "updater:deny-install",
|
"const": "updater:deny-install",
|
||||||
"markdownDescription": "Denies the install command without any pre-configured scope."
|
"markdownDescription": "Denies the install command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n\n#### This default permission set includes:\n\n- `allow-filename`\n- `allow-restore-state`\n- `allow-save-window-state`",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:default",
|
||||||
|
"markdownDescription": "This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n\n#### This default permission set includes:\n\n- `allow-filename`\n- `allow-restore-state`\n- `allow-save-window-state`"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the filename command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:allow-filename",
|
||||||
|
"markdownDescription": "Enables the filename command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the restore_state command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:allow-restore-state",
|
||||||
|
"markdownDescription": "Enables the restore_state command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the save_window_state command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:allow-save-window-state",
|
||||||
|
"markdownDescription": "Enables the save_window_state command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the filename command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:deny-filename",
|
||||||
|
"markdownDescription": "Denies the filename command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the restore_state command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:deny-restore-state",
|
||||||
|
"markdownDescription": "Denies the restore_state command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the save_window_state command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "window-state:deny-save-window-state",
|
||||||
|
"markdownDescription": "Denies the save_window_state command without any pre-configured scope."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -128,6 +128,12 @@ pub fn run() {
|
|||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
|
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
|
||||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||||
|
// Remember size + position of every window across app restarts.
|
||||||
|
// Without this, secondary windows (preview overlay, task float,
|
||||||
|
// transcript viewer) open at whatever spot the compositor picks,
|
||||||
|
// which feels random. State is persisted per-window-label to
|
||||||
|
// app-data/window-state.json.
|
||||||
|
.plugin(tauri_plugin_window_state::Builder::default().build())
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
// Initialise database (blocking in setup — runs once at startup)
|
// Initialise database (blocking in setup — runs once at startup)
|
||||||
let db_path = database_path();
|
let db_path = database_path();
|
||||||
|
|||||||
Reference in New Issue
Block a user