Fix a bug in extra_modifiers

```
keymap:
  - remap:
      RO: Shift-RO
```

When you press Shift-RO, Shift is considered extra_modifiers (against
source KeyPress) and it was released after Shift-RO. This patch fixes
that case.
This commit is contained in:
Takashi Kokubun 2022-08-15 23:53:17 -07:00
parent e8d30a3e38
commit 9b0c084a5d
No known key found for this signature in database
GPG Key ID: 6FFC433B12EE23DD
2 changed files with 21 additions and 41 deletions

View File

@ -32,9 +32,7 @@ pub enum Action {
// Internals
#[serde(skip)]
PressModifier(Vec<Key>),
#[serde(skip)]
ReleaseModifier(Vec<Key>),
SetExtraModifiers(Vec<Key>),
}
fn deserialize_remap<'de, D>(deserializer: D) -> Result<Remap, D::Error>

View File

@ -24,6 +24,8 @@ pub struct EventHandler {
device: VirtualDevice,
// Currently pressed modifier keys
modifiers: HashSet<Key>,
// Modifiers that are currently pressed but not in the source KeyPress
extra_modifiers: HashSet<Key>,
// Make sure the original event is released even if remapping changes while holding the key
pressed_keys: HashMap<Key, Key>,
// Check the currently active application
@ -52,6 +54,7 @@ impl EventHandler {
EventHandler {
device,
modifiers: HashSet::new(),
extra_modifiers: HashSet::new(),
pressed_keys: HashMap::new(),
application_client: build_client(),
application_cache: None,
@ -88,7 +91,7 @@ impl EventHandler {
if config.virtual_modifiers.contains(&key) {
self.update_modifier(key, value);
continue;
} else if MODIFIER_KEYS.contains(&key.code()) {
} else if MODIFIER_KEYS.contains(&key) {
self.update_modifier(key, value);
} else if is_pressed(value) {
if self.escape_next_key {
@ -312,14 +315,10 @@ impl EventHandler {
Action::SetMark(set) => self.mark_set = *set,
Action::WithMark(key_press) => self.send_key_press(&self.with_mark(key_press))?,
Action::EscapeNextKey(escape_next_key) => self.escape_next_key = *escape_next_key,
Action::PressModifier(keys) => {
Action::SetExtraModifiers(keys) => {
self.extra_modifiers.clear();
for key in keys {
self.modifiers.insert(*key);
}
}
Action::ReleaseModifier(keys) => {
for key in keys {
self.modifiers.remove(key);
self.extra_modifiers.insert(*key);
}
}
}
@ -330,8 +329,8 @@ impl EventHandler {
// Build extra or missing modifiers. Note that only MODIFIER_KEYS are handled
// because logical modifiers shouldn't make an impact outside xremap.
let (mut extra_modifiers, mut missing_modifiers) = self.diff_modifiers(&key_press.modifiers);
extra_modifiers.retain(|key| MODIFIER_KEYS.contains(&key.code()));
missing_modifiers.retain(|key| MODIFIER_KEYS.contains(&key.code()));
extra_modifiers.retain(|key| MODIFIER_KEYS.contains(&key) && !self.extra_modifiers.contains(&key));
missing_modifiers.retain(|key| MODIFIER_KEYS.contains(&key));
// Emulate the modifiers of KeyPress
self.send_keys(&extra_modifiers, RELEASE)?;
@ -460,12 +459,12 @@ fn with_extra_modifiers(actions: &Vec<Action>, extra_modifiers: &Vec<Key>) -> Ve
let mut result: Vec<Action> = vec![];
if extra_modifiers.len() > 0 {
// Virtually release extra modifiers so that they won't be physically released on KeyPress
result.push(Action::ReleaseModifier(extra_modifiers.clone()));
result.push(Action::SetExtraModifiers(extra_modifiers.clone()));
}
result.extend(actions.clone());
if extra_modifiers.len() > 0 {
// Resurrect the modifier status
result.push(Action::PressModifier(extra_modifiers.clone()));
result.push(Action::SetExtraModifiers(vec![]));
}
return result;
}
@ -486,36 +485,19 @@ fn contains_modifier(modifiers: &Vec<Modifier>, key: &Key) -> bool {
}
lazy_static! {
static ref MODIFIER_KEYS: [u16; 8] = [
static ref MODIFIER_KEYS: [Key; 8] = [
// Shift
Key::KEY_LEFTSHIFT.code(),
Key::KEY_RIGHTSHIFT.code(),
Key::KEY_LEFTSHIFT,
Key::KEY_RIGHTSHIFT,
// Control
Key::KEY_LEFTCTRL.code(),
Key::KEY_RIGHTCTRL.code(),
Key::KEY_LEFTCTRL,
Key::KEY_RIGHTCTRL,
// Alt
Key::KEY_LEFTALT.code(),
Key::KEY_RIGHTALT.code(),
Key::KEY_LEFTALT,
Key::KEY_RIGHTALT,
// Windows
Key::KEY_LEFTMETA.code(),
Key::KEY_RIGHTMETA.code(),
];
static ref SHIFT_KEYS: [Key; 2] = [
Key::new(Key::KEY_LEFTSHIFT.code()),
Key::new(Key::KEY_RIGHTSHIFT.code()),
];
static ref CONTROL_KEYS: [Key; 2] = [
Key::new(Key::KEY_LEFTCTRL.code()),
Key::new(Key::KEY_RIGHTCTRL.code()),
];
static ref ALT_KEYS: [Key; 2] = [
Key::new(Key::KEY_LEFTALT.code()),
Key::new(Key::KEY_RIGHTALT.code()),
];
static ref WINDOWS_KEYS: [Key; 2] = [
Key::new(Key::KEY_LEFTMETA.code()),
Key::new(Key::KEY_RIGHTMETA.code()),
Key::KEY_LEFTMETA,
Key::KEY_RIGHTMETA,
];
}