tauri_plugin_snap_layout/
lib_win_impl.rs1use crate::desktop::Snap;
2use serde::{Deserialize, Serialize};
3use tauri::{
4 plugin::{Builder, TauriPlugin},
5 Manager, Runtime,
6};
7
8pub(crate) mod snap;
9
10#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
11pub enum SnapCursor {
12 Arrow,
13 Hand,
14}
15
16#[derive(Clone, Serialize, Deserialize)]
17pub struct SnapConfig {
18 pub button_id: String,
19 pub padding_left: i32,
20 pub padding_right: i32,
21 pub padding_top: i32,
22 pub padding_bottom: i32,
23 pub padding_all: i32,
24 pub display: bool,
25 pub debug_color: String,
26 pub cursor: SnapCursor,
27}
28
29pub struct AreaBuilder {
30 config: SnapConfig,
31}
32
33#[tauri::command(rename_all = "snake_case", name = "update_snap_bounds")]
34fn fallback_update_snap_bounds(_x: i32, _y: i32, _width: i32, _height: i32) {}
35
36#[tauri::command(rename_all = "snake_case", name = "detach_snap_bounds")]
37fn fallback_detach_snap_bounds() {}
38
39impl AreaBuilder {
40 pub fn new() -> Self {
41 Self {
42 config: SnapConfig {
43 button_id: "".into(),
44 padding_left: 0,
45 padding_right: 0,
46 padding_top: 0,
47 padding_bottom: 0,
48 padding_all: 0,
49 display: false,
50 debug_color: "rgba(196, 42, 28, 0.42)".into(),
51 cursor: SnapCursor::Arrow,
52 },
53 }
54 }
55
56 pub fn button_id(mut self, id: impl Into<String>) -> Self {
57 self.config.button_id = id.into();
58 self
59 }
60
61 pub fn padding_left(mut self, padding_left: i32) -> Self {
62 self.config.padding_left = padding_left;
63 self
64 }
65
66 pub fn padding_right(mut self, padding_right: i32) -> Self {
67 self.config.padding_right = padding_right;
68 self
69 }
70
71 pub fn padding_top(mut self, padding_top: i32) -> Self {
72 self.config.padding_top = padding_top;
73 self
74 }
75
76 pub fn padding_bottom(mut self, padding_bottom: i32) -> Self {
77 self.config.padding_bottom = padding_bottom;
78 self
79 }
80
81 pub fn padding_all(mut self, padding_all: i32) -> Self {
82 self.config.padding_all = padding_all;
83 self
84 }
85
86 pub fn display(mut self, is_display: bool) -> Self {
87 self.config.display = is_display;
88 self
89 }
90
91 pub fn debug_color(mut self, color: impl Into<String>) -> Self {
92 self.config.debug_color = color.into();
93 self
94 }
95
96 pub fn cursor(mut self, cursor: SnapCursor) -> Self {
97 self.config.cursor = cursor;
98 self
99 }
100
101 pub fn build<R: Runtime>(self) -> TauriPlugin<R> {
102 let version = windows_version::OsVersion::current();
103 if version.build < 22000 {
104 return Builder::new("snap-layout")
105 .setup(|app, _| {
106 app.manage(Snap::new(app.clone()));
107 Ok(())
108 })
109 .invoke_handler(tauri::generate_handler![
110 fallback_update_snap_bounds,
111 fallback_detach_snap_bounds
112 ])
113 .build();
114 }
115
116 let base_script = include_str!("../dist-js/inline-injection.js");
117
118 let injection_script = base_script
119 .replace(
120 "__SNAP_BUTTON_ID__",
121 &serde_json::to_string(&self.config.button_id)
122 .unwrap_or_else(|_| "\"\"".to_string()),
123 )
124 .replace("__SNAP_DISPLAY__", &self.config.display.to_string())
125 .replace(
126 "__SNAP_DEBUG_COLOR__",
127 &serde_json::to_string(&self.config.debug_color)
128 .unwrap_or_else(|_| "\"\"".to_string()),
129 )
130 .replace(
131 "__SNAP_PADDING_LEFT__",
132 &format!("{}", self.config.padding_left),
133 )
134 .replace(
135 "__SNAP_PADDING_RIGHT__",
136 &format!("{}", self.config.padding_right),
137 )
138 .replace(
139 "__SNAP_PADDING_TOP__",
140 &format!("{}", self.config.padding_top),
141 )
142 .replace(
143 "__SNAP_PADDING_BOTTOM__",
144 &format!("{}", self.config.padding_bottom),
145 )
146 .replace(
147 "__SNAP_PADDING_ALL__",
148 &format!("{}", self.config.padding_all),
149 );
150
151 let plugin_config = self.config.clone();
152
153 Builder::new("snap-layout")
154 .setup(move |app, _| {
155 app.manage(Snap::new(app.clone()));
156 app.manage(plugin_config);
157 Ok(())
158 })
159 .invoke_handler(tauri::generate_handler![
160 snap::update_snap_bounds,
161 snap::detach_snap_bounds
162 ])
163 .js_init_script(injection_script)
164 .build()
165 }
166}