|
|
@ -2,8 +2,8 @@ use crate::client::{build_client, WMClient};
|
|
|
|
use crate::config::action::Action;
|
|
|
|
use crate::config::action::Action;
|
|
|
|
use crate::config::application::Application;
|
|
|
|
use crate::config::application::Application;
|
|
|
|
use crate::config::key_action::{KeyAction, MultiPurposeKey, PressReleaseKey};
|
|
|
|
use crate::config::key_action::{KeyAction, MultiPurposeKey, PressReleaseKey};
|
|
|
|
use crate::config::key_press::{KeyPress, Modifier, ModifierState};
|
|
|
|
use crate::config::key_press::{KeyPress, Modifier};
|
|
|
|
use crate::config::keymap::expand_modifiers;
|
|
|
|
use crate::config::keymap::{build_override_table, OverrideEntry};
|
|
|
|
use crate::config::remap::Remap;
|
|
|
|
use crate::config::remap::Remap;
|
|
|
|
use crate::Config;
|
|
|
|
use crate::Config;
|
|
|
|
use evdev::uinput::VirtualDevice;
|
|
|
|
use evdev::uinput::VirtualDevice;
|
|
|
@ -14,18 +14,16 @@ use nix::sys::signal;
|
|
|
|
use nix::sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet};
|
|
|
|
use nix::sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet};
|
|
|
|
use nix::sys::time::TimeSpec;
|
|
|
|
use nix::sys::time::TimeSpec;
|
|
|
|
use nix::sys::timerfd::{Expiration, TimerFd, TimerSetTimeFlags};
|
|
|
|
use nix::sys::timerfd::{Expiration, TimerFd, TimerSetTimeFlags};
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::collections::{HashMap, HashSet};
|
|
|
|
use std::error::Error;
|
|
|
|
use std::error::Error;
|
|
|
|
use std::process::{Command, Stdio};
|
|
|
|
use std::process::{Command, Stdio};
|
|
|
|
use std::time::Instant;
|
|
|
|
use std::time::Instant;
|
|
|
|
|
|
|
|
|
|
|
|
pub struct EventHandler {
|
|
|
|
pub struct EventHandler {
|
|
|
|
|
|
|
|
// Device to emit events
|
|
|
|
device: VirtualDevice,
|
|
|
|
device: VirtualDevice,
|
|
|
|
// Recognize modifier key combinations
|
|
|
|
// Currently pressed modifier keys
|
|
|
|
shift: PressState,
|
|
|
|
modifiers: HashSet<Key>,
|
|
|
|
control: PressState,
|
|
|
|
|
|
|
|
alt: PressState,
|
|
|
|
|
|
|
|
windows: PressState,
|
|
|
|
|
|
|
|
// Make sure the original event is released even if remapping changes while holding the key
|
|
|
|
// Make sure the original event is released even if remapping changes while holding the key
|
|
|
|
pressed_keys: HashMap<Key, Key>,
|
|
|
|
pressed_keys: HashMap<Key, Key>,
|
|
|
|
// Check the currently active application
|
|
|
|
// Check the currently active application
|
|
|
@ -34,7 +32,7 @@ pub struct EventHandler {
|
|
|
|
// State machine for multi-purpose keys
|
|
|
|
// State machine for multi-purpose keys
|
|
|
|
multi_purpose_keys: HashMap<Key, MultiPurposeKeyState>,
|
|
|
|
multi_purpose_keys: HashMap<Key, MultiPurposeKeyState>,
|
|
|
|
// Current nested remaps
|
|
|
|
// Current nested remaps
|
|
|
|
override_remap: Option<HashMap<KeyPress, Vec<Action>>>,
|
|
|
|
override_remap: Option<HashMap<Key, Vec<OverrideEntry>>>,
|
|
|
|
// Key triggered on a timeout of nested remaps
|
|
|
|
// Key triggered on a timeout of nested remaps
|
|
|
|
override_timeout_key: Option<Key>,
|
|
|
|
override_timeout_key: Option<Key>,
|
|
|
|
// Trigger a timeout of nested remaps through select(2)
|
|
|
|
// Trigger a timeout of nested remaps through select(2)
|
|
|
@ -53,10 +51,7 @@ impl EventHandler {
|
|
|
|
pub fn new(device: VirtualDevice, timer: TimerFd, mode: &str) -> EventHandler {
|
|
|
|
pub fn new(device: VirtualDevice, timer: TimerFd, mode: &str) -> EventHandler {
|
|
|
|
EventHandler {
|
|
|
|
EventHandler {
|
|
|
|
device,
|
|
|
|
device,
|
|
|
|
shift: PressState::new(),
|
|
|
|
modifiers: HashSet::new(),
|
|
|
|
control: PressState::new(),
|
|
|
|
|
|
|
|
alt: PressState::new(),
|
|
|
|
|
|
|
|
windows: PressState::new(),
|
|
|
|
|
|
|
|
pressed_keys: HashMap::new(),
|
|
|
|
pressed_keys: HashMap::new(),
|
|
|
|
application_client: build_client(),
|
|
|
|
application_client: build_client(),
|
|
|
|
application_cache: None,
|
|
|
|
application_cache: None,
|
|
|
@ -91,7 +86,7 @@ impl EventHandler {
|
|
|
|
// Apply keymap
|
|
|
|
// Apply keymap
|
|
|
|
for (key, value) in key_values.into_iter() {
|
|
|
|
for (key, value) in key_values.into_iter() {
|
|
|
|
if MODIFIER_KEYS.contains(&key.code()) {
|
|
|
|
if MODIFIER_KEYS.contains(&key.code()) {
|
|
|
|
self.update_modifier(key.code(), value);
|
|
|
|
self.update_modifier(key, value);
|
|
|
|
} else if is_pressed(value) {
|
|
|
|
} else if is_pressed(value) {
|
|
|
|
if self.escape_next_key {
|
|
|
|
if self.escape_next_key {
|
|
|
|
self.escape_next_key = false
|
|
|
|
self.escape_next_key = false
|
|
|
@ -127,6 +122,13 @@ impl EventHandler {
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn send_keys(&mut self, keys: &Vec<Key>, value: i32) -> std::io::Result<()> {
|
|
|
|
|
|
|
|
for key in keys {
|
|
|
|
|
|
|
|
self.send_key(key, value)?;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn send_key(&mut self, key: &Key, value: i32) -> std::io::Result<()> {
|
|
|
|
fn send_key(&mut self, key: &Key, value: i32) -> std::io::Result<()> {
|
|
|
|
let event = InputEvent::new(EventType::KEY, key.code(), value);
|
|
|
|
let event = InputEvent::new(EventType::KEY, key.code(), value);
|
|
|
|
self.send_event(event)
|
|
|
|
self.send_event(event)
|
|
|
@ -239,34 +241,36 @@ impl EventHandler {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn find_keymap(&mut self, config: &Config, key: &Key) -> Result<Option<Vec<Action>>, Box<dyn Error>> {
|
|
|
|
fn find_keymap(&mut self, config: &Config, key: &Key) -> Result<Option<Vec<Action>>, Box<dyn Error>> {
|
|
|
|
let key_press = KeyPress {
|
|
|
|
|
|
|
|
key: *key,
|
|
|
|
|
|
|
|
shift: self.shift.to_modifier_state(),
|
|
|
|
|
|
|
|
control: self.control.to_modifier_state(),
|
|
|
|
|
|
|
|
alt: self.alt.to_modifier_state(),
|
|
|
|
|
|
|
|
windows: self.windows.to_modifier_state(),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(override_remap) = &self.override_remap {
|
|
|
|
if let Some(override_remap) = &self.override_remap {
|
|
|
|
if let Some(actions) = override_remap.clone().get(&key_press) {
|
|
|
|
if let Some(entries) = override_remap.get(key) {
|
|
|
|
self.remove_override()?;
|
|
|
|
for exact_match in [true, false] {
|
|
|
|
return Ok(Some(actions.to_vec()));
|
|
|
|
for entry in entries {
|
|
|
|
} else {
|
|
|
|
if !self.match_modifiers(&entry.modifiers, exact_match) {
|
|
|
|
self.timeout_override()?;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok(Some(entry.actions.to_vec()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for keymap in &config.keymap {
|
|
|
|
if let Some(entries) = config.keymap_table.get(key) {
|
|
|
|
if let Some(actions) = keymap.remap.get(&key_press) {
|
|
|
|
for exact_match in [true, false] {
|
|
|
|
if let Some(application_matcher) = &keymap.application {
|
|
|
|
for entry in entries {
|
|
|
|
if !self.match_application(application_matcher) {
|
|
|
|
if !self.match_modifiers(&entry.modifiers, exact_match) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if let Some(application_matcher) = &entry.application {
|
|
|
|
if let Some(modes) = &keymap.mode {
|
|
|
|
if !self.match_application(application_matcher) {
|
|
|
|
if !modes.contains(&self.mode) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(modes) = &entry.mode {
|
|
|
|
|
|
|
|
if !modes.contains(&self.mode) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok(Some(entry.actions.clone()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Ok(Some(actions.to_vec()));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(None)
|
|
|
|
Ok(None)
|
|
|
@ -287,13 +291,7 @@ impl EventHandler {
|
|
|
|
timeout,
|
|
|
|
timeout,
|
|
|
|
timeout_key,
|
|
|
|
timeout_key,
|
|
|
|
}) => {
|
|
|
|
}) => {
|
|
|
|
let mut override_remap: HashMap<KeyPress, Vec<Action>> = HashMap::new();
|
|
|
|
self.override_remap = Some(build_override_table(remap));
|
|
|
|
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) = timeout {
|
|
|
|
if let Some(timeout) = timeout {
|
|
|
|
let expiration = Expiration::OneShot(TimeSpec::from_duration(*timeout));
|
|
|
|
let expiration = Expiration::OneShot(TimeSpec::from_duration(*timeout));
|
|
|
|
self.override_timer.unset()?;
|
|
|
|
self.override_timer.unset()?;
|
|
|
@ -314,121 +312,61 @@ impl EventHandler {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn send_key_press(&mut self, key_press: &KeyPress) -> Result<(), Box<dyn Error>> {
|
|
|
|
fn send_key_press(&mut self, key_press: &KeyPress) -> Result<(), Box<dyn Error>> {
|
|
|
|
let next_shift = self.build_state(Modifier::Shift, key_press.shift.clone());
|
|
|
|
// Build missing or extra modifiers
|
|
|
|
let next_control = self.build_state(Modifier::Control, key_press.control.clone());
|
|
|
|
let extra_modifiers: Vec<Key> = self
|
|
|
|
let next_alt = self.build_state(Modifier::Alt, key_press.alt.clone());
|
|
|
|
.modifiers
|
|
|
|
let next_windows = self.build_state(Modifier::Windows, key_press.windows.clone());
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.filter_map(|modifier| {
|
|
|
|
|
|
|
|
if self.contains_modifier(&key_press.modifiers, modifier) {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
Some(modifier.clone())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
let missing_modifiers: Vec<Key> = key_press
|
|
|
|
|
|
|
|
.modifiers
|
|
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.filter_map(|modifier| {
|
|
|
|
|
|
|
|
if self.match_modifier(modifier) {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => Some(Key::KEY_LEFTSHIFT),
|
|
|
|
|
|
|
|
Modifier::Control => Some(Key::KEY_LEFTCTRL),
|
|
|
|
|
|
|
|
Modifier::Alt => Some(Key::KEY_LEFTALT),
|
|
|
|
|
|
|
|
Modifier::Windows => Some(Key::KEY_LEFTMETA),
|
|
|
|
|
|
|
|
Modifier::Key(key) => Some(key.clone()),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
|
|
let prev_shift = self.send_modifier(Modifier::Shift, &next_shift)?;
|
|
|
|
// Emulate the modifiers of KeyPress
|
|
|
|
let prev_control = self.send_modifier(Modifier::Control, &next_control)?;
|
|
|
|
self.send_keys(&extra_modifiers, RELEASE)?;
|
|
|
|
let prev_alt = self.send_modifier(Modifier::Alt, &next_alt)?;
|
|
|
|
self.send_keys(&missing_modifiers, PRESS)?;
|
|
|
|
let prev_windows = self.send_modifier(Modifier::Windows, &next_windows)?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Press the main key
|
|
|
|
self.send_key(&key_press.key, PRESS)?;
|
|
|
|
self.send_key(&key_press.key, PRESS)?;
|
|
|
|
self.send_key(&key_press.key, RELEASE)?;
|
|
|
|
self.send_key(&key_press.key, RELEASE)?;
|
|
|
|
|
|
|
|
|
|
|
|
self.send_modifier(Modifier::Windows, &prev_windows)?;
|
|
|
|
// Resurrect the original modifiers
|
|
|
|
self.send_modifier(Modifier::Alt, &prev_alt)?;
|
|
|
|
self.send_keys(&missing_modifiers, RELEASE)?;
|
|
|
|
self.send_modifier(Modifier::Control, &prev_control)?;
|
|
|
|
self.send_keys(&extra_modifiers, PRESS)?;
|
|
|
|
self.send_modifier(Modifier::Shift, &prev_shift)?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn send_modifier(&mut self, modifier: Modifier, desired: &PressState) -> Result<PressState, Box<dyn Error>> {
|
|
|
|
|
|
|
|
let mut current = match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => &self.shift,
|
|
|
|
|
|
|
|
Modifier::Control => &self.control,
|
|
|
|
|
|
|
|
Modifier::Alt => &self.alt,
|
|
|
|
|
|
|
|
Modifier::Windows => &self.windows,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.clone();
|
|
|
|
|
|
|
|
let original = current.clone();
|
|
|
|
|
|
|
|
let left_key = match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => &SHIFT_KEYS[0],
|
|
|
|
|
|
|
|
Modifier::Control => &CONTROL_KEYS[0],
|
|
|
|
|
|
|
|
Modifier::Alt => &ALT_KEYS[0],
|
|
|
|
|
|
|
|
Modifier::Windows => &WINDOWS_KEYS[0],
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
let right_key = match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => &SHIFT_KEYS[1],
|
|
|
|
|
|
|
|
Modifier::Control => &CONTROL_KEYS[1],
|
|
|
|
|
|
|
|
Modifier::Alt => &ALT_KEYS[1],
|
|
|
|
|
|
|
|
Modifier::Windows => &WINDOWS_KEYS[1],
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !current.left && desired.left {
|
|
|
|
|
|
|
|
self.send_key(left_key, PRESS)?;
|
|
|
|
|
|
|
|
current.left = true;
|
|
|
|
|
|
|
|
} else if current.left && !desired.left {
|
|
|
|
|
|
|
|
self.send_key(left_key, RELEASE)?;
|
|
|
|
|
|
|
|
current.left = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !current.right && desired.right {
|
|
|
|
|
|
|
|
self.send_key(right_key, PRESS)?;
|
|
|
|
|
|
|
|
current.right = true;
|
|
|
|
|
|
|
|
} else if current.right && !desired.right {
|
|
|
|
|
|
|
|
self.send_key(right_key, RELEASE)?;
|
|
|
|
|
|
|
|
current.right = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => self.shift = current,
|
|
|
|
|
|
|
|
Modifier::Control => self.control = current,
|
|
|
|
|
|
|
|
Modifier::Alt => self.alt = current,
|
|
|
|
|
|
|
|
Modifier::Windows => self.windows = current,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(original)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn build_state(&self, modifier: Modifier, modifier_state: ModifierState) -> PressState {
|
|
|
|
Ok(())
|
|
|
|
let press_state = match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => &self.shift,
|
|
|
|
|
|
|
|
Modifier::Control => &self.control,
|
|
|
|
|
|
|
|
Modifier::Alt => &self.alt,
|
|
|
|
|
|
|
|
Modifier::Windows => &self.windows,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match modifier_state {
|
|
|
|
|
|
|
|
ModifierState::Either => {
|
|
|
|
|
|
|
|
// Choose a PressState closest to the current PressState
|
|
|
|
|
|
|
|
if press_state.left || press_state.right {
|
|
|
|
|
|
|
|
press_state.clone() // no change is necessary
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// Just press left
|
|
|
|
|
|
|
|
PressState {
|
|
|
|
|
|
|
|
left: true,
|
|
|
|
|
|
|
|
right: false,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ModifierState::Left => PressState {
|
|
|
|
|
|
|
|
left: true,
|
|
|
|
|
|
|
|
right: false,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
ModifierState::Right => PressState {
|
|
|
|
|
|
|
|
left: false,
|
|
|
|
|
|
|
|
right: true,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
ModifierState::None => PressState {
|
|
|
|
|
|
|
|
left: false,
|
|
|
|
|
|
|
|
right: false,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn with_mark(&self, key_press: &KeyPress) -> KeyPress {
|
|
|
|
fn with_mark(&self, key_press: &KeyPress) -> KeyPress {
|
|
|
|
let mut shift = key_press.shift.clone();
|
|
|
|
if self.mark_set && !self.match_modifier(&Modifier::Shift) {
|
|
|
|
if self.mark_set && shift == ModifierState::None {
|
|
|
|
let mut modifiers = key_press.modifiers.clone();
|
|
|
|
// We don't leave Either in expand_modifiers(), so just using Left here.
|
|
|
|
modifiers.push(Modifier::Shift);
|
|
|
|
shift = ModifierState::Left;
|
|
|
|
KeyPress {
|
|
|
|
}
|
|
|
|
key: key_press.key,
|
|
|
|
KeyPress {
|
|
|
|
modifiers,
|
|
|
|
key: key_press.key,
|
|
|
|
}
|
|
|
|
shift,
|
|
|
|
} else {
|
|
|
|
control: key_press.control.clone(),
|
|
|
|
key_press.clone()
|
|
|
|
alt: key_press.alt.clone(),
|
|
|
|
|
|
|
|
windows: key_press.windows.clone(),
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -455,6 +393,49 @@ impl EventHandler {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn contains_modifier(&self, modifiers: &Vec<Modifier>, key: &Key) -> bool {
|
|
|
|
|
|
|
|
for modifier in modifiers {
|
|
|
|
|
|
|
|
if match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => key == &Key::KEY_LEFTSHIFT || key == &Key::KEY_RIGHTSHIFT,
|
|
|
|
|
|
|
|
Modifier::Control => key == &Key::KEY_LEFTCTRL || key == &Key::KEY_RIGHTCTRL,
|
|
|
|
|
|
|
|
Modifier::Alt => key == &Key::KEY_LEFTALT || key == &Key::KEY_RIGHTALT,
|
|
|
|
|
|
|
|
Modifier::Windows => key == &Key::KEY_LEFTMETA || key == &Key::KEY_RIGHTMETA,
|
|
|
|
|
|
|
|
Modifier::Key(modifier_key) => key == modifier_key,
|
|
|
|
|
|
|
|
} {
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn match_modifiers(&self, modifiers: &Vec<Modifier>, exact_match: bool) -> bool {
|
|
|
|
|
|
|
|
if exact_match && self.modifiers.len() > modifiers.len() {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for modifier in modifiers {
|
|
|
|
|
|
|
|
if !self.match_modifier(modifier) {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn match_modifier(&self, modifier: &Modifier) -> bool {
|
|
|
|
|
|
|
|
match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => {
|
|
|
|
|
|
|
|
self.modifiers.contains(&Key::KEY_LEFTSHIFT) || self.modifiers.contains(&Key::KEY_RIGHTSHIFT)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Modifier::Control => {
|
|
|
|
|
|
|
|
self.modifiers.contains(&Key::KEY_LEFTCTRL) || self.modifiers.contains(&Key::KEY_RIGHTCTRL)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Modifier::Alt => self.modifiers.contains(&Key::KEY_LEFTALT) || self.modifiers.contains(&Key::KEY_RIGHTALT),
|
|
|
|
|
|
|
|
Modifier::Windows => {
|
|
|
|
|
|
|
|
self.modifiers.contains(&Key::KEY_LEFTMETA) || self.modifiers.contains(&Key::KEY_RIGHTMETA)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Modifier::Key(key) => self.modifiers.contains(key),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn match_application(&mut self, application_matcher: &Application) -> bool {
|
|
|
|
fn match_application(&mut self, application_matcher: &Application) -> bool {
|
|
|
|
// Lazily fill the wm_class cache
|
|
|
|
// Lazily fill the wm_class cache
|
|
|
|
if self.application_cache.is_none() {
|
|
|
|
if self.application_cache.is_none() {
|
|
|
@ -475,25 +456,11 @@ impl EventHandler {
|
|
|
|
false
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn update_modifier(&mut self, code: u16, value: i32) {
|
|
|
|
fn update_modifier(&mut self, key: Key, value: i32) {
|
|
|
|
if code == Key::KEY_LEFTSHIFT.code() {
|
|
|
|
if value == PRESS {
|
|
|
|
self.shift.left = is_pressed(value)
|
|
|
|
self.modifiers.insert(key);
|
|
|
|
} else if code == Key::KEY_RIGHTSHIFT.code() {
|
|
|
|
} else if value == RELEASE {
|
|
|
|
self.shift.right = is_pressed(value)
|
|
|
|
self.modifiers.remove(&key);
|
|
|
|
} else if code == Key::KEY_LEFTCTRL.code() {
|
|
|
|
|
|
|
|
self.control.left = is_pressed(value)
|
|
|
|
|
|
|
|
} else if code == Key::KEY_RIGHTCTRL.code() {
|
|
|
|
|
|
|
|
self.control.right = is_pressed(value)
|
|
|
|
|
|
|
|
} else if code == Key::KEY_LEFTALT.code() {
|
|
|
|
|
|
|
|
self.alt.left = is_pressed(value)
|
|
|
|
|
|
|
|
} else if code == Key::KEY_RIGHTALT.code() {
|
|
|
|
|
|
|
|
self.alt.right = is_pressed(value)
|
|
|
|
|
|
|
|
} else if code == Key::KEY_LEFTMETA.code() {
|
|
|
|
|
|
|
|
self.windows.left = is_pressed(value)
|
|
|
|
|
|
|
|
} else if code == Key::KEY_RIGHTMETA.code() {
|
|
|
|
|
|
|
|
self.windows.right = is_pressed(value)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
panic!("unexpected key {:?} at update_modifier", Key::new(code));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -534,31 +501,6 @@ lazy_static! {
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
//---
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
|
|
|
struct PressState {
|
|
|
|
|
|
|
|
left: bool,
|
|
|
|
|
|
|
|
right: bool,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl PressState {
|
|
|
|
|
|
|
|
fn new() -> PressState {
|
|
|
|
|
|
|
|
PressState {
|
|
|
|
|
|
|
|
left: false,
|
|
|
|
|
|
|
|
right: false,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn to_modifier_state(&self) -> ModifierState {
|
|
|
|
|
|
|
|
if self.left {
|
|
|
|
|
|
|
|
ModifierState::Left
|
|
|
|
|
|
|
|
} else if self.right {
|
|
|
|
|
|
|
|
ModifierState::Right
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ModifierState::None
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn is_pressed(value: i32) -> bool {
|
|
|
|
fn is_pressed(value: i32) -> bool {
|
|
|
|
value == PRESS || value == REPEAT
|
|
|
|
value == PRESS || value == REPEAT
|
|
|
|
}
|
|
|
|
}
|
|
|
|