Skip to main content

tauri_plugin_frame/
desktop.rs

1use tauri::{Runtime, WebviewWindow};
2
3use crate::error::Result;
4
5pub struct Frame<R: Runtime> {
6    #[allow(dead_code)]
7    app: tauri::AppHandle<R>,
8}
9
10impl<R: Runtime> Frame<R> {
11    pub fn new(app: tauri::AppHandle<R>) -> Self {
12        Self { app }
13    }
14
15    #[cfg(windows)]
16    pub fn titlebar_height(&self) -> u32 {
17        crate::get_titlebar_height()
18    }
19
20    #[cfg(not(windows))]
21    pub fn titlebar_height(&self) -> u32 {
22        32
23    }
24
25    #[cfg(windows)]
26    pub fn auto_titlebar(&self) -> bool {
27        crate::get_auto_titlebar()
28    }
29
30    #[cfg(not(windows))]
31    pub fn auto_titlebar(&self) -> bool {
32        false
33    }
34}
35
36pub trait WebviewWindowExt<R: Runtime> {
37    fn create_overlay_titlebar(&self) -> Result<&WebviewWindow<R>>;
38    fn create_overlay_titlebar_with_height(&self, height: u32) -> Result<&WebviewWindow<R>>;
39}
40
41#[cfg(windows)]
42impl<R: Runtime> WebviewWindowExt<R> for WebviewWindow<R> {
43    fn create_overlay_titlebar(&self) -> Result<&WebviewWindow<R>> {
44        self.create_overlay_titlebar_with_height(crate::get_titlebar_height())
45    }
46
47    fn create_overlay_titlebar_with_height(&self, height: u32) -> Result<&WebviewWindow<R>> {
48        use tauri::Listener;
49
50        self.set_decorations(false)?;
51
52        let win = self.clone();
53        self.listen("frame-page-load", move |event| {
54            let controls: Vec<&str> = [
55                win.is_minimizable().unwrap_or(false).then_some("minimize"),
56                (win.is_maximizable().unwrap_or(false) && win.is_resizable().unwrap_or(false))
57                    .then_some("maximize"),
58                win.is_closable().unwrap_or(false).then_some("close"),
59            ]
60            .into_iter()
61            .flatten()
62            .collect();
63
64            // right_index = number of buttons to the right of the maximize button
65            // Button order (right to left): close, maximize, minimize
66            let right_index = if controls.contains(&"close") { 1 } else { 0 };
67
68            let _ = win.eval(crate::build_scripts(height, Some(controls)));
69            if crate::snap_overlay_enabled() {
70                let _ = crate::snap::install(&win, height, crate::get_button_width(), right_index);
71            }
72
73            let win2 = win.clone();
74            win.on_window_event(move |e| {
75                if matches!(e, tauri::WindowEvent::CloseRequested { .. }) {
76                    let _ = crate::snap::uninstall(&win2);
77                    win2.unlisten(event.id());
78                }
79            });
80        });
81
82        Ok(self)
83    }
84}
85
86#[cfg(not(windows))]
87impl<R: Runtime> WebviewWindowExt<R> for WebviewWindow<R> {
88    fn create_overlay_titlebar(&self) -> Result<&WebviewWindow<R>> {
89        Ok(self)
90    }
91
92    fn create_overlay_titlebar_with_height(&self, _height: u32) -> Result<&WebviewWindow<R>> {
93        Ok(self)
94    }
95}