1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use super::InvokeResponse;
use crate::{Params, Window};
use serde::Deserialize;
#[cfg(global_shortcut_all)]
use crate::{api::shortcuts::ShortcutManager, runtime::Dispatch};
#[cfg(global_shortcut_all)]
type ShortcutManagerHandle = std::sync::Arc<std::sync::Mutex<ShortcutManager>>;
#[cfg(global_shortcut_all)]
pub fn manager_handle() -> &'static ShortcutManagerHandle {
use once_cell::sync::Lazy;
static MANAGER: Lazy<ShortcutManagerHandle> = Lazy::new(Default::default);
&MANAGER
}
#[derive(Deserialize)]
#[serde(tag = "cmd", rename_all = "camelCase")]
pub enum Cmd {
Register { shortcut: String, handler: String },
RegisterAll {
shortcuts: Vec<String>,
handler: String,
},
Unregister { shortcut: String },
UnregisterAll,
IsRegistered { shortcut: String },
}
#[cfg(global_shortcut_all)]
fn register_shortcut<D: Dispatch>(
dispatcher: D,
manager: &mut ShortcutManager,
shortcut: String,
handler: String,
) -> crate::Result<()> {
manager.register(shortcut.clone(), move || {
let callback_string = crate::api::rpc::format_callback(handler.to_string(), &shortcut)
.expect("unable to serialize shortcut string to json");
let _ = dispatcher.eval_script(callback_string.as_str());
})?;
Ok(())
}
#[cfg(not(global_shortcut_all))]
impl Cmd {
pub fn run<P: Params>(self, _window: Window<P>) -> crate::Result<InvokeResponse> {
Err(crate::Error::ApiNotAllowlisted(
"globalShortcut > all".to_string(),
))
}
}
#[cfg(global_shortcut_all)]
impl Cmd {
pub fn run<P: Params>(self, window: Window<P>) -> crate::Result<InvokeResponse> {
match self {
Self::Register { shortcut, handler } => {
let dispatcher = window.dispatcher();
let mut manager = manager_handle().lock().unwrap();
register_shortcut(dispatcher, &mut manager, shortcut, handler)?;
Ok(().into())
}
Self::RegisterAll { shortcuts, handler } => {
let dispatcher = window.dispatcher();
let mut manager = manager_handle().lock().unwrap();
for shortcut in shortcuts {
let dispatch = dispatcher.clone();
register_shortcut(dispatch, &mut manager, shortcut, handler.clone())?;
}
Ok(().into())
}
Self::Unregister { shortcut } => {
let mut manager = manager_handle().lock().unwrap();
manager.unregister(shortcut)?;
Ok(().into())
}
Self::UnregisterAll => {
let mut manager = manager_handle().lock().unwrap();
manager.unregister_all()?;
Ok(().into())
}
Self::IsRegistered { shortcut } => {
let manager = manager_handle().lock().unwrap();
Ok(manager.is_registered(shortcut)?.into())
}
}
}
}