Medius - Rust LibraryCatch

Catch

Stream the physical mouse and keyboard input

catch_events subscribes to the user's real input and hands back an EventStream of CatchEvent snapshots, relative motion and held-usage sets, captured before any lock suppression or injection. Drop the stream to unsubscribe.

catch_events

Subscribe to the physical-input stream
fn catch_events(&self, mask: CatchMask) -> Result<EventStream>

Fire-and-forget

CatchMask picks which classes of change emit an event: MOTION, WHEEL, BUTTONS,KEYS, MEDIA, combined with |, or CatchMask::all() for the full mirror. The returned EventStream receives every event; the subscribe itself sends one frame and doesn't wait for a reply.

PARAMETERS
ParameterTypeDescription
maskCatchMaskBitmask selecting which input classes emit events (see above).

The subscription is held alive by the library's keepalive (which re-asserts it after a device-side blip) and across a reconnect; it clears like injection: on control-PC silence, a reset (which ends the stream, so its recv returns Err), or link loss. The reported input is the user's physical input; a locked or injected target still reports its real hand value here. See the native CATCH command for the wire layout.

EXAMPLE
use medius::{Device, CatchMask, CatchEvent, Button};

let device = Device::find()?;
let events = device.catch_events(CatchMask::all())?;   // or MOTION | BUTTONS | KEYS | MEDIA
while let Ok(event) = events.recv() {
    match event {
        CatchEvent::Motion(m) => println!("dx={} dy={} dz={}", m.dx, m.dy, m.dz),
        CatchEvent::Usages(u) if u.is_held(Button::Side1) => {
            // the side button is held; rebind it...
        }
        CatchEvent::Usages(u) => println!("{} usages held", u.usages.len()),
    }
}
// dropping `events` unsubscribes

EventStream

Receive physical-input reports

The handle catch_events returns. Pull CatchEvent snapshots with whichever method fits your loop; cloning shares the queue (like LogStream). When the stream and all its clones drop, the subscription ends and the box returns to passthrough.

METHODS
MethodReturnsDescription
recv()Result<CatchEvent>Block until the next event.
try_recv()Option<CatchEvent>The next buffered event, or None (never blocks).
recv_timeout(dur)Option<CatchEvent>Block up to dur; None on timeout.
try_iter()impl IteratorDrain every buffered event without blocking.
recv_async().awaitResult<CatchEvent>Await the next event (async feature), runtime-agnostic.
dropped()u64Events lost host-side because this consumer fell behind.

The buffer is bounded and lossy: a slow consumer drops the OLDEST events, keeping the freshest input (count them with dropped()). The box's own drop count, under back-pressure on the wire, is on query_catch.

On AsyncDevice

catch_events fires, the stream awaits

AsyncDevice keeps catch_events synchronous (it just sends the subscribe and returns the stream) while the stream itself offers recv_async().await. query_catch is a future, like the other queries.

EXAMPLE
use medius::{AsyncDevice, CatchMask};

let device = AsyncDevice::open("/dev/ttyACM0")?;
let events = device.catch_events(CatchMask::BUTTONS)?;   // sync, no await
let report = events.recv_async().await?;                 // stream awaits