pub trait InputBackend: Send + Sync {
// Required methods
fn press_keysym<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn key_down<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn key_up<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn pointer_motion_relative<'life0, 'life1, 'async_trait>(
&'life0 self,
dx: f64,
dy: f64,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn pointer_motion_absolute<'life0, 'life1, 'async_trait>(
&'life0 self,
x: f64,
y: f64,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn pointer_button_down<'life0, 'life1, 'async_trait>(
&'life0 self,
button: PointerButton,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn pointer_button_up<'life0, 'life1, 'async_trait>(
&'life0 self,
button: PointerButton,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn pointer_axis_discrete<'life0, 'life1, 'async_trait>(
&'life0 self,
axis: PointerAxis,
steps: i32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
// Provided method
fn pointer_button<'life0, 'life1, 'async_trait>(
&'life0 self,
button: PointerButton,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
}Expand description
Keyboard and pointer injection. Decoupled from the compositor trait so alternative implementations (e.g. libei) can drive the same compositor alongside a mutter/KWin/wlroots backend.
§Cancellation convention
Every method accepts a CancellationToken. The token is the
Session’s own cancellation handle, forwarded by
Session-level wrappers so individual backend calls can observe it
without the caller needing to plumb it themselves.
Implementations must treat cancellation as follows:
- Atomic press/release gaps must complete. Backends that press a key (or button) down, wait, then release must not bail during that gap — doing so would leave a key stuck in the compositor’s state. The gap is short (single-digit to tens of ms) so running it to completion costs little.
- Tail throttles may bail. Backends that sleep after an event
committed (so back-to-back events don’t overwhelm the app) should
race the sleep against
cancel.cancelled()and returnOk(())early on cancel — the event already succeeded and the throttle is a courtesy. Higher-level loops (e.g.Session::type_text) pick up the cancellation on their next pre-flight check and returnError::Cancelledto the caller. - Pre-event checks are optional — the outer loops already short-circuit, so there’s no correctness requirement to re-check at the backend boundary. Backends may still check if it saves setup work (e.g. a D-Bus call).
Required Methods§
Sourcefn press_keysym<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn press_keysym<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Sourcefn key_down<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn key_down<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Press a key and hold it down until a corresponding
key_up fires. Used to build modifier combos — hold
Ctrl down across a target keystroke and release it afterward.
Sourcefn key_up<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn key_up<'life0, 'life1, 'async_trait>(
&'life0 self,
keysym: u32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Release a key that was previously pressed with
key_down. Safe to call on a key that isn’t held
(behavior is implementation-defined, but must not panic).
Sourcefn pointer_motion_relative<'life0, 'life1, 'async_trait>(
&'life0 self,
dx: f64,
dy: f64,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pointer_motion_relative<'life0, 'life1, 'async_trait>(
&'life0 self,
dx: f64,
dy: f64,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Move the pointer by a relative offset in logical pixels.
Sourcefn pointer_motion_absolute<'life0, 'life1, 'async_trait>(
&'life0 self,
x: f64,
y: f64,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pointer_motion_absolute<'life0, 'life1, 'async_trait>(
&'life0 self,
x: f64,
y: f64,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Move the pointer to a screen-relative absolute position in logical
pixels. Implementations route through whatever channel their
compositor exposes (e.g. NotifyPointerMotionAbsolute on mutter’s
RemoteDesktop). Backends with no active capture stream to address
should return Err.
Press a pointer button and hold it down until a corresponding
pointer_button_up fires. The
PointerButton enum carries either one of the three named
buttons or a raw Linux evdev BTN_* code via Other(u32).
Used to build drag gestures — press, move the pointer across
intermediate coordinates, then release.
Release a pointer button that was previously pressed with
pointer_button_down. Safe to call on
a button that isn’t held (behavior is implementation-defined, but
must not panic).
Sourcefn pointer_axis_discrete<'life0, 'life1, 'async_trait>(
&'life0 self,
axis: PointerAxis,
steps: i32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pointer_axis_discrete<'life0, 'life1, 'async_trait>(
&'life0 self,
axis: PointerAxis,
steps: i32,
cancel: &'life1 CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Emit a discrete pointer-axis (wheel) event. axis selects the
direction (PointerAxis::Vertical / Horizontal); steps is
the number of wheel detents; positive scrolls down / right,
negative scrolls up / left.
Backends that don’t support discrete wheel events may emulate
via continuous axis deltas; callers shouldn’t rely on step being
exactly one wheel click’s worth of travel, just on sign + rough
magnitude. Backends translate the enum into their transport’s
native encoding (mutter’s RemoteDesktop wants 0=vertical, 1=horizontal, libei has its own enum).
Provided Methods§
Press and release a pointer button. Default impl composes
pointer_button_down and
pointer_button_up with a short gap so
the compositor distinguishes press from release; backends with a
more efficient combined path can override.
The 20 ms press/release gap is atomic: we do not race it
against the token because cancelling mid-gap would leave the
button held down in the compositor’s state. Cancellation
observed on the tail of pointer_button_up (or at the outer
loop’s next iteration) is the designed bail-point.