tauri-plugin-decor 1.0.1

Opinionated window decoration controls for Tauri apps.
Documentation
use crate::decor::{Decor, DecorExt, DecorStyle};
use crate::error::Result;
use tauri::{AppHandle, Runtime};

#[tauri::command]
pub fn update_style<R: Runtime>(app: AppHandle<R>, style: DecorStyle) -> Result<()> {
    let decor: &Decor<R> = app.decor();
    decor.reconfigure(style);
    Ok(())
}

#[cfg(target_os = "windows")]
static SNAP_INPUT_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());

#[cfg(target_os = "windows")]
fn snap_layout_supported() -> bool {
    windows_version::OsVersion::current().build >= 22000
}

#[cfg(target_os = "windows")]
#[tauri::command]
pub async fn show_snap_overlay() -> Result<()> {
    use crate::error::Error;

    if !snap_layout_supported() {
        return Ok(());
    }
    let delay_ms = crate::config::snap_overlay_delay_ms();
    match tauri::async_runtime::spawn_blocking(move || run_snap_overlay_keys(delay_ms)).await {
        Ok(Ok(())) => Ok(()),
        Ok(Err(e)) => Err(e),
        Err(e) => Err(Error::from(eyre::eyre!("spawn_blocking join: {e}"))),
    }
}

#[cfg(target_os = "windows")]
fn run_snap_overlay_keys(delay_ms: u64) -> Result<()> {
    use crate::error::Error;
    use enigo::{
        Direction::{Click, Press, Release},
        Enigo, Key, Keyboard, Settings,
    };
    use std::time::Duration;

    let _guard = SNAP_INPUT_LOCK
        .lock()
        .map_err(|e| Error::from(eyre::eyre!("snap input lock: {e}")))?;

    let mut enigo =
        Enigo::new(&Settings::default()).map_err(|e| Error::from(eyre::eyre!("{e}")))?;

    enigo
        .key(Key::Meta, Press)
        .map_err(|e| Error::from(eyre::eyre!("{e}")))?;
    enigo
        .key(Key::Z, Click)
        .map_err(|e| Error::from(eyre::eyre!("{e}")))?;
    enigo
        .key(Key::Meta, Release)
        .map_err(|e| Error::from(eyre::eyre!("{e}")))?;

    std::thread::sleep(Duration::from_millis(delay_ms.max(1)));

    for key in [Key::Meta, Key::Alt, Key::Control, Key::Shift] {
        enigo.key(key, Release).ok();
    }

    Ok(())
}

#[cfg(not(target_os = "windows"))]
#[tauri::command]
pub async fn show_snap_overlay() -> Result<()> {
    Ok(())
}