mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-03 21:01:27 +03:00
move enter hook logic to service (where it belongs)
This commit is contained in:
@@ -8,13 +8,9 @@ use futures::StreamExt;
|
|||||||
use input_capture::{
|
use input_capture::{
|
||||||
CaptureError, CaptureEvent, CaptureHandle, InputCapture, InputCaptureError, Position,
|
CaptureError, CaptureEvent, CaptureHandle, InputCapture, InputCaptureError, Position,
|
||||||
};
|
};
|
||||||
use lan_mouse_ipc::ClientHandle;
|
|
||||||
use lan_mouse_proto::ProtoEvent;
|
use lan_mouse_proto::ProtoEvent;
|
||||||
use local_channel::mpsc::{channel, Receiver, Sender};
|
use local_channel::mpsc::{channel, Receiver, Sender};
|
||||||
use tokio::{
|
use tokio::task::{spawn_local, JoinHandle};
|
||||||
process::Command,
|
|
||||||
task::{spawn_local, JoinHandle},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{connect::LanMouseConnection, service::Service};
|
use crate::{connect::LanMouseConnection, service::Service};
|
||||||
|
|
||||||
@@ -28,11 +24,18 @@ pub(crate) struct Capture {
|
|||||||
|
|
||||||
pub(crate) enum ICaptureEvent {
|
pub(crate) enum ICaptureEvent {
|
||||||
/// a client was entered
|
/// a client was entered
|
||||||
ClientEntered(CaptureHandle),
|
CaptureBegin(CaptureHandle),
|
||||||
/// capture disabled
|
/// capture disabled
|
||||||
CaptureDisabled,
|
CaptureDisabled,
|
||||||
/// capture disabled
|
/// capture disabled
|
||||||
CaptureEnabled,
|
CaptureEnabled,
|
||||||
|
/// A (new) client was entered.
|
||||||
|
/// In contrast to [`ICaptureEvent::CaptureBegin`] this
|
||||||
|
/// event is only triggered when the capture was
|
||||||
|
/// explicitly released in the meantime by
|
||||||
|
/// either the remote client leaving its device region,
|
||||||
|
/// a new device entering the screen or the release bind.
|
||||||
|
ClientEntered(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -309,7 +312,7 @@ async fn handle_capture_event(
|
|||||||
|
|
||||||
if event == CaptureEvent::Begin {
|
if event == CaptureEvent::Begin {
|
||||||
event_tx
|
event_tx
|
||||||
.send(ICaptureEvent::ClientEntered(handle))
|
.send(ICaptureEvent::CaptureBegin(handle))
|
||||||
.expect("channel closed");
|
.expect("channel closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,8 +334,9 @@ async fn handle_capture_event(
|
|||||||
if event == CaptureEvent::Begin && Some(handle) != active.get() {
|
if event == CaptureEvent::Begin && Some(handle) != active.get() {
|
||||||
*state = State::WaitingForAck;
|
*state = State::WaitingForAck;
|
||||||
active.replace(Some(handle));
|
active.replace(Some(handle));
|
||||||
log::info!("entering client {handle} ...");
|
event_tx
|
||||||
spawn_hook_command(service, handle);
|
.send(ICaptureEvent::ClientEntered(handle))
|
||||||
|
.expect("channel closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
let pos = match service.client_manager.get_pos(handle) {
|
let pos = match service.client_manager.get_pos(handle) {
|
||||||
@@ -345,7 +349,7 @@ async fn handle_capture_event(
|
|||||||
CaptureEvent::Input(e) => match state {
|
CaptureEvent::Input(e) => match state {
|
||||||
// connection not acknowledged, repeat `Enter` event
|
// connection not acknowledged, repeat `Enter` event
|
||||||
State::WaitingForAck => ProtoEvent::Enter(pos),
|
State::WaitingForAck => ProtoEvent::Enter(pos),
|
||||||
_ => ProtoEvent::Input(e),
|
State::Sending => ProtoEvent::Input(e),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -383,32 +387,6 @@ fn to_proto_pos(pos: lan_mouse_ipc::Position) -> lan_mouse_proto::Position {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_hook_command(service: &Service, handle: ClientHandle) {
|
|
||||||
let Some(cmd) = service.client_manager.get_enter_cmd(handle) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
tokio::task::spawn_local(async move {
|
|
||||||
log::info!("spawning command!");
|
|
||||||
let mut child = match Command::new("sh").arg("-c").arg(cmd.as_str()).spawn() {
|
|
||||||
Ok(c) => c,
|
|
||||||
Err(e) => {
|
|
||||||
log::warn!("could not execute cmd: {e}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
match child.wait().await {
|
|
||||||
Ok(s) => {
|
|
||||||
if s.success() {
|
|
||||||
log::info!("{cmd} exited successfully");
|
|
||||||
} else {
|
|
||||||
log::warn!("{cmd} exited with {s}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => log::warn!("{cmd}: {e}"),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn wait_for_termination(rx: &mut Receiver<CaptureRequest>) {
|
async fn wait_for_termination(rx: &mut Receiver<CaptureRequest>) {
|
||||||
loop {
|
loop {
|
||||||
match rx.recv().await.expect("channel closed") {
|
match rx.recv().await.expect("channel closed") {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use std::{
|
|||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tokio::{signal, sync::Notify};
|
use tokio::{process::Command, signal, sync::Notify};
|
||||||
use webrtc_dtls::crypto::Certificate;
|
use webrtc_dtls::crypto::Certificate;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
@@ -284,7 +284,7 @@ impl Service {
|
|||||||
EmulationEvent::ReleaseNotify => capture.release(),
|
EmulationEvent::ReleaseNotify => capture.release(),
|
||||||
},
|
},
|
||||||
event = capture.event() => match event {
|
event = capture.event() => match event {
|
||||||
ICaptureEvent::ClientEntered(handle) => {
|
ICaptureEvent::CaptureBegin(handle) => {
|
||||||
// we entered the capture zone for an incoming connection
|
// we entered the capture zone for an incoming connection
|
||||||
// => notify it that its capture should be released
|
// => notify it that its capture should be released
|
||||||
if let Some(incoming) = self.incoming_conn_info.borrow().get(&handle) {
|
if let Some(incoming) = self.incoming_conn_info.borrow().get(&handle) {
|
||||||
@@ -299,6 +299,10 @@ impl Service {
|
|||||||
self.capture_status.replace(Status::Enabled);
|
self.capture_status.replace(Status::Enabled);
|
||||||
self.notify_frontend(FrontendEvent::CaptureStatus(Status::Enabled));
|
self.notify_frontend(FrontendEvent::CaptureStatus(Status::Enabled));
|
||||||
}
|
}
|
||||||
|
ICaptureEvent::ClientEntered(handle) => {
|
||||||
|
log::info!("entering client {handle} ...");
|
||||||
|
self.spawn_hook_command(handle)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
event = resolver.event() => match event {
|
event = resolver.event() => match event {
|
||||||
DnsEvent::Resolving(handle) => self.set_resolving(handle, true),
|
DnsEvent::Resolving(handle) => self.set_resolving(handle, true),
|
||||||
@@ -497,4 +501,30 @@ impl Service {
|
|||||||
self.client_manager.set_resolving(handle, status);
|
self.client_manager.set_resolving(handle, status);
|
||||||
self.client_updated(handle);
|
self.client_updated(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn spawn_hook_command(&self, handle: ClientHandle) {
|
||||||
|
let Some(cmd) = self.client_manager.get_enter_cmd(handle) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
tokio::task::spawn_local(async move {
|
||||||
|
log::info!("spawning command!");
|
||||||
|
let mut child = match Command::new("sh").arg("-c").arg(cmd.as_str()).spawn() {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("could not execute cmd: {e}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match child.wait().await {
|
||||||
|
Ok(s) => {
|
||||||
|
if s.success() {
|
||||||
|
log::info!("{cmd} exited successfully");
|
||||||
|
} else {
|
||||||
|
log::warn!("{cmd} exited with {s}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => log::warn!("{cmd}: {e}"),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user