5 releases

0.1.4 Jun 18, 2023
0.1.3 Jun 17, 2023
0.1.2 Jun 17, 2023
0.1.1 Jun 17, 2023
0.1.0 Jun 17, 2023

#904 in Asynchronous

26 downloads per month
Used in shortcutd

MIT/Apache

33KB
860 lines

evdev-shortcut

Global shortcuts using evdev

Usage

use std::path::PathBuf;
use glob::GlobError;
use evdev_shortcut::{ShortcutListener, Shortcut, Modifier, Key};
use tokio::pin;
use futures::stream::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = ShortcutListener::new();
    listener.add(Shortcut::new(&[Modifier::Meta], Key::KeyN));
    
    let devices =
        glob::glob("/dev/input/by-id/*-kbd")?.collect::<Result<Vec<PathBuf>, GlobError>>()?;
    
    let stream = listener.listen(&devices)?;
    pin!(stream);
    
    while let Some(event) = stream.next().await {
        println!("{} {}", event.shortcut, event.state);
    }
    Ok(())
}

Note that raw access to evdev devices is a privileged operation and usually requires running with elevated privileges. See shortcutd for a solution to running the elevated input handling in a separate process.


lib.rs:

Global keyboard shortcuts using evdev.

By connecting to the input devices directly with evdev the shortcuts can work regardless of the environment, they will work under X11, wayland and in the terminal.

This does come at the cost of having to run the program with elevated permissions. See shortcutd for a solution to running the elevated input handling in a separate process.

Example:

let listener = ShortcutListener::new();
listener.add(Shortcut::new(&[Modifier::Meta], Key::KeyN));

let devices =
    glob::glob("/dev/input/by-id/*-kbd")?.collect::<Result<Vec<PathBuf>, GlobError>>()?;

let stream = listener.listen(&devices)?;
pin!(stream);

while let Some(event) = stream.next().await {
    println!("{} {}", event.shortcut, event.state);
}

Dependencies

~3–14MB
~145K SLoC