sands/
sands.rs

1use hookmap::macros::button_arg::ButtonArg;
2use hookmap::prelude::*;
3use std::sync::{
4    atomic::{AtomicBool, Ordering},
5    Arc,
6};
7
8fn emulate_sands(hotkey: &mut Hotkey, context: &Context, space: Button, ignored: ButtonArg) {
9    let is_other_key_pressed = Arc::new(AtomicBool::default());
10
11    let mut registrar = hotkey.register(
12        Context::new()
13            .merge(context)
14            .native_event_operation(NativeEventOperation::Block),
15    );
16
17    let is_other_key_pressed_ = Arc::clone(&is_other_key_pressed);
18    registrar.on_press(space, move |_| {
19        is_other_key_pressed_.store(false, Ordering::SeqCst);
20        seq!(LShift down).send();
21    });
22
23    let is_other_key_pressed_ = Arc::clone(&is_other_key_pressed);
24    registrar.on_release(space, move |_| {
25        seq!(LShift up).send();
26        if !is_other_key_pressed_.load(Ordering::SeqCst) {
27            seq!([space]).send();
28        }
29    });
30
31    let target = buttons!(![ignored]);
32    let filter = Filter::new().action(ButtonAction::Press).target(target);
33
34    std::thread::spawn(move || {
35        Interceptor::dispatch(filter)
36            .iter()
37            .for_each(|_| is_other_key_pressed.store(true, Ordering::SeqCst))
38    });
39}
40
41fn main() {
42    let mut hotkey = Hotkey::new();
43    let ignored = buttons!(Space, LShift, RShift, LCtrl, RCtrl, LAlt, RAlt, LShift, RShift);
44
45    emulate_sands(&mut hotkey, &Context::default(), Button::Space, ignored);
46
47    hotkey.install();
48}