Skip to main content

soma_tauri_shell/
window.rs

1//! Window show/hide/focus/resize/center/shadow mechanics.
2//!
3//! These helpers operate on an already-resolved `WebviewWindow`. Resolving
4//! the window by label, and deciding *when* to call these (launch, tray
5//! click, global shortcut, ...), stays in the app.
6
7use tauri::{LogicalSize, Size, WebviewWindow};
8
9use crate::command::{CommandResult, TauriResultExt};
10
11/// Hide the window without closing it.
12pub fn hide(window: &WebviewWindow) -> CommandResult<()> {
13    window.hide().command_result()
14}
15
16/// Show, un-maximize (if needed), focus, and raise `window`.
17pub fn show_and_focus(window: &WebviewWindow) -> CommandResult<()> {
18    if window.is_maximized().unwrap_or(false) {
19        if let Err(err) = window.unmaximize() {
20            tracing::warn!("failed to unmaximize window before showing: {err}");
21        }
22    }
23    window.show().command_result()?;
24    window.set_focus().command_result()
25}
26
27/// Resize `window` to `(width, height)` logical pixels, toggle its native
28/// shadow, and re-center it. A maximized window ignores `set_size` on
29/// Windows, so maximize is dropped first.
30pub fn resize_and_center(
31    window: &WebviewWindow,
32    width: f64,
33    height: f64,
34    shadow: bool,
35) -> CommandResult<()> {
36    if window.is_maximized().unwrap_or(false) {
37        if let Err(err) = window.unmaximize() {
38            tracing::warn!("failed to unmaximize window before resizing: {err}");
39        }
40    }
41    window
42        .set_size(Size::Logical(LogicalSize { width, height }))
43        .command_result()?;
44    if let Err(err) = window.set_shadow(shadow) {
45        tracing::warn!("failed to set window shadow: {err}");
46    }
47    window.center().command_result()
48}
49
50/// Flip `window` between maximized and restored.
51pub fn toggle_maximize(window: &WebviewWindow) -> CommandResult<()> {
52    if window.is_maximized().command_result()? {
53        window.unmaximize().command_result()
54    } else {
55        window.maximize().command_result()
56    }
57}
58
59/// Best-effort visibility check; treats an error resolving visibility as
60/// "not visible" so callers default to showing the window.
61pub fn is_visible(window: &WebviewWindow) -> bool {
62    window.is_visible().unwrap_or_else(|err| {
63        tracing::warn!("failed to query window visibility, assuming hidden: {err}");
64        false
65    })
66}
67
68// No unit tests here: every function requires a live `WebviewWindow`, which
69// needs a running Tauri application to construct. These are thin,
70// directly-inspectable wrappers over `tauri::WebviewWindow` methods; the
71// app's own manual/smoke testing (see `apps/palette/CLAUDE.md`) is the
72// verification surface for actual window behavior, matching how
73// `apps/palette/src-tauri` tested this code before extraction.