From c421866df866b26e935d5a8d52f45ed5d40b24ff Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Mon, 10 Oct 2022 21:23:19 -0700 Subject: [PATCH] Add keypress_delay_ms to workaround #179 --- README.md | 6 ++++++ src/config/mod.rs | 2 ++ src/event_handler.rs | 8 ++++++-- src/main.rs | 4 +++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fc4b7302..8caacf5b 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,12 @@ keymap: CapsLock-l: Right ``` +### keypress_delay_ms + +Some applications have trouble understanding synthesized key events, especially on +Wayland. `keypress_delay_ms` can be used to workaround the issue. +See [#179](https://github.com/k0kubun/xremap/issues/179) for the detail. + ## License `xremap` is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). diff --git a/src/config/mod.rs b/src/config/mod.rs index e5e15664..667f37d4 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -36,6 +36,8 @@ pub struct Config { pub default_mode: String, #[serde(deserialize_with = "deserialize_virtual_modifiers", default = "Vec::new")] pub virtual_modifiers: Vec, + #[serde(default)] + pub keypress_delay_ms: u64, // Internals #[serde(skip)] diff --git a/src/event_handler.rs b/src/event_handler.rs index f1d22678..f76c5501 100644 --- a/src/event_handler.rs +++ b/src/event_handler.rs @@ -17,7 +17,8 @@ use nix::sys::timerfd::{Expiration, TimerFd, TimerSetTimeFlags}; use std::collections::{HashMap, HashSet}; use std::error::Error; use std::process::{Command, Stdio}; -use std::time::Instant; +use std::thread; +use std::time::{Duration, Instant}; pub struct EventHandler { // Device to emit events @@ -47,10 +48,11 @@ pub struct EventHandler { mark_set: bool, // { escape_next_key: true } escape_next_key: bool, + keypress_delay: Duration, } impl EventHandler { - pub fn new(device: VirtualDevice, timer: TimerFd, mode: &str) -> EventHandler { + pub fn new(device: VirtualDevice, timer: TimerFd, mode: &str, keypress_delay: Duration) -> EventHandler { EventHandler { device, modifiers: HashSet::new(), @@ -66,6 +68,7 @@ impl EventHandler { mode: mode.to_string(), mark_set: false, escape_next_key: false, + keypress_delay, } } @@ -343,6 +346,7 @@ impl EventHandler { // Press the main key self.send_key(&key_press.key, PRESS)?; + thread::sleep(self.keypress_delay); self.send_key(&key_press.key, RELEASE)?; // Resurrect the original modifiers diff --git a/src/main.rs b/src/main.rs index cf9d4576..897df59c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ use std::collections::HashMap; use std::io::stdout; use std::os::unix::io::{AsRawFd, RawFd}; use std::path::{Path, PathBuf}; +use std::time::Duration; mod client; mod config; @@ -110,7 +111,8 @@ fn main() -> anyhow::Result<()> { }; let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty())?; let timer_fd = timer.as_raw_fd(); - let mut handler = EventHandler::new(output_device, timer, &config.default_mode); + let delay = Duration::from_millis(config.keypress_delay_ms); + let mut handler = EventHandler::new(output_device, timer, &config.default_mode, delay); let mut input_devices = match get_input_devices(&device_filter, &ignore_filter, mouse, watch_devices) { Ok(input_devices) => input_devices, Err(e) => bail!("Failed to prepare input devices: {}", e),