mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-03-07 11:59:59 +03:00
track pressed keys in input-capture (#170)
move pressed key tracking to input capture
This commit is contained in:
committed by
GitHub
parent
096567640c
commit
266ad28c6b
@@ -8,7 +8,7 @@ use input_event::Event;
|
||||
|
||||
use crate::CaptureError;
|
||||
|
||||
use super::{CaptureHandle, InputCapture, Position};
|
||||
use super::{Capture, CaptureHandle, Position};
|
||||
|
||||
pub struct DummyInputCapture {}
|
||||
|
||||
@@ -25,7 +25,7 @@ impl Default for DummyInputCapture {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl InputCapture for DummyInputCapture {
|
||||
impl Capture for DummyInputCapture {
|
||||
async fn create(&mut self, _handle: CaptureHandle, _pos: Position) -> Result<(), CaptureError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
use std::fmt::Display;
|
||||
use std::{collections::HashSet, fmt::Display, task::Poll};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use futures::StreamExt;
|
||||
use futures_core::Stream;
|
||||
|
||||
use input_event::Event;
|
||||
use input_event::{scancode, Event, KeyboardEvent};
|
||||
|
||||
pub use error::{CaptureCreationError, CaptureError, InputCaptureError};
|
||||
|
||||
pub mod error;
|
||||
|
||||
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||
pub mod libei;
|
||||
mod libei;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod macos;
|
||||
mod macos;
|
||||
|
||||
#[cfg(all(unix, feature = "wayland", not(target_os = "macos")))]
|
||||
pub mod wayland;
|
||||
mod wayland;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub mod windows;
|
||||
mod windows;
|
||||
|
||||
#[cfg(all(unix, feature = "x11", not(target_os = "macos")))]
|
||||
pub mod x11;
|
||||
mod x11;
|
||||
|
||||
/// fallback input capture (does not produce events)
|
||||
pub mod dummy;
|
||||
mod dummy;
|
||||
|
||||
pub type CaptureHandle = u64;
|
||||
|
||||
@@ -93,10 +94,79 @@ impl Display for Backend {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InputCapture {
|
||||
capture: Box<dyn Capture>,
|
||||
pressed_keys: HashSet<scancode::Linux>,
|
||||
}
|
||||
|
||||
impl InputCapture {
|
||||
/// create a new client with the given id
|
||||
pub async fn create(&mut self, id: CaptureHandle, pos: Position) -> Result<(), CaptureError> {
|
||||
self.capture.create(id, pos).await
|
||||
}
|
||||
|
||||
/// destroy the client with the given id, if it exists
|
||||
pub async fn destroy(&mut self, id: CaptureHandle) -> Result<(), CaptureError> {
|
||||
self.capture.destroy(id).await
|
||||
}
|
||||
|
||||
/// release mouse
|
||||
pub async fn release(&mut self) -> Result<(), CaptureError> {
|
||||
self.pressed_keys.clear();
|
||||
self.capture.release().await
|
||||
}
|
||||
|
||||
/// destroy the input capture
|
||||
pub async fn terminate(&mut self) -> Result<(), CaptureError> {
|
||||
self.capture.terminate().await
|
||||
}
|
||||
|
||||
/// creates a new [`InputCapture`]
|
||||
pub async fn new(backend: Option<Backend>) -> Result<Self, CaptureCreationError> {
|
||||
let capture = create(backend).await?;
|
||||
Ok(Self {
|
||||
capture,
|
||||
pressed_keys: HashSet::new(),
|
||||
})
|
||||
}
|
||||
|
||||
/// check whether the given keys are pressed
|
||||
pub fn keys_pressed(&self, keys: &[scancode::Linux]) -> bool {
|
||||
keys.iter().all(|k| self.pressed_keys.contains(k))
|
||||
}
|
||||
|
||||
fn update_pressed_keys(&mut self, key: u32, state: u8) {
|
||||
if let Ok(scancode) = scancode::Linux::try_from(key) {
|
||||
log::debug!("key: {key}, state: {state}, scancode: {scancode:?}");
|
||||
match state {
|
||||
1 => self.pressed_keys.insert(scancode),
|
||||
_ => self.pressed_keys.remove(&scancode),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for InputCapture {
|
||||
type Item = Result<(CaptureHandle, Event), CaptureError>;
|
||||
|
||||
fn poll_next(
|
||||
mut self: std::pin::Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> Poll<Option<Self::Item>> {
|
||||
match self.capture.poll_next_unpin(cx) {
|
||||
Poll::Ready(e) => {
|
||||
if let Some(Ok((_, Event::Keyboard(KeyboardEvent::Key { key, state, .. })))) = e {
|
||||
self.update_pressed_keys(key, state);
|
||||
}
|
||||
Poll::Ready(e)
|
||||
}
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait InputCapture:
|
||||
Stream<Item = Result<(CaptureHandle, Event), CaptureError>> + Unpin
|
||||
{
|
||||
trait Capture: Stream<Item = Result<(CaptureHandle, Event), CaptureError>> + Unpin {
|
||||
/// create a new client with the given id
|
||||
async fn create(&mut self, id: CaptureHandle, pos: Position) -> Result<(), CaptureError>;
|
||||
|
||||
@@ -110,10 +180,10 @@ pub trait InputCapture:
|
||||
async fn terminate(&mut self) -> Result<(), CaptureError>;
|
||||
}
|
||||
|
||||
pub async fn create_backend(
|
||||
async fn create_backend(
|
||||
backend: Backend,
|
||||
) -> Result<
|
||||
Box<dyn InputCapture<Item = Result<(CaptureHandle, Event), CaptureError>>>,
|
||||
Box<dyn Capture<Item = Result<(CaptureHandle, Event), CaptureError>>>,
|
||||
CaptureCreationError,
|
||||
> {
|
||||
match backend {
|
||||
@@ -131,10 +201,10 @@ pub async fn create_backend(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create(
|
||||
async fn create(
|
||||
backend: Option<Backend>,
|
||||
) -> Result<
|
||||
Box<dyn InputCapture<Item = Result<(CaptureHandle, Event), CaptureError>>>,
|
||||
Box<dyn Capture<Item = Result<(CaptureHandle, Event), CaptureError>>>,
|
||||
CaptureCreationError,
|
||||
> {
|
||||
if let Some(backend) = backend {
|
||||
|
||||
@@ -38,7 +38,7 @@ use input_event::Event;
|
||||
|
||||
use super::{
|
||||
error::{CaptureError, LibeiCaptureCreationError, ReisConvertEventStreamError},
|
||||
CaptureHandle, InputCapture as LanMouseInputCapture, Position,
|
||||
Capture as LanMouseInputCapture, CaptureHandle, Position,
|
||||
};
|
||||
|
||||
/* there is a bug in xdg-remote-desktop-portal-gnome / mutter that
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
error::MacOSInputCaptureCreationError, CaptureError, CaptureHandle, InputCapture, Position,
|
||||
error::MacOSInputCaptureCreationError, Capture, CaptureError, CaptureHandle, Position,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use futures_core::Stream;
|
||||
@@ -24,7 +24,7 @@ impl Stream for MacOSInputCapture {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl InputCapture for MacOSInputCapture {
|
||||
impl Capture for MacOSInputCapture {
|
||||
async fn create(&mut self, _id: CaptureHandle, _pos: Position) -> Result<(), CaptureError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -58,15 +58,13 @@ use wayland_client::{
|
||||
Connection, Dispatch, DispatchError, EventQueue, QueueHandle, WEnum,
|
||||
};
|
||||
|
||||
use tempfile;
|
||||
|
||||
use input_event::{Event, KeyboardEvent, PointerEvent};
|
||||
|
||||
use crate::CaptureError;
|
||||
|
||||
use super::{
|
||||
error::{LayerShellCaptureCreationError, WaylandBindError},
|
||||
CaptureHandle, InputCapture, Position,
|
||||
Capture, CaptureHandle, Position,
|
||||
};
|
||||
|
||||
struct Globals {
|
||||
@@ -561,7 +559,7 @@ impl Inner {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl InputCapture for WaylandInputCapture {
|
||||
impl Capture for WaylandInputCapture {
|
||||
async fn create(&mut self, handle: CaptureHandle, pos: Position) -> Result<(), CaptureError> {
|
||||
self.add_client(handle, pos);
|
||||
let inner = self.0.get_mut();
|
||||
|
||||
@@ -37,7 +37,7 @@ use input_event::{
|
||||
Event, KeyboardEvent, PointerEvent, BTN_BACK, BTN_FORWARD, BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,
|
||||
};
|
||||
|
||||
use super::{CaptureError, CaptureHandle, InputCapture, Position};
|
||||
use super::{Capture, CaptureError, CaptureHandle, Position};
|
||||
|
||||
enum Request {
|
||||
Create(CaptureHandle, Position),
|
||||
@@ -64,7 +64,7 @@ unsafe fn signal_message_thread(event_type: EventType) {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl InputCapture for WindowsInputCapture {
|
||||
impl Capture for WindowsInputCapture {
|
||||
async fn create(&mut self, handle: CaptureHandle, pos: Position) -> Result<(), CaptureError> {
|
||||
unsafe {
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ use futures_core::Stream;
|
||||
|
||||
use crate::CaptureError;
|
||||
|
||||
use super::InputCapture;
|
||||
use super::Capture;
|
||||
use input_event::Event;
|
||||
|
||||
use super::error::X11InputCaptureCreationError;
|
||||
@@ -20,7 +20,7 @@ impl X11InputCapture {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl InputCapture for X11InputCapture {
|
||||
impl Capture for X11InputCapture {
|
||||
async fn create(&mut self, _id: CaptureHandle, _pos: Position) -> Result<(), CaptureError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user