diff --git a/src/config/action.rs b/src/config/action.rs index 9392a5a..cf8044c 100644 --- a/src/config/action.rs +++ b/src/config/action.rs @@ -7,6 +7,9 @@ use serde::{Deserialize, Deserializer}; use std::fmt::Debug; use std::time::Duration; +use super::key::parse_key; +use super::remap::RemapActions; + // Values in `keymap.remap` #[derive(Clone, Debug, Deserialize)] #[serde(untagged)] @@ -34,6 +37,14 @@ where Ok(Remap { remap: action.remap.into_iter().map(|(k, v)| (k, v.into_vec())).collect(), timeout: action.timeout_millis.map(Duration::from_millis), + timeout_key: if let Some(key) = action.timeout_key { + match parse_key(&key) { + Ok(key) => Some(key), + Err(e) => return Err(de::Error::custom(e.to_string())), + } + } else { + None + }, }) } @@ -118,10 +129,3 @@ impl Actions { } } } - -// Used only for deserializing Remap with Vec -#[derive(Debug, Deserialize)] -pub struct RemapActions { - pub remap: HashMap, - pub timeout_millis: Option, -} diff --git a/src/config/mod.rs b/src/config/mod.rs index 9c18530..fa917ba 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -6,7 +6,7 @@ pub mod key_press; pub mod keymap; mod modmap; -mod remap; +pub mod remap; #[cfg(test)] mod tests; diff --git a/src/config/remap.rs b/src/config/remap.rs index 7ddc9d8..75e9147 100644 --- a/src/config/remap.rs +++ b/src/config/remap.rs @@ -1,10 +1,24 @@ +use evdev::Key; +use serde::Deserialize; + use crate::config::action::Action; use crate::config::key_press::KeyPress; use std::collections::HashMap; use std::time::Duration; +use super::action::Actions; + #[derive(Clone, Debug)] pub struct Remap { pub remap: HashMap>, pub timeout: Option, + pub timeout_key: Option, +} + +// USed only for deserialization +#[derive(Debug, Deserialize)] +pub struct RemapActions { + pub remap: HashMap, + pub timeout_millis: Option, + pub timeout_key: Option, } diff --git a/src/config/tests.rs b/src/config/tests.rs index 4ff64f5..d79d561 100644 --- a/src/config/tests.rs +++ b/src/config/tests.rs @@ -139,6 +139,7 @@ fn test_keymap_remap() { C-s: remap: x: C-z + timeout_key: Down timeout_millis: 1000 "}) } diff --git a/src/event_handler.rs b/src/event_handler.rs index ece806a..8b06dec 100644 --- a/src/event_handler.rs +++ b/src/event_handler.rs @@ -4,6 +4,7 @@ use crate::config::application::Application; use crate::config::key_action::{KeyAction, MultiPurposeKey, PressReleaseKey}; use crate::config::key_press::{KeyPress, Modifier, ModifierState}; use crate::config::keymap::expand_modifiers; +use crate::config::remap::Remap; use crate::Config; use evdev::uinput::VirtualDevice; use evdev::{EventType, InputEvent, Key}; @@ -281,19 +282,23 @@ impl EventHandler { fn dispatch_action(&mut self, action: &Action, key: &Key) -> Result<(), Box> { match action { Action::KeyPress(key_press) => self.send_key_press(key_press)?, - Action::Remap(action) => { + Action::Remap(Remap { + remap, + timeout, + timeout_key, + }) => { let mut override_remap: HashMap> = HashMap::new(); - for (key_press, actions) in action.remap.iter() { + for (key_press, actions) in remap.iter() { for key_press in expand_modifiers(key_press.clone()) { override_remap.insert(key_press, actions.to_vec()); } } self.override_remap = Some(override_remap); - if let Some(timeout) = action.timeout { - let expiration = Expiration::OneShot(TimeSpec::from_duration(timeout)); + if let Some(timeout) = timeout { + let expiration = Expiration::OneShot(TimeSpec::from_duration(*timeout)); self.override_timer.unset()?; self.override_timer.set(expiration, TimerSetTimeFlags::empty())?; - self.override_timeout_key = Some(*key); + self.override_timeout_key = timeout_key.or_else(|| Some(*key)); } } Action::Launch(command) => self.run_command(command.clone()),