-
Notifications
You must be signed in to change notification settings - Fork 130
/
custom_tap_hold.rs
58 lines (54 loc) · 2.26 KB
/
custom_tap_hold.rs
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
use kanata_keyberon::layout::{Event, QueuedIter, WaitingAction};
use crate::keys::OsCode;
use super::alloc::Allocations;
/// Returns a closure that can be used in `HoldTapConfig::Custom`, which will return early with a
/// Tap action in the case that any of `keys` are pressed. Otherwise it behaves as
/// `HoldTapConfig::PermissiveHold` would.
pub(crate) fn custom_tap_hold_release(
keys: &[OsCode],
a: &Allocations,
) -> &'static (dyn Fn(QueuedIter) -> (Option<WaitingAction>, bool) + Send + Sync) {
let keys = a.sref_vec(Vec::from_iter(keys.iter().copied()));
a.sref(
move |mut queued: QueuedIter| -> (Option<WaitingAction>, bool) {
while let Some(q) = queued.next() {
if q.event().is_press() {
let (i, j) = q.event().coord();
// If any key matches the input, do a tap right away.
if keys.iter().copied().map(u16::from).any(|j2| j2 == j) {
return (Some(WaitingAction::Tap), false);
}
// Otherwise do the PermissiveHold algorithm.
let target = Event::Release(i, j);
if queued.clone().copied().any(|q| q.event() == target) {
return (Some(WaitingAction::Hold), false);
}
}
}
(None, false)
},
)
}
pub(crate) fn custom_tap_hold_except(
keys: &[OsCode],
a: &Allocations,
) -> &'static (dyn Fn(QueuedIter) -> (Option<WaitingAction>, bool) + Send + Sync) {
let keys = a.sref_vec(Vec::from_iter(keys.iter().copied()));
a.sref(
move |mut queued: QueuedIter| -> (Option<WaitingAction>, bool) {
for q in queued.by_ref() {
if q.event().is_press() {
let (_i, j) = q.event().coord();
// If any key matches the input, do a tap.
if keys.iter().copied().map(u16::from).any(|j2| j2 == j) {
return (Some(WaitingAction::Tap), false);
}
// Otherwise continue with default behavior
return (None, false);
}
}
// Otherwise skip timeout
(None, true)
},
)
}