Support logical modifiers

This commit is contained in:
Takashi Kokubun 2022-08-14 02:35:38 -07:00
parent 6c69b04daf
commit feb6bfe693
No known key found for this signature in database
GPG Key ID: 6FFC433B12EE23DD
3 changed files with 25 additions and 2 deletions

View File

@ -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.

View File

@ -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")]

View File

@ -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<Vec<(Key, i32)>, Box<dyn Error>> {
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,