mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-18 18:31:28 +03:00
cleanup
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
use reis::tokio::EiConvertEventStreamError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[cfg(all(unix, feature = "wayland", not(target_os = "macos")))]
|
#[cfg(all(unix, feature = "wayland", not(target_os = "macos")))]
|
||||||
@@ -9,6 +10,39 @@ use wayland_client::{
|
|||||||
ConnectError, DispatchError,
|
ConnectError, DispatchError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||||
|
use reis::tokio::HandshakeError;
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
#[error("error in libei stream: {inner:?}")]
|
||||||
|
pub struct ReisConvertEventStreamError {
|
||||||
|
inner: EiConvertEventStreamError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||||
|
impl From<EiConvertEventStreamError> for ReisConvertEventStreamError {
|
||||||
|
fn from(e: EiConvertEventStreamError) -> Self {
|
||||||
|
Self { inner: e }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum CaptureError {
|
||||||
|
#[error("activation stream closed unexpectedly")]
|
||||||
|
ActivationClosed,
|
||||||
|
#[error("libei stream was closed")]
|
||||||
|
EndOfStream,
|
||||||
|
#[error("io error: `{0}`")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[error("error in libei stream: `{0}`")]
|
||||||
|
Reis(#[from] ReisConvertEventStreamError),
|
||||||
|
#[error("libei handshake failed: `{0}`")]
|
||||||
|
Handshake(#[from] HandshakeError),
|
||||||
|
#[error(transparent)]
|
||||||
|
Portal(#[from] ashpd::Error),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum CaptureCreationError {
|
pub enum CaptureCreationError {
|
||||||
#[error("no backend available")]
|
#[error("no backend available")]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use futures_core::Stream;
|
|||||||
|
|
||||||
use input_event::Event;
|
use input_event::Event;
|
||||||
|
|
||||||
use self::error::CaptureCreationError;
|
pub use error::{CaptureCreationError, CaptureError};
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use anyhow::{anyhow, Result};
|
|
||||||
use ashpd::{
|
use ashpd::{
|
||||||
desktop::{
|
desktop::{
|
||||||
input_capture::{Activated, Barrier, BarrierID, Capabilities, InputCapture, Region, Zones},
|
input_capture::{Activated, Barrier, BarrierID, Capabilities, InputCapture, Region, Zones},
|
||||||
@@ -32,6 +31,8 @@ use once_cell::sync::Lazy;
|
|||||||
|
|
||||||
use input_event::{Event, KeyboardEvent, PointerEvent};
|
use input_event::{Event, KeyboardEvent, PointerEvent};
|
||||||
|
|
||||||
|
use crate::error::{CaptureError, ReisConvertEventStreamError};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
error::LibeiCaptureCreationError, CaptureHandle, InputCapture as LanMouseInputCapture, Position,
|
error::LibeiCaptureCreationError, CaptureHandle, InputCapture as LanMouseInputCapture, Position,
|
||||||
};
|
};
|
||||||
@@ -46,7 +47,7 @@ enum ProducerEvent {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct LibeiInputCapture<'a> {
|
pub struct LibeiInputCapture<'a> {
|
||||||
input_capture: Pin<Box<InputCapture<'a>>>,
|
input_capture: Pin<Box<InputCapture<'a>>>,
|
||||||
libei_task: JoinHandle<Result<()>>,
|
libei_task: JoinHandle<Result<(), CaptureError>>,
|
||||||
event_rx: tokio::sync::mpsc::Receiver<(CaptureHandle, Event)>,
|
event_rx: tokio::sync::mpsc::Receiver<(CaptureHandle, Event)>,
|
||||||
notify_tx: tokio::sync::mpsc::Sender<ProducerEvent>,
|
notify_tx: tokio::sync::mpsc::Sender<ProducerEvent>,
|
||||||
}
|
}
|
||||||
@@ -108,7 +109,7 @@ async fn update_barriers(
|
|||||||
session: &Session<'_>,
|
session: &Session<'_>,
|
||||||
active_clients: &Vec<(CaptureHandle, Position)>,
|
active_clients: &Vec<(CaptureHandle, Position)>,
|
||||||
next_barrier_id: &mut u32,
|
next_barrier_id: &mut u32,
|
||||||
) -> Result<HashMap<BarrierID, CaptureHandle>> {
|
) -> Result<HashMap<BarrierID, CaptureHandle>, ashpd::Error> {
|
||||||
let zones = input_capture.zones(session).await?.response()?;
|
let zones = input_capture.zones(session).await?.response()?;
|
||||||
log::debug!("zones: {zones:?}");
|
log::debug!("zones: {zones:?}");
|
||||||
|
|
||||||
@@ -154,7 +155,7 @@ async fn create_session<'a>(
|
|||||||
async fn connect_to_eis(
|
async fn connect_to_eis(
|
||||||
input_capture: &InputCapture<'_>,
|
input_capture: &InputCapture<'_>,
|
||||||
session: &Session<'_>,
|
session: &Session<'_>,
|
||||||
) -> Result<(ei::Context, EiConvertEventStream)> {
|
) -> Result<(ei::Context, EiConvertEventStream), CaptureError> {
|
||||||
log::debug!("connect_to_eis");
|
log::debug!("connect_to_eis");
|
||||||
let fd = input_capture.connect_to_eis(session).await?;
|
let fd = input_capture.connect_to_eis(session).await?;
|
||||||
|
|
||||||
@@ -165,17 +166,13 @@ async fn connect_to_eis(
|
|||||||
// create ei context
|
// create ei context
|
||||||
let context = ei::Context::new(stream)?;
|
let context = ei::Context::new(stream)?;
|
||||||
let mut event_stream = EiEventStream::new(context.clone())?;
|
let mut event_stream = EiEventStream::new(context.clone())?;
|
||||||
let response = match reis::tokio::ei_handshake(
|
let response = reis::tokio::ei_handshake(
|
||||||
&mut event_stream,
|
&mut event_stream,
|
||||||
"de.feschber.LanMouse",
|
"de.feschber.LanMouse",
|
||||||
ei::handshake::ContextType::Receiver,
|
ei::handshake::ContextType::Receiver,
|
||||||
&INTERFACES,
|
&INTERFACES,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
{
|
|
||||||
Ok(res) => res,
|
|
||||||
Err(e) => return Err(anyhow!("ei handshake failed: {e:?}")),
|
|
||||||
};
|
|
||||||
let event_stream = EiConvertEventStream::new(event_stream, response.serial);
|
let event_stream = EiConvertEventStream::new(event_stream, response.serial);
|
||||||
|
|
||||||
Ok((context, event_stream))
|
Ok((context, event_stream))
|
||||||
@@ -186,13 +183,13 @@ async fn libei_event_handler(
|
|||||||
context: ei::Context,
|
context: ei::Context,
|
||||||
event_tx: Sender<(CaptureHandle, Event)>,
|
event_tx: Sender<(CaptureHandle, Event)>,
|
||||||
current_client: Rc<Cell<Option<CaptureHandle>>>,
|
current_client: Rc<Cell<Option<CaptureHandle>>>,
|
||||||
) -> Result<()> {
|
) -> Result<(), CaptureError> {
|
||||||
loop {
|
loop {
|
||||||
let ei_event = match ei_event_stream.next().await {
|
let ei_event = ei_event_stream
|
||||||
Some(Ok(event)) => event,
|
.next()
|
||||||
Some(Err(e)) => return Err(anyhow!("libei connection closed: {e:?}")),
|
.await
|
||||||
None => return Err(anyhow!("libei connection closed")),
|
.ok_or(CaptureError::EndOfStream)?
|
||||||
};
|
.map_err(ReisConvertEventStreamError::from)?;
|
||||||
log::trace!("from ei: {ei_event:?}");
|
log::trace!("from ei: {ei_event:?}");
|
||||||
let client = current_client.get();
|
let client = current_client.get();
|
||||||
handle_ei_event(ei_event, client, &context, &event_tx).await;
|
handle_ei_event(ei_event, client, &context, &event_tx).await;
|
||||||
@@ -202,136 +199,26 @@ async fn libei_event_handler(
|
|||||||
async fn wait_for_active_client(
|
async fn wait_for_active_client(
|
||||||
notify_rx: &mut Receiver<ProducerEvent>,
|
notify_rx: &mut Receiver<ProducerEvent>,
|
||||||
active_clients: &mut Vec<(CaptureHandle, Position)>,
|
active_clients: &mut Vec<(CaptureHandle, Position)>,
|
||||||
) -> Result<()> {
|
) {
|
||||||
// wait for a client update
|
// wait for a client update
|
||||||
while let Some(producer_event) = notify_rx.recv().await {
|
while let Some(producer_event) = notify_rx.recv().await {
|
||||||
if let ProducerEvent::Create(c, p) = producer_event {
|
if let ProducerEvent::Create(c, p) = producer_event {
|
||||||
handle_producer_event(ProducerEvent::Create(c, p), active_clients)?;
|
handle_producer_event(ProducerEvent::Create(c, p), active_clients);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LibeiInputCapture<'a> {
|
impl<'a> LibeiInputCapture<'a> {
|
||||||
pub async fn new() -> std::result::Result<Self, LibeiCaptureCreationError> {
|
pub async fn new() -> std::result::Result<Self, LibeiCaptureCreationError> {
|
||||||
let input_capture = Box::pin(InputCapture::new().await?);
|
let input_capture = Box::pin(InputCapture::new().await?);
|
||||||
let input_capture_ptr = input_capture.as_ref().get_ref() as *const InputCapture<'static>;
|
let input_capture_ptr = input_capture.as_ref().get_ref() as *const InputCapture<'static>;
|
||||||
let mut first_session = Some(create_session(unsafe { &*input_capture_ptr }).await?);
|
let first_session = Some(create_session(unsafe { &*input_capture_ptr }).await?);
|
||||||
|
|
||||||
let (event_tx, event_rx) = tokio::sync::mpsc::channel(32);
|
let (event_tx, event_rx) = tokio::sync::mpsc::channel(32);
|
||||||
let (notify_tx, mut notify_rx) = tokio::sync::mpsc::channel(32);
|
let (notify_tx, notify_rx) = tokio::sync::mpsc::channel(32);
|
||||||
let libei_task = tokio::task::spawn_local(async move {
|
let capture = do_capture(input_capture_ptr, notify_rx, first_session, event_tx);
|
||||||
/* safety: libei_task does not outlive Self */
|
let libei_task = tokio::task::spawn_local(capture);
|
||||||
let input_capture = unsafe { &*input_capture_ptr };
|
|
||||||
|
|
||||||
let mut active_clients: Vec<(CaptureHandle, Position)> = vec![];
|
|
||||||
let mut next_barrier_id = 1u32;
|
|
||||||
|
|
||||||
/* there is a bug in xdg-remote-desktop-portal-gnome / mutter that
|
|
||||||
* prevents receiving further events after a session has been disabled once.
|
|
||||||
* Therefore the session needs to recreated when the barriers are updated */
|
|
||||||
|
|
||||||
loop {
|
|
||||||
// otherwise it asks to capture input even with no active clients
|
|
||||||
if active_clients.is_empty() {
|
|
||||||
wait_for_active_client(&mut notify_rx, &mut active_clients).await?;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let current_client = Rc::new(Cell::new(None));
|
|
||||||
|
|
||||||
// create session
|
|
||||||
let (session, _) = match first_session.take() {
|
|
||||||
Some(s) => s,
|
|
||||||
_ => create_session(input_capture).await?,
|
|
||||||
};
|
|
||||||
|
|
||||||
// connect to eis server
|
|
||||||
let (context, ei_event_stream) = connect_to_eis(input_capture, &session).await?;
|
|
||||||
|
|
||||||
// async event task
|
|
||||||
let mut ei_task: JoinHandle<Result<(), anyhow::Error>> =
|
|
||||||
tokio::task::spawn_local(libei_event_handler(
|
|
||||||
ei_event_stream,
|
|
||||||
context,
|
|
||||||
event_tx.clone(),
|
|
||||||
current_client.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
let mut activated = input_capture.receive_activated().await?;
|
|
||||||
let mut zones_changed = input_capture.receive_zones_changed().await?;
|
|
||||||
|
|
||||||
// set barriers
|
|
||||||
let client_for_barrier_id = update_barriers(
|
|
||||||
input_capture,
|
|
||||||
&session,
|
|
||||||
&active_clients,
|
|
||||||
&mut next_barrier_id,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
log::debug!("enabling session");
|
|
||||||
input_capture.enable(&session).await?;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
tokio::select! {
|
|
||||||
activated = activated.next() => {
|
|
||||||
let activated = activated.ok_or(anyhow!("error receiving activation token"))?;
|
|
||||||
log::debug!("activated: {activated:?}");
|
|
||||||
|
|
||||||
let client = *client_for_barrier_id
|
|
||||||
.get(&activated.barrier_id())
|
|
||||||
.expect("invalid barrier id");
|
|
||||||
current_client.replace(Some(client));
|
|
||||||
|
|
||||||
event_tx.send((client, Event::Enter())).await?;
|
|
||||||
|
|
||||||
tokio::select! {
|
|
||||||
producer_event = notify_rx.recv() => {
|
|
||||||
let producer_event = producer_event.expect("channel closed");
|
|
||||||
if handle_producer_event(producer_event, &mut active_clients)? {
|
|
||||||
break; /* clients updated */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zones_changed = zones_changed.next() => {
|
|
||||||
log::debug!("zones changed: {zones_changed:?}");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
res = &mut ei_task => {
|
|
||||||
if let Err(e) = res.expect("ei task paniced") {
|
|
||||||
log::warn!("libei task exited: {e}");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
release_capture(
|
|
||||||
input_capture,
|
|
||||||
&session,
|
|
||||||
activated,
|
|
||||||
client,
|
|
||||||
&active_clients,
|
|
||||||
).await?;
|
|
||||||
}
|
|
||||||
producer_event = notify_rx.recv() => {
|
|
||||||
let producer_event = producer_event.expect("channel closed");
|
|
||||||
if handle_producer_event(producer_event, &mut active_clients)? {
|
|
||||||
/* clients updated */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
res = &mut ei_task => {
|
|
||||||
if let Err(e) = res.expect("ei task paniced") {
|
|
||||||
log::warn!("libei task exited: {e}");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ei_task.abort();
|
|
||||||
input_capture.disable(&session).await?;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let producer = Self {
|
let producer = Self {
|
||||||
input_capture,
|
input_capture,
|
||||||
@@ -344,13 +231,139 @@ impl<'a> LibeiInputCapture<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn do_capture<'a>(
|
||||||
|
input_capture_ptr: *const InputCapture<'static>,
|
||||||
|
mut notify_rx: Receiver<ProducerEvent>,
|
||||||
|
mut first_session: Option<(Session<'a>, BitFlags<Capabilities>)>,
|
||||||
|
event_tx: Sender<(CaptureHandle, Event)>,
|
||||||
|
) -> Result<(), CaptureError> {
|
||||||
|
/* safety: libei_task does not outlive Self */
|
||||||
|
let input_capture = unsafe { &*input_capture_ptr };
|
||||||
|
|
||||||
|
let mut active_clients: Vec<(CaptureHandle, Position)> = vec![];
|
||||||
|
let mut next_barrier_id = 1u32;
|
||||||
|
|
||||||
|
/* there is a bug in xdg-remote-desktop-portal-gnome / mutter that
|
||||||
|
* prevents receiving further events after a session has been disabled once.
|
||||||
|
* Therefore the session needs to recreated when the barriers are updated */
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// otherwise it asks to capture input even with no active clients
|
||||||
|
if active_clients.is_empty() {
|
||||||
|
wait_for_active_client(&mut notify_rx, &mut active_clients).await;
|
||||||
|
if notify_rx.is_closed() {
|
||||||
|
break Ok(());
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_client = Rc::new(Cell::new(None));
|
||||||
|
|
||||||
|
// create session
|
||||||
|
let (session, _) = match first_session.take() {
|
||||||
|
Some(s) => s,
|
||||||
|
_ => create_session(input_capture).await?,
|
||||||
|
};
|
||||||
|
|
||||||
|
// connect to eis server
|
||||||
|
let (context, ei_event_stream) = connect_to_eis(input_capture, &session).await?;
|
||||||
|
|
||||||
|
// async event task
|
||||||
|
let mut ei_task: JoinHandle<Result<(), CaptureError>> =
|
||||||
|
tokio::task::spawn_local(libei_event_handler(
|
||||||
|
ei_event_stream,
|
||||||
|
context,
|
||||||
|
event_tx.clone(),
|
||||||
|
current_client.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut activated = input_capture.receive_activated().await?;
|
||||||
|
let mut zones_changed = input_capture.receive_zones_changed().await?;
|
||||||
|
|
||||||
|
// set barriers
|
||||||
|
let client_for_barrier_id = update_barriers(
|
||||||
|
input_capture,
|
||||||
|
&session,
|
||||||
|
&active_clients,
|
||||||
|
&mut next_barrier_id,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
log::debug!("enabling session");
|
||||||
|
input_capture.enable(&session).await?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
tokio::select! {
|
||||||
|
activated = activated.next() => {
|
||||||
|
let activated = activated.ok_or(CaptureError::ActivationClosed)?;
|
||||||
|
log::debug!("activated: {activated:?}");
|
||||||
|
|
||||||
|
let client = *client_for_barrier_id
|
||||||
|
.get(&activated.barrier_id())
|
||||||
|
.expect("invalid barrier id");
|
||||||
|
current_client.replace(Some(client));
|
||||||
|
|
||||||
|
if event_tx.send((client, Event::Enter())).await.is_err() {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
tokio::select! {
|
||||||
|
producer_event = notify_rx.recv() => {
|
||||||
|
let producer_event = producer_event.expect("channel closed");
|
||||||
|
if handle_producer_event(producer_event, &mut active_clients) {
|
||||||
|
break; /* clients updated */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zones_changed = zones_changed.next() => {
|
||||||
|
log::debug!("zones changed: {zones_changed:?}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
res = &mut ei_task => {
|
||||||
|
if let Err(e) = res.expect("ei task paniced") {
|
||||||
|
log::warn!("libei task exited: {e}");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
release_capture(
|
||||||
|
input_capture,
|
||||||
|
&session,
|
||||||
|
activated,
|
||||||
|
client,
|
||||||
|
&active_clients,
|
||||||
|
).await?;
|
||||||
|
}
|
||||||
|
producer_event = notify_rx.recv() => {
|
||||||
|
let producer_event = producer_event.expect("channel closed");
|
||||||
|
if handle_producer_event(producer_event, &mut active_clients) {
|
||||||
|
/* clients updated */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
res = &mut ei_task => {
|
||||||
|
if let Err(e) = res.expect("ei task paniced") {
|
||||||
|
log::warn!("libei task exited: {e}");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ei_task.abort();
|
||||||
|
input_capture.disable(&session).await?;
|
||||||
|
if event_tx.is_closed() {
|
||||||
|
break Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn release_capture(
|
async fn release_capture(
|
||||||
input_capture: &InputCapture<'_>,
|
input_capture: &InputCapture<'_>,
|
||||||
session: &Session<'_>,
|
session: &Session<'_>,
|
||||||
activated: Activated,
|
activated: Activated,
|
||||||
current_client: CaptureHandle,
|
current_client: CaptureHandle,
|
||||||
active_clients: &[(CaptureHandle, Position)],
|
active_clients: &[(CaptureHandle, Position)],
|
||||||
) -> Result<()> {
|
) -> Result<(), CaptureError> {
|
||||||
log::debug!("releasing input capture {}", activated.activation_id());
|
log::debug!("releasing input capture {}", activated.activation_id());
|
||||||
let (x, y) = activated.cursor_position();
|
let (x, y) = activated.cursor_position();
|
||||||
let pos = active_clients
|
let pos = active_clients
|
||||||
@@ -377,9 +390,9 @@ async fn release_capture(
|
|||||||
fn handle_producer_event(
|
fn handle_producer_event(
|
||||||
producer_event: ProducerEvent,
|
producer_event: ProducerEvent,
|
||||||
active_clients: &mut Vec<(CaptureHandle, Position)>,
|
active_clients: &mut Vec<(CaptureHandle, Position)>,
|
||||||
) -> Result<bool> {
|
) -> bool {
|
||||||
log::debug!("handling event: {producer_event:?}");
|
log::debug!("handling event: {producer_event:?}");
|
||||||
let updated = match producer_event {
|
match producer_event {
|
||||||
ProducerEvent::Release => false,
|
ProducerEvent::Release => false,
|
||||||
ProducerEvent::Create(c, p) => {
|
ProducerEvent::Create(c, p) => {
|
||||||
active_clients.push((c, p));
|
active_clients.push((c, p));
|
||||||
@@ -389,8 +402,7 @@ fn handle_producer_event(
|
|||||||
active_clients.retain(|(h, _)| *h != c);
|
active_clients.retain(|(h, _)| *h != c);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
Ok(updated)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_ei_event(
|
async fn handle_ei_event(
|
||||||
|
|||||||
@@ -38,11 +38,7 @@ async fn input_emulation_test(config: Config) -> Result<()> {
|
|||||||
let relative_motion = (new_offset.0 - offset.0, new_offset.1 - offset.1);
|
let relative_motion = (new_offset.0 - offset.0, new_offset.1 - offset.1);
|
||||||
offset = new_offset;
|
offset = new_offset;
|
||||||
let (dx, dy) = (relative_motion.0 as f64, relative_motion.1 as f64);
|
let (dx, dy) = (relative_motion.0 as f64, relative_motion.1 as f64);
|
||||||
let event = Event::Pointer(PointerEvent::Motion {
|
let event = Event::Pointer(PointerEvent::Motion { time: 0, dx, dy });
|
||||||
time: 0,
|
|
||||||
dx: dx,
|
|
||||||
dy: dy,
|
|
||||||
});
|
|
||||||
emulation.consume(event, 0).await?;
|
emulation.consume(event, 0).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ async fn udp_receiver(
|
|||||||
receiver_tx: &Sender<Result<(Event, SocketAddr), NetworkError>>,
|
receiver_tx: &Sender<Result<(Event, SocketAddr), NetworkError>>,
|
||||||
) {
|
) {
|
||||||
loop {
|
loop {
|
||||||
let event = receive_event(&socket).await;
|
let event = receive_event(socket).await;
|
||||||
if let Err(_) = receiver_tx.send(event).await {
|
if receiver_tx.send(event).await.is_err() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ async fn udp_sender(socket: &UdpSocket, rx: &mut Receiver<(Event, SocketAddr)>)
|
|||||||
Some(e) => e,
|
Some(e) => e,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
if let Err(e) = send_event(&socket, event, addr) {
|
if let Err(e) = send_event(socket, event, addr) {
|
||||||
log::warn!("udp send failed: {e}");
|
log::warn!("udp send failed: {e}");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user