tauri_plugin_positioner/
lib.rs1#![doc(
15 html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
16 html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
17)]
18#![cfg(not(any(target_os = "android", target_os = "ios")))]
19
20mod ext;
21
22pub use ext::*;
23use tauri::{
24 plugin::{self, TauriPlugin},
25 Result, Runtime,
26};
27
28#[cfg(feature = "tray-icon")]
29use tauri::{tray::TrayIconEvent, AppHandle, Manager, PhysicalPosition, PhysicalSize};
30
31#[cfg(feature = "tray-icon")]
32struct Tray(std::sync::Mutex<Option<(PhysicalPosition<f64>, PhysicalSize<f64>)>>);
33
34#[cfg(feature = "tray-icon")]
35pub fn on_tray_event<R: Runtime>(app: &AppHandle<R>, event: &TrayIconEvent) {
36 let (position, size) = {
37 match event {
38 TrayIconEvent::Click { rect, .. }
39 | TrayIconEvent::Enter { rect, .. }
40 | TrayIconEvent::Leave { rect, .. }
41 | TrayIconEvent::Move { rect, .. } => {
42 let size = rect.size.to_physical(1.0);
44 let position = rect.position.to_physical(1.0);
45 (position, size)
46 }
47
48 _ => return,
49 }
50 };
51
52 app.state::<Tray>()
53 .0
54 .lock()
55 .unwrap()
56 .replace((position, size));
57}
58
59#[tauri::command]
60async fn move_window<R: Runtime>(window: tauri::Window<R>, position: Position) -> Result<()> {
61 window.move_window(position)
62}
63
64#[cfg(feature = "tray-icon")]
65#[tauri::command]
66async fn move_window_constrained<R: Runtime>(
67 window: tauri::Window<R>,
68 position: Position,
69) -> Result<()> {
70 window.move_window_constrained(position)
71}
72
73#[cfg(feature = "tray-icon")]
74#[tauri::command]
75fn set_tray_icon_state<R: Runtime>(
76 app: AppHandle<R>,
77 position: PhysicalPosition<f64>,
78 size: PhysicalSize<f64>,
79) {
80 app.state::<Tray>()
81 .0
82 .lock()
83 .unwrap()
84 .replace((position, size));
85}
86
87pub fn init<R: Runtime>() -> TauriPlugin<R> {
89 let plugin = plugin::Builder::new("positioner").invoke_handler(tauri::generate_handler![
90 move_window,
91 #[cfg(feature = "tray-icon")]
92 move_window_constrained,
93 #[cfg(feature = "tray-icon")]
94 set_tray_icon_state
95 ]);
96
97 #[cfg(feature = "tray-icon")]
98 let plugin = plugin.setup(|app_handle, _api| {
99 app_handle.manage(Tray(std::sync::Mutex::new(None)));
100 Ok(())
101 });
102
103 plugin.build()
104}