Skip to main content

InputBackend

Trait InputBackend 

Source
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 return Ok(()) 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 return Error::Cancelled to 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§

Source

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,

Press and release a single X11 keysym. Implementations handle any inter-event timing required by the transport. Equivalent to key_down immediately followed by key_up.

Source

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.

Source

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).

Source

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.

Source

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.

Source

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,

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.

Source

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,

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).

Source

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§

Source

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,

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.

Implementors§