sharing\natives/
common.rs1use thiserror::Error;
8
9
10#[derive(Error, Debug)]
11pub enum NativeError {
12 #[error("singleton was owned from another pid")]
13 SingletonLocked,
14 #[error("Unable to get singleton handle")]
15 SingletonUnavailable
16}
17
18pub type NativeResult<T> = crate::PisPasResult<T>;
19
20pub trait Lock {
21 fn lock(&self) -> NativeResult<()>;
22
23 fn unlock(&self)-> NativeResult<()> ;
24}
25use std::process::{Command, Stdio};
26
27pub fn show_message_box_non_blocking(message: &str) {
28 let title = "UNPISPAS SERVICIO IMPRESION";
29
30 #[cfg(target_os = "windows")]
31 show_message_box_windows(message, title);
32
33 #[cfg(target_os = "macos")]
34 show_message_box_macos(message, title);
35
36 #[cfg(target_os = "linux")]
37 show_message_box_linux(message, title);
38
39 #[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
40 {
41 tracing::warn!("Message box not supported on this platform: {}", message);
42 println!("{}: {}", title, message);
43 }
44}
45
46#[cfg(target_os = "windows")]
47fn show_message_box_windows(message: &str, title: &str) {
48 let command = format!(
49 "[reflection.assembly]::LoadWithPartialName('System.Windows.Forms')|out-null;[windows.forms.messagebox]::Show('{}', '{}')",
50 message, title
51 );
52
53 let result = Command::new("powershell")
54 .arg("-WindowStyle")
55 .arg("Hidden")
56 .arg("-Command")
57 .arg(command)
58 .stdout(Stdio::null())
59 .stderr(Stdio::piped())
60 .spawn();
61
62 if let Err(e) = result {
63 tracing::error!("Error al ejecutar el comando PowerShell: {}", e);
64 }
65}
66
67#[cfg(target_os = "macos")]
68fn show_message_box_macos(message: &str, title: &str) {
69 let script = format!(
71 "display dialog \"{}\" with title \"{}\" buttons {{\"OK\"}} default button \"OK\"",
72 message.replace("\"", "\\\""),
73 title.replace("\"", "\\\"")
74 );
75
76 let result = Command::new("osascript")
77 .arg("-e")
78 .arg(script)
79 .stdout(Stdio::null())
80 .stderr(Stdio::piped())
81 .spawn();
82
83 if let Err(e) = result {
84 tracing::error!("Error al ejecutar osascript: {}", e);
85
86 fallback_macos_notification(message, title);
88 }
89}
90
91#[cfg(target_os = "macos")]
92fn fallback_macos_notification(message: &str, title: &str) {
93 let result = Command::new("terminal-notifier")
95 .arg("-message")
96 .arg(message)
97 .arg("-title")
98 .arg(title)
99 .arg("-sound")
100 .arg("default")
101 .stdout(Stdio::null())
102 .stderr(Stdio::piped())
103 .spawn();
104
105 if let Err(e) = result {
106 tracing::error!("Error con terminal-notifier: {}", e);
107 let _ = Command::new("say")
109 .arg(format!("{}: {}", title, message))
110 .spawn();
111 }
112}
113
114#[cfg(target_os = "linux")]
115fn show_message_box_linux(message: &str, title: &str) {
116 if try_zenity(message, title) {
120 return;
121 }
122
123 if try_kdialog(message, title) {
125 return;
126 }
127
128 if try_notify_send(message, title) {
130 return;
131 }
132
133 if try_xmessage(message, title) {
135 return;
136 }
137
138 tracing::warn!("No se pudo mostrar message box en Linux: {}", message);
140 println!("{}: {}", title, message);
141}
142
143#[cfg(target_os = "linux")]
144fn try_zenity(message: &str, title: &str) -> bool {
145 Command::new("zenity")
146 .arg("--info")
147 .arg("--title")
148 .arg(title)
149 .arg("--text")
150 .arg(message)
151 .arg("--no-wrap")
152 .stdout(Stdio::null())
153 .stderr(Stdio::piped())
154 .spawn()
155 .is_ok()
156}
157
158#[cfg(target_os = "linux")]
159fn try_kdialog(message: &str, title: &str) -> bool {
160 Command::new("kdialog")
161 .arg("--msgbox")
162 .arg(message)
163 .arg("--title")
164 .arg(title)
165 .stdout(Stdio::null())
166 .stderr(Stdio::piped())
167 .spawn()
168 .is_ok()
169}
170
171#[cfg(target_os = "linux")]
172fn try_notify_send(message: &str, title: &str) -> bool {
173 Command::new("notify-send")
174 .arg(title)
175 .arg(message)
176 .arg("--urgency=normal")
177 .arg("--expire-time=5000") .stdout(Stdio::null())
179 .stderr(Stdio::piped())
180 .spawn()
181 .is_ok()
182}
183
184#[cfg(target_os = "linux")]
185fn try_xmessage(message: &str, title: &str) -> bool {
186 let full_message = format!("{}\n\n{}", title, message);
187 Command::new("xmessage")
188 .arg("-center")
189 .arg(full_message)
190 .stdout(Stdio::null())
191 .stderr(Stdio::piped())
192 .spawn()
193 .is_ok()
194}
195
196pub fn show_message_box_blocking(message: &str) -> bool {
198 let title = "UNPISPAS SERVICIO IMPRESION";
199
200 #[cfg(target_os = "windows")]
201 return show_message_box_blocking_windows(message, title);
202
203 #[cfg(target_os = "macos")]
204 return show_message_box_blocking_macos(message, title);
205
206 #[cfg(target_os = "linux")]
207 return show_message_box_blocking_linux(message, title);
208
209 #[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
210 {
211 println!("{}: {}", title, message);
212 false
213 }
214}
215
216#[cfg(target_os = "windows")]
217fn show_message_box_blocking_windows(message: &str, title: &str) -> bool {
218 let command = format!(
219 "[reflection.assembly]::LoadWithPartialName('System.Windows.Forms')|out-null;[windows.forms.messagebox]::Show('{}', '{}', 'YesNo')",
220 message, title
221 );
222
223 let result = Command::new("powershell")
224 .arg("-WindowStyle")
225 .arg("Hidden")
226 .arg("-Command")
227 .arg(command)
228 .output();
229
230 match result {
231 Ok(output) => {
232 let stdout = String::from_utf8_lossy(&output.stdout);
233 stdout.trim() == "Yes"
234 }
235 Err(e) => {
236 tracing::error!("Error al ejecutar PowerShell: {}", e);
237 false
238 }
239 }
240}
241
242#[cfg(target_os = "macos")]
243fn show_message_box_blocking_macos(message: &str, title: &str) -> bool {
244 let script = format!(
245 "display dialog \"{}\" with title \"{}\" buttons {{\"No\", \"Yes\"}} default button \"Yes\"",
246 message.replace("\"", "\\\""),
247 title.replace("\"", "\\\"")
248 );
249
250 let result = Command::new("osascript")
251 .arg("-e")
252 .arg(script)
253 .output();
254
255 match result {
256 Ok(output) => {
257 let stdout = String::from_utf8_lossy(&output.stdout);
258 stdout.contains("Yes")
259 }
260 Err(e) => {
261 tracing::error!("Error al ejecutar osascript: {}", e);
262 false
263 }
264 }
265}
266
267#[cfg(target_os = "linux")]
268fn show_message_box_blocking_linux(message: &str, title: &str) -> bool {
269 if let Ok(output) = Command::new("zenity")
271 .arg("--question")
272 .arg("--title")
273 .arg(title)
274 .arg("--text")
275 .arg(message)
276 .output()
277 {
278 return output.status.success();
279 }
280
281 if let Ok(output) = Command::new("kdialog")
283 .arg("--yesno")
284 .arg(message)
285 .arg("--title")
286 .arg(title)
287 .output()
288 {
289 return output.status.success();
290 }
291
292 show_message_box_linux(message, title);
294 false
295}