Skip to content

Instantly share code, notes, and snippets.

@taoky
Last active November 11, 2024 07:26
Show Gist options
  • Save taoky/c344472cd9c878a56f2b845bb85bbc14 to your computer and use it in GitHub Desktop.
Save taoky/c344472cd9c878a56f2b845bb85bbc14 to your computer and use it in GitHub Desktop.
Simulate keyboard input in GNOME/KDE Wayland
[package]
name = "keyboardsim"
version = "0.1.0"
edition = "2021"
[dependencies]
ashpd = "0.10.2"
keycode = "0.4.0"
tokio = { version = "1.41.1", features = ["full"] }
// [dependencies]
// ashpd = "0.10.2"
// xkbcommon = "0.8.0"
// tokio = { version = "1.41.1", features = ["full"] }
use std::{fs::File, io::Read, process::exit, time::Duration};
use ashpd::desktop::{
remote_desktop::{DeviceType, KeyState, RemoteDesktop},
PersistMode, Session,
};
use xkbcommon::xkb::{
keysyms::{KEY_Escape, KEY_Return, KEY_Tab},
utf32_to_keysym,
};
async fn press_key(
proxy: &RemoteDesktop<'_>,
session: &Session<'_, RemoteDesktop<'_>>,
ch: char,
) -> ashpd::Result<()> {
let keysym = match ch {
'\n' => KEY_Return,
'\t' => KEY_Tab,
'\x1b' => KEY_Escape,
_ => utf32_to_keysym(ch as u32).into(),
};
proxy
.notify_keyboard_keysym(session, keysym as i32, KeyState::Pressed)
.await?;
proxy
.notify_keyboard_keysym(session, keysym as i32, KeyState::Released)
.await?;
Ok(())
}
async fn run(buffer: Vec<u8>) -> ashpd::Result<()> {
let proxy = RemoteDesktop::new().await?;
let session = proxy.create_session().await?;
proxy
.select_devices(
&session,
DeviceType::Keyboard.into(),
None,
PersistMode::DoNot,
)
.await?;
let response = proxy.start(&session, None).await?.response()?;
println!("{:#?}", response.devices());
println!("Wait 2s for you to focus...");
std::thread::sleep(Duration::new(2, 0));
for i in buffer {
press_key(&proxy, &session, i as char).await?;
}
Ok(())
}
#[tokio::main]
async fn main() {
let argv: Vec<_> = std::env::args().collect();
if argv.len() <= 1 {
println!("Usage: {} [filename]", argv[0]);
exit(1);
}
let filename = &argv[1];
let mut file = File::open(filename).unwrap();
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).unwrap();
run(buffer).await.unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment