Skip to content

Commit bcff275

Browse files
committed
macos: fix key-release with repeat logic
1 parent b071201 commit bcff275

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

input-emulation/src/macos.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use core_graphics::event_source::{CGEventSource, CGEventSourceStateID};
1111
use input_event::{Event, KeyboardEvent, PointerEvent};
1212
use keycode::{KeyMap, KeyMapping};
1313
use std::ops::{Index, IndexMut};
14+
use std::sync::Arc;
1415
use std::time::Duration;
15-
use tokio::task::AbortHandle;
16+
use tokio::{sync::Notify, task::JoinHandle};
1617

1718
use super::error::MacOSEmulationCreationError;
1819

@@ -21,8 +22,9 @@ const DEFAULT_REPEAT_INTERVAL: Duration = Duration::from_millis(32);
2122

2223
pub(crate) struct MacOSEmulation {
2324
event_source: CGEventSource,
24-
repeat_task: Option<AbortHandle>,
25+
repeat_task: Option<JoinHandle<()>>,
2526
button_state: ButtonState,
27+
notify_repeat_task: Arc<Notify>,
2628
}
2729

2830
struct ButtonState {
@@ -68,6 +70,7 @@ impl MacOSEmulation {
6870
event_source,
6971
button_state,
7072
repeat_task: None,
73+
notify_repeat_task: Arc::new(Notify::new()),
7174
})
7275
}
7376

@@ -79,20 +82,27 @@ impl MacOSEmulation {
7982
async fn spawn_repeat_task(&mut self, key: u16) {
8083
// there can only be one repeating key and it's
8184
// always the last to be pressed
82-
self.kill_repeat_task();
85+
self.cancel_repeat_task().await;
8386
let event_source = self.event_source.clone();
87+
let notify = self.notify_repeat_task.clone();
8488
let repeat_task = tokio::task::spawn_local(async move {
85-
tokio::time::sleep(DEFAULT_REPEAT_DELAY).await;
8689
loop {
90+
tokio::select! {
91+
_ = tokio::time::sleep(DEFAULT_REPEAT_INTERVAL) => {},
92+
_ = notify.notified() => break,
93+
}
8794
key_event(event_source.clone(), key, 1);
88-
tokio::time::sleep(DEFAULT_REPEAT_INTERVAL).await;
8995
}
96+
// release key when cancelled
97+
key_event(event_source.clone(), key, 0);
9098
});
91-
self.repeat_task = Some(repeat_task.abort_handle());
99+
self.repeat_task = Some(repeat_task);
92100
}
93-
fn kill_repeat_task(&mut self) {
101+
102+
async fn cancel_repeat_task(&mut self) {
94103
if let Some(task) = self.repeat_task.take() {
95-
task.abort();
104+
self.notify_repeat_task.notify_waiters();
105+
task.await;
96106
}
97107
}
98108
}
@@ -346,7 +356,7 @@ impl Emulation for MacOSEmulation {
346356
match state {
347357
// pressed
348358
1 => self.spawn_repeat_task(code).await,
349-
_ => self.kill_repeat_task(),
359+
_ => self.cancel_repeat_task().await,
350360
}
351361
key_event(self.event_source.clone(), code, state)
352362
}

0 commit comments

Comments
 (0)