tauri-plugin-decor 1.0.1

Opinionated window decoration controls for Tauri apps.
Documentation
#[cfg(any(target_os = "windows", target_os = "linux"))]
mod html {
    use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering};
    use std::sync::RwLock;

    pub(crate) const DEFAULT_TITLEBAR_HEIGHT: u32 = 32;
    pub(crate) const DEFAULT_BUTTON_WIDTH: u32 = 46;
    pub(crate) const DEFAULT_CONTROLS_SCALE: f64 = 1.0;
    pub(crate) const DEFAULT_CLOSE_HOVER_BG: &str = "rgba(196,43,28,1)";
    pub(crate) const DEFAULT_BUTTON_HOVER_BG: &str = "rgba(0,0,0,0.2)";

    pub(crate) static BASE_TITLEBAR_HEIGHT: AtomicU32 = AtomicU32::new(DEFAULT_TITLEBAR_HEIGHT);
    pub(crate) static BASE_BUTTON_WIDTH: AtomicU32 = AtomicU32::new(DEFAULT_BUTTON_WIDTH);
    pub(crate) static CONTROLS_SCALE_BITS: AtomicU64 =
        AtomicU64::new(DEFAULT_CONTROLS_SCALE.to_bits());
    pub(crate) static AUTO_TITLEBAR: AtomicBool = AtomicBool::new(false);
    pub(crate) static CLOSE_HOVER_BG: RwLock<String> = RwLock::new(String::new());
    pub(crate) static BUTTON_HOVER_BG: RwLock<String> = RwLock::new(String::new());

    pub fn controls_scale() -> f64 {
        f64::from_bits(CONTROLS_SCALE_BITS.load(Ordering::SeqCst))
    }

    pub fn set_controls_scale(value: f64) {
        CONTROLS_SCALE_BITS.store(value.to_bits(), Ordering::SeqCst);
    }

    pub fn base_titlebar_height() -> u32 {
        BASE_TITLEBAR_HEIGHT.load(Ordering::SeqCst)
    }

    pub fn set_titlebar_height(value: u32) {
        BASE_TITLEBAR_HEIGHT.store(value, Ordering::SeqCst);
    }

    pub fn titlebar_height() -> u32 {
        let scaled = (base_titlebar_height() as f64) * controls_scale();
        scaled.round().max(1.0) as u32
    }

    pub fn base_button_width() -> u32 {
        BASE_BUTTON_WIDTH.load(Ordering::SeqCst)
    }

    pub fn set_button_width(value: u32) {
        BASE_BUTTON_WIDTH.store(value, Ordering::SeqCst);
    }

    pub fn button_width() -> u32 {
        let scaled = (base_button_width() as f64) * controls_scale();
        scaled.round().max(1.0) as u32
    }

    pub fn auto_titlebar() -> bool {
        AUTO_TITLEBAR.load(Ordering::SeqCst)
    }

    pub fn set_auto_titlebar(value: bool) {
        AUTO_TITLEBAR.store(value, Ordering::SeqCst);
    }

    pub fn close_hover_bg() -> String {
        CLOSE_HOVER_BG
            .read()
            .expect("decor: close_hover_bg lock poisoned")
            .clone()
    }

    pub fn set_close_hover_bg(value: impl Into<String>) {
        *CLOSE_HOVER_BG
            .write()
            .expect("decor: close_hover_bg lock poisoned") = value.into();
    }

    pub fn button_hover_bg() -> String {
        BUTTON_HOVER_BG
            .read()
            .expect("decor: button_hover_bg lock poisoned")
            .clone()
    }

    pub fn set_button_hover_bg(value: impl Into<String>) {
        *BUTTON_HOVER_BG
            .write()
            .expect("decor: button_hover_bg lock poisoned") = value.into();
    }

    pub(crate) fn store(
        titlebar_height: u32,
        button_width: u32,
        controls_scale: f64,
        auto_titlebar: bool,
        close_hover_bg: String,
        button_hover_bg: String,
    ) {
        set_titlebar_height(titlebar_height);
        set_button_width(button_width);
        set_controls_scale(controls_scale);
        set_auto_titlebar(auto_titlebar);
        set_close_hover_bg(close_hover_bg);
        set_button_hover_bg(button_hover_bg);
    }
}

#[cfg(any(target_os = "windows", target_os = "linux"))]
pub use html::*;

#[cfg(target_os = "windows")]
mod windows_only {
    use std::sync::atomic::{AtomicU64, Ordering};

    pub(crate) static SNAP_OVERLAY_DELAY_MS: AtomicU64 = AtomicU64::new(10);

    pub fn snap_overlay_delay_ms() -> u64 {
        SNAP_OVERLAY_DELAY_MS.load(Ordering::SeqCst)
    }

    pub fn set_snap_overlay_delay_ms(value: u64) {
        SNAP_OVERLAY_DELAY_MS.store(value, Ordering::SeqCst);
    }

    pub(crate) fn store_snap(snap_overlay_delay_ms: u64) {
        set_snap_overlay_delay_ms(snap_overlay_delay_ms);
    }
}

#[cfg(target_os = "windows")]
pub use windows_only::*;

#[cfg(target_os = "macos")]
mod macos_only {
    use std::sync::atomic::{AtomicU64, Ordering};

    const DEFAULT_INSET_X: f64 = 12.0;
    const DEFAULT_INSET_Y: f64 = 16.0;
    const DEFAULT_SPACING: f64 = 20.0;
    const DEFAULT_SCALE: f64 = 1.0;

    static TRAFFIC_INSET_X: AtomicU64 = AtomicU64::new(DEFAULT_INSET_X.to_bits());
    static TRAFFIC_INSET_Y: AtomicU64 = AtomicU64::new(DEFAULT_INSET_Y.to_bits());
    static TRAFFIC_SPACING: AtomicU64 = AtomicU64::new(DEFAULT_SPACING.to_bits());
    static TRAFFIC_SCALE: AtomicU64 = AtomicU64::new(DEFAULT_SCALE.to_bits());

    fn store_bits(slot: &AtomicU64, value: f64) {
        slot.store(value.to_bits(), Ordering::SeqCst);
    }

    fn load_bits(slot: &AtomicU64) -> f64 {
        f64::from_bits(slot.load(Ordering::SeqCst))
    }

    pub fn traffic_inset_x() -> f64 {
        load_bits(&TRAFFIC_INSET_X)
    }

    pub fn set_traffic_inset_x(value: f64) {
        store_bits(&TRAFFIC_INSET_X, value);
    }

    pub fn traffic_inset_y() -> f64 {
        load_bits(&TRAFFIC_INSET_Y)
    }

    pub fn set_traffic_inset_y(value: f64) {
        store_bits(&TRAFFIC_INSET_Y, value);
    }

    pub fn traffic_spacing() -> f64 {
        load_bits(&TRAFFIC_SPACING)
    }

    pub fn set_traffic_spacing(value: f64) {
        store_bits(&TRAFFIC_SPACING, value);
    }

    pub fn traffic_scale() -> f64 {
        load_bits(&TRAFFIC_SCALE)
    }

    pub fn set_traffic_scale(value: f64) {
        store_bits(&TRAFFIC_SCALE, value);
    }

    pub(crate) fn store_traffic(inset_x: f64, inset_y: f64, spacing: f64, scale: f64) {
        set_traffic_inset_x(inset_x);
        set_traffic_inset_y(inset_y);
        set_traffic_spacing(spacing);
        set_traffic_scale(scale);
    }
}

#[cfg(target_os = "macos")]
pub use macos_only::*;