fix double release

This commit is contained in:
Ferdinand Schober
2024-09-21 17:59:45 +02:00
parent fa63a7e9e5
commit b16f3b272a
6 changed files with 51 additions and 32 deletions

View File

@@ -167,6 +167,7 @@ impl InputCapture {
/// release mouse /// release mouse
pub async fn release(&mut self) -> Result<(), CaptureError> { pub async fn release(&mut self) -> Result<(), CaptureError> {
log::info!("RELEASE CAPTURE");
self.pressed_keys.clear(); self.pressed_keys.clear();
self.capture.release().await self.capture.release().await
} }

View File

@@ -477,10 +477,10 @@ async fn release_capture<'a>(
log::debug!("client entered @ ({x}, {y})"); log::debug!("client entered @ ({x}, {y})");
let (dx, dy) = match current_pos { let (dx, dy) = match current_pos {
// offset cursor position to not enter again immediately // offset cursor position to not enter again immediately
Position::Left => (1., 0.), Position::Left => (10., 0.),
Position::Right => (-1., 0.), Position::Right => (-10., 0.),
Position::Top => (0., 1.), Position::Top => (0., 10.),
Position::Bottom => (0., -1.), Position::Bottom => (0., -10.),
}; };
// release 1px to the right of the entered zone // release 1px to the right of the entered zone
let cursor_position = (x as f64 + dx, y as f64 + dy); let cursor_position = (x as f64 + dx, y as f64 + dy);

View File

@@ -111,7 +111,7 @@ async fn do_capture(
capture.create(handle, to_capture_pos(pos)).await?; capture.create(handle, to_capture_pos(pos)).await?;
} }
let mut state = State::Idle; let mut state = State::Receiving;
loop { loop {
tokio::select! { tokio::select! {
@@ -119,25 +119,27 @@ async fn do_capture(
Some(event) => handle_capture_event(server, &mut capture, conn, event?, &mut state).await?, Some(event) => handle_capture_event(server, &mut capture, conn, event?, &mut state).await?,
None => return Ok(()), None => return Ok(()),
}, },
(handle, event) = conn.recv() => if let Some(active) = server.get_active() { (handle, event) = conn.recv() => {
if handle != active { if let Some(active) = server.get_active() {
// we only care about events coming from the client we are currently connected to if handle != active {
// only `Ack` and `Leave` are relevant // we only care about events coming from the client we are currently connected to
continue // only `Ack` and `Leave` are relevant
continue
}
} }
match event { match event {
// connection acknowlegded => set state to Sending // connection acknowlegded => set state to Sending
ProtoEvent::Ack(_) => state = State::Sending, ProtoEvent::Ack(_) => state = State::Sending,
// client disconnected // client disconnected
ProtoEvent::Leave(_) => release_capture(&mut capture, server, &mut state).await?, ProtoEvent::Leave(_) => release_capture(&mut capture, server).await?,
_ => {} _ => {}
} }
}, },
e = rx.recv() => { e = rx.recv() => {
match e { match e {
Some(e) => match e { Some(e) => match e {
CaptureRequest::Release => release_capture(&mut capture, server, &mut state).await?, CaptureRequest::Release => release_capture(&mut capture, server).await?,
CaptureRequest::Create(h, p) => capture.create(h, p).await?, CaptureRequest::Create(h, p) => capture.create(h, p).await?,
CaptureRequest::Destroy(h) => capture.destroy(h).await?, CaptureRequest::Destroy(h) => capture.destroy(h).await?,
}, },
@@ -173,8 +175,9 @@ macro_rules! debounce {
}; };
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum State { enum State {
Idle, Receiving,
WaitingForAck, WaitingForAck,
Sending, Sending,
} }
@@ -189,14 +192,21 @@ async fn handle_capture_event(
let (handle, event) = event; let (handle, event) = event;
log::trace!("({handle}): {event:?}"); log::trace!("({handle}): {event:?}");
if server.should_release.borrow_mut().take().is_some() if server.should_release.borrow_mut().take().is_some() && *state != State::Receiving {
|| capture.keys_pressed(&server.release_bind) log::info!("releasing capture: a client entered the device");
{ *state = State::Receiving;
return release_capture(capture, server, state).await; return release_capture(capture, server).await;
}
if capture.keys_pressed(&server.release_bind) {
log::info!("releasing capture: release-bind pressed");
return release_capture(capture, server).await;
} }
if event == CaptureEvent::Begin { if event == CaptureEvent::Begin {
*state = State::WaitingForAck; if *state != State::Sending {
*state = State::WaitingForAck;
}
server.set_active(Some(handle)); server.set_active(Some(handle));
spawn_hook_command(server, handle); spawn_hook_command(server, handle);
} }
@@ -204,26 +214,23 @@ async fn handle_capture_event(
let event = match event { let event = match event {
CaptureEvent::Begin => ProtoEvent::Enter(lan_mouse_proto::Position::Left), CaptureEvent::Begin => ProtoEvent::Enter(lan_mouse_proto::Position::Left),
CaptureEvent::Input(e) => match state { CaptureEvent::Input(e) => match state {
State::Sending => ProtoEvent::Input(e),
// connection not acknowledged, repeat `Enter` event // connection not acknowledged, repeat `Enter` event
_ => ProtoEvent::Enter(lan_mouse_proto::Position::Left), State::WaitingForAck => ProtoEvent::Enter(lan_mouse_proto::Position::Left),
_ => ProtoEvent::Input(e),
}, },
}; };
log::info!("CAPTURE {event} >=>=>=>=>=> {handle}");
if let Err(e) = conn.send(event, handle).await { if let Err(e) = conn.send(event, handle).await {
const DUR: Duration = Duration::from_millis(500); // const DUR: Duration = Duration::from_millis(500);
debounce!(PREV_LOG, DUR, log::warn!("releasing capture: {e}")); log::warn!("releasing capture: {e}");
// debounce!(PREV_LOG, DUR, log::warn!("releasing capture: {e}"));
capture.release().await?; capture.release().await?;
} }
Ok(()) Ok(())
} }
async fn release_capture( async fn release_capture(capture: &mut InputCapture, server: &Server) -> Result<(), CaptureError> {
capture: &mut InputCapture,
server: &Server,
state: &mut State,
) -> Result<(), CaptureError> {
*state = State::Idle;
server.set_active(None); server.set_active(None);
capture.release().await capture.release().await
} }

View File

@@ -96,19 +96,19 @@ impl LanMouseConnection {
) -> Result<(), LanMouseConnectionError> { ) -> Result<(), LanMouseConnectionError> {
let (buf, len): ([u8; MAX_EVENT_SIZE], usize) = event.into(); let (buf, len): ([u8; MAX_EVENT_SIZE], usize) = event.into();
let buf = &buf[..len]; let buf = &buf[..len];
log::info!("{event} =>=>=>=>=>=> {handle}");
if let Some(addr) = self.server.active_addr(handle) { if let Some(addr) = self.server.active_addr(handle) {
let conn = { let conn = {
let conns = self.conns.lock().await; let conns = self.conns.lock().await;
conns.get(&addr).cloned() conns.get(&addr).cloned()
}; };
if let Some(conn) = conn { if let Some(conn) = conn {
log::trace!("{event} >->->->->- {addr}"); log::info!("{event} >->->->->- {addr}");
match conn.send(buf).await { match conn.send(buf).await {
Ok(_) => return Ok(()), Ok(_) => return Ok(()),
Err(e) => { Err(e) => {
log::warn!("client {handle} failed to send: {e}"); log::warn!("client {handle} failed to send: {e}");
self.conns.lock().await.remove(&addr); disconnect(&self.server, handle, addr, &self.conns).await;
self.server.set_active_addr(handle, None);
} }
} }
} }
@@ -186,6 +186,7 @@ async fn ping_pong(
) { ) {
loop { loop {
let (buf, len) = ProtoEvent::Ping.into(); let (buf, len) = ProtoEvent::Ping.into();
log::trace!("PING >->->->->- {addr}");
if let Err(e) = conn.send(&buf[..len]).await { if let Err(e) = conn.send(&buf[..len]).await {
log::warn!("send: {e}"); log::warn!("send: {e}");
disconnect(&server, handle, addr, &conns).await; disconnect(&server, handle, addr, &conns).await;

View File

@@ -41,9 +41,15 @@ impl Emulation {
Some(e) => e, Some(e) => e,
None => break, None => break,
}; };
if let ProtoEvent::Ping = event {
log::trace!("{event} <-<-<-<-<- {addr}");
} else {
log::info!("{event} <-<-<-<-<- {addr}");
}
last_response.insert(addr, Instant::now()); last_response.insert(addr, Instant::now());
match event { match event {
ProtoEvent::Enter(_) => { ProtoEvent::Enter(_) => {
log::info!("A CLIENT ENTERED THE DEVICE!");
server.release_capture(); server.release_capture();
listener.reply(addr, ProtoEvent::Ack(0)).await; listener.reply(addr, ProtoEvent::Ack(0)).await;
} }

View File

@@ -51,7 +51,6 @@ impl LanMouseListener {
let tx = listen_tx.clone(); let tx = listen_tx.clone();
let listen_task: JoinHandle<()> = spawn_local(async move { let listen_task: JoinHandle<()> = spawn_local(async move {
loop { loop {
log::info!("accepting ...");
let sleep = tokio::time::sleep(Duration::from_secs(2)); let sleep = tokio::time::sleep(Duration::from_secs(2));
let (conn, addr) = tokio::select! { let (conn, addr) = tokio::select! {
_ = sleep => continue, _ = sleep => continue,
@@ -97,6 +96,11 @@ impl LanMouseListener {
} }
pub(crate) async fn reply(&self, addr: SocketAddr, event: ProtoEvent) { pub(crate) async fn reply(&self, addr: SocketAddr, event: ProtoEvent) {
if let ProtoEvent::Pong = event {
log::trace!("reply {event} >=>=>=>=>=> {addr}");
} else {
log::info!("reply {event} >=>=>=>=>=> {addr}");
}
let (buf, len): ([u8; MAX_EVENT_SIZE], usize) = event.into(); let (buf, len): ([u8; MAX_EVENT_SIZE], usize) = event.into();
let conns = self.conns.lock().await; let conns = self.conns.lock().await;
for (a, conn) in conns.iter() { for (a, conn) in conns.iter() {