Lock
Block one physical input; injection still drives itA lock blocks the physical device from one input, while host injection still drives that same input. Lock what the user shouldn't touch, then drive it yourself.
a locked input:
physical --X blocked
injected --> still reaches the PC| Block a... | Lock | Release |
|---|---|---|
| relative axis (X / Y / wheel) | lock / lock_axis | unlock / unlock_axis |
| button, key, or media usage | lock | unlock |
| a whole class (blanket) | lock_all | unlock_all |
All are fire-and-forget: one frame, no reply. query_locks reads the active set.
lock
Block a physical inputfn lock(&self, target: impl Into<LockTarget>, direction: LockDirection) -> Result<()>
Fire-and-forget
LockTarget picks the input and LockDirection picks the sign or edge. For an axis or the wheel the direction is a sign, so you can block scrolling up but not down; for a usage it's an edge, so you can block the press but not the release.
| Parameter | Type | Description |
|---|---|---|
target | impl Into<LockTarget> | An Axis (X, Y, or wheel) or any Usage (a button, key, or media usage). |
direction | LockDirection | Both, Positive (axis +, usage press), or Negative (axis -, usage release). |
A lock blocks the physical device only, and holds until you unlock it. The box also clears every lock on control-PC silence, on reset, or on inter-chip link loss. See the native LOCK command for the wire layout.
use medius::{Device, Axis, Button, Key, LockDirection};
let device = Device::find()?;
device.lock(Axis::X, LockDirection::Both)?; // freeze horizontal motion
device.lock(Button::Left, LockDirection::Positive)?; // block left-click press
device.lock(Key::LEFT_GUI, LockDirection::Both)?; // block the GUI/Windows key
device.move_rel(50, 0)?; // injection still moves Xunlock
Clear a blockfn unlock(&self, target: impl Into<LockTarget>, direction: LockDirection) -> Result<()>
Fire-and-forget
The inverse of lock: same target and direction, but it clears the block instead of setting it. Hand a physical input back to the user.
use medius::{Device, Axis, LockDirection};
let device = Device::find()?;
device.unlock(Axis::X, LockDirection::Both)?; // hand horizontal motion backlock_axis / unlock_axis
Block a relative axis by signfn lock_axis(&self, axis: Axis, direction: LockDirection) -> Result<()>
fn unlock_axis(&self, axis: Axis, direction: LockDirection) -> Result<()>
Fire-and-forget
Convenience for lock / unlock with an Axis. The direction is a sign, so a positive-only lock freezes scroll-up while scroll-down still passes.
use medius::{Device, Axis, LockDirection};
let device = Device::find()?;
device.lock_axis(Axis::Wheel, LockDirection::Positive)?; // block scroll up, keep scroll down
device.unlock_axis(Axis::Wheel, LockDirection::Positive)?;lock_all / unlock_all
Blanket-block a whole classfn lock_all(&self, what: Blanket, direction: LockDirection) -> Result<()>
fn unlock_all(&self, what: Blanket, direction: LockDirection) -> Result<()>
Fire-and-forget
Block an entire input group at once with a Blanket (Aim, Wheel, Buttons, Keys, or Media); direction applies to the whole group. Injection still drives any field you choose to.
use medius::{Device, Blanket, LockDirection};
let device = Device::find()?;
device.lock_all(Blanket::Keys, LockDirection::Both)?; // every physical key blocked
device.unlock_all(Blanket::Keys, LockDirection::Both)?;On AsyncDevice
locks fire, query_locks awaitsAsyncDevice keeps every lock call synchronous (lock/unlock, lock_axis, and lock_all with their unlock pairs) since they expect no reply; query_locks is a future like the other queries.
use futures::executor::block_on;
use medius::{AsyncDevice, Axis, LockDirection};
let device = AsyncDevice::open("/dev/ttyACM0")?;
device.lock(Axis::Y, LockDirection::Both)?; // sync, no await
let locks = block_on(device.query_locks())?; // query awaits