From feb6bfe69312516f9b99ae7a880bcebf9671cd1f Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Sun, 14 Aug 2022 02:35:38 -0700 Subject: [PATCH] Support logical modifiers --- README.md | 7 +++++++ src/config/key_action.rs | 7 ++++++- src/event_handler.rs | 13 ++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 63d0692..afbce15 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,12 @@ is supported only in `modmap` since `keymap` handles modifier keys differently. modmap: - name: Name # Optional remap: # Required + # Replace a key with another KEY_XXX: KEY_YYY # Required + # Make it a logical modifier key + KEY_XXX: + modifier: true # Required + # Dispatch different keys depending on whether you hold it or press it alone KEY_XXX: held: KEY_YYY # Required alone: KEY_ZZZ # Required @@ -226,6 +231,8 @@ You can use multiple prefixes like `C-M-Shift-a`. You may also suffix them with `_L` or `_R` (case-insensitive) so that remapping is triggered only on a left or right modifier, e.g. `Ctrl_L-a`. +If you set `modifier: true` in `modmap`, you can use it in the `MOD1-` part too. + ### application `application` can be used for both `modmap` and `keymap`, which allows you to specify application-specific remapping. diff --git a/src/config/key_action.rs b/src/config/key_action.rs index 9adfd96..3001c65 100644 --- a/src/config/key_action.rs +++ b/src/config/key_action.rs @@ -12,10 +12,16 @@ use super::action::{Action, Actions}; pub enum KeyAction { #[serde(deserialize_with = "deserialize_key")] Key(Key), + ModifierKey(ModifierKey), MultiPurposeKey(MultiPurposeKey), PressReleaseKey(PressReleaseKey), } +#[derive(Clone, Debug, Deserialize)] +pub struct ModifierKey { + pub modifier: bool, +} + #[serde_as] #[derive(Clone, Debug, Deserialize)] pub struct MultiPurposeKey { @@ -28,7 +34,6 @@ pub struct MultiPurposeKey { pub alone_timeout: Duration, } -#[serde_as] #[derive(Clone, Debug, Deserialize)] pub struct PressReleaseKey { #[serde(deserialize_with = "deserialize_actions")] diff --git a/src/event_handler.rs b/src/event_handler.rs index 8ac10f8..91fd452 100644 --- a/src/event_handler.rs +++ b/src/event_handler.rs @@ -1,7 +1,7 @@ use crate::client::{build_client, WMClient}; use crate::config::action::Action; use crate::config::application::Application; -use crate::config::key_action::{KeyAction, MultiPurposeKey, PressReleaseKey}; +use crate::config::key_action::{KeyAction, ModifierKey, MultiPurposeKey, PressReleaseKey}; use crate::config::key_press::{KeyPress, Modifier}; use crate::config::keymap::{build_override_table, OverrideEntry}; use crate::config::remap::Remap; @@ -162,6 +162,17 @@ impl EventHandler { ) -> Result, Box> { let keys = match key_action { KeyAction::Key(modmap_key) => vec![(modmap_key, value)], + KeyAction::ModifierKey(ModifierKey { modifier }) => { + if modifier { + if value == PRESS { + self.modifiers.insert(key); + } else if value == RELEASE { + self.modifiers.remove(&key); + } + } + // Process this key only in xremap + vec![] + } KeyAction::MultiPurposeKey(MultiPurposeKey { held, alone,