|
|
@ -1,6 +1,6 @@
|
|
|
|
use crate::client::x11_client::X11Client;
|
|
|
|
use crate::client::x11_client::X11Client;
|
|
|
|
use crate::config::action::Action;
|
|
|
|
use crate::config::action::Action;
|
|
|
|
use crate::config::key_press::KeyPress;
|
|
|
|
use crate::config::key_press::{KeyPress, Modifier};
|
|
|
|
use crate::config::wm_class::WMClass;
|
|
|
|
use crate::config::wm_class::WMClass;
|
|
|
|
use crate::Config;
|
|
|
|
use crate::Config;
|
|
|
|
use evdev::uinput::VirtualDevice;
|
|
|
|
use evdev::uinput::VirtualDevice;
|
|
|
@ -38,7 +38,7 @@ impl EventHandler {
|
|
|
|
pub fn on_event(&mut self, event: InputEvent, config: &Config) -> Result<(), Box<dyn Error>> {
|
|
|
|
pub fn on_event(&mut self, event: InputEvent, config: &Config) -> Result<(), Box<dyn Error>> {
|
|
|
|
self.wm_class_cache = None; // expire cache
|
|
|
|
self.wm_class_cache = None; // expire cache
|
|
|
|
let mut key = Key::new(event.code());
|
|
|
|
let mut key = Key::new(event.code());
|
|
|
|
println!("=> {}: {:?}", event.value(), &key);
|
|
|
|
// println!("=> {}: {:?}", event.value(), &key);
|
|
|
|
|
|
|
|
|
|
|
|
// Apply modmap
|
|
|
|
// Apply modmap
|
|
|
|
for modmap in &config.modmap {
|
|
|
|
for modmap in &config.modmap {
|
|
|
@ -68,9 +68,7 @@ impl EventHandler {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn send_event(&mut self, event: InputEvent) -> std::io::Result<()> {
|
|
|
|
pub fn send_event(&mut self, event: InputEvent) -> std::io::Result<()> {
|
|
|
|
if event.event_type() == EventType::KEY {
|
|
|
|
// if event.event_type() == EventType::KEY { println!("{}: {:?}", event.value(), Key::new(event.code())) }
|
|
|
|
println!("{}: {:?}", event.value(), Key::new(event.code()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
self.device.emit(&[event])
|
|
|
|
self.device.emit(&[event])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -113,49 +111,29 @@ impl EventHandler {
|
|
|
|
|
|
|
|
|
|
|
|
fn dispatch_action(&mut self, action: &Action) -> Result<(), Box<dyn Error>> {
|
|
|
|
fn dispatch_action(&mut self, action: &Action) -> Result<(), Box<dyn Error>> {
|
|
|
|
match action {
|
|
|
|
match action {
|
|
|
|
Action::KeyPress(press) => {
|
|
|
|
Action::KeyPress(key_press) => {
|
|
|
|
self.send_modifier(
|
|
|
|
let next_shift = self.build_state(Modifier::Shift, key_press.shift);
|
|
|
|
&self.shift.clone(),
|
|
|
|
let next_control = self.build_state(Modifier::Control, key_press.control);
|
|
|
|
&PressState::new(press.shift),
|
|
|
|
let next_alt = self.build_state(Modifier::Alt, key_press.alt);
|
|
|
|
&SHIFT_KEYS,
|
|
|
|
let next_windows = self.build_state(Modifier::Windows, key_press.windows);
|
|
|
|
)?;
|
|
|
|
|
|
|
|
self.send_modifier(
|
|
|
|
let prev_shift = self.send_modifier(Modifier::Shift, &next_shift)?;
|
|
|
|
&self.control.clone(),
|
|
|
|
let prev_control = self.send_modifier(Modifier::Control, &next_control)?;
|
|
|
|
&PressState::new(press.control),
|
|
|
|
let prev_alt = self.send_modifier(Modifier::Alt, &next_alt)?;
|
|
|
|
&CTRL_KEYS,
|
|
|
|
let prev_windows = self.send_modifier(Modifier::Windows, &next_windows)?;
|
|
|
|
)?;
|
|
|
|
|
|
|
|
self.send_modifier(&self.alt.clone(), &PressState::new(press.alt), &ALT_KEYS)?;
|
|
|
|
|
|
|
|
self.send_modifier(
|
|
|
|
|
|
|
|
&self.windows.clone(),
|
|
|
|
|
|
|
|
&PressState::new(press.windows),
|
|
|
|
|
|
|
|
&WIN_KEYS,
|
|
|
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.send_key(&press.key, PRESS)?;
|
|
|
|
self.send_key(&key_press.key, PRESS)?;
|
|
|
|
self.send_key(&press.key, RELEASE)?;
|
|
|
|
self.send_key(&key_press.key, RELEASE)?;
|
|
|
|
|
|
|
|
|
|
|
|
self.send_modifier(
|
|
|
|
self.send_modifier(Modifier::Windows, &prev_windows)?;
|
|
|
|
&PressState::new(press.windows),
|
|
|
|
self.send_modifier(Modifier::Alt, &prev_alt)?;
|
|
|
|
&self.windows.clone(),
|
|
|
|
self.send_modifier(Modifier::Control, &prev_control)?;
|
|
|
|
&WIN_KEYS,
|
|
|
|
self.send_modifier(Modifier::Shift, &prev_shift)?;
|
|
|
|
)?;
|
|
|
|
|
|
|
|
self.send_modifier(&PressState::new(press.alt), &self.alt.clone(), &ALT_KEYS)?;
|
|
|
|
|
|
|
|
self.send_modifier(
|
|
|
|
|
|
|
|
&PressState::new(press.control),
|
|
|
|
|
|
|
|
&self.control.clone(),
|
|
|
|
|
|
|
|
&CTRL_KEYS,
|
|
|
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
self.send_modifier(
|
|
|
|
|
|
|
|
&PressState::new(press.shift),
|
|
|
|
|
|
|
|
&self.shift.clone(),
|
|
|
|
|
|
|
|
&SHIFT_KEYS,
|
|
|
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Action::Remap(remap) => {
|
|
|
|
Action::Remap(remap) => {
|
|
|
|
let mut override_remap: HashMap<KeyPress, Vec<Action>> = HashMap::new();
|
|
|
|
let mut override_remap: HashMap<KeyPress, Vec<Action>> = HashMap::new();
|
|
|
|
for (key_press, actions) in remap.iter() {
|
|
|
|
for (key_press, actions) in remap.iter() {
|
|
|
|
override_remap
|
|
|
|
override_remap.insert(key_press.clone(), actions.iter().map(|a| a.clone()).collect());
|
|
|
|
.insert(key_press.clone(), actions.iter().map(|a| a.clone()).collect());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.override_remap = Some(override_remap)
|
|
|
|
self.override_remap = Some(override_remap)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -163,28 +141,73 @@ impl EventHandler {
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn send_modifier(
|
|
|
|
fn send_modifier(&mut self, modifier: Modifier, desired: &PressState) -> Result<PressState, Box<dyn Error>> {
|
|
|
|
&mut self,
|
|
|
|
let mut current = match modifier {
|
|
|
|
from: &PressState,
|
|
|
|
Modifier::Shift => &self.shift,
|
|
|
|
to: &PressState,
|
|
|
|
Modifier::Control => &self.control,
|
|
|
|
keys: &[Key; 2],
|
|
|
|
Modifier::Alt => &self.alt,
|
|
|
|
) -> Result<(), Box<dyn Error>> {
|
|
|
|
Modifier::Windows => &self.windows,
|
|
|
|
let left_key = &keys[0];
|
|
|
|
|
|
|
|
if !from.left && to.left {
|
|
|
|
|
|
|
|
self.send_key(left_key, PRESS)?;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if from.left && !to.left {
|
|
|
|
.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)?;
|
|
|
|
self.send_key(left_key, RELEASE)?;
|
|
|
|
|
|
|
|
current.left = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let right_key = &keys[1];
|
|
|
|
if !current.right && desired.right {
|
|
|
|
if !from.right && to.right {
|
|
|
|
|
|
|
|
self.send_key(right_key, PRESS)?;
|
|
|
|
self.send_key(right_key, PRESS)?;
|
|
|
|
}
|
|
|
|
current.right = true;
|
|
|
|
if from.right && !to.right {
|
|
|
|
} else if current.right && !desired.right {
|
|
|
|
self.send_key(right_key, RELEASE)?;
|
|
|
|
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)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Choose a PressState closest to the current state
|
|
|
|
|
|
|
|
fn build_state(&self, modifier: Modifier, pressed: bool) -> PressState {
|
|
|
|
|
|
|
|
let press_state = match modifier {
|
|
|
|
|
|
|
|
Modifier::Shift => &self.shift,
|
|
|
|
|
|
|
|
Modifier::Control => &self.control,
|
|
|
|
|
|
|
|
Modifier::Alt => &self.alt,
|
|
|
|
|
|
|
|
Modifier::Windows => &self.windows,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
if (press_state.left || press_state.right) == pressed {
|
|
|
|
|
|
|
|
press_state.clone() // no change is needed
|
|
|
|
|
|
|
|
} else if pressed {
|
|
|
|
|
|
|
|
// just press left
|
|
|
|
|
|
|
|
PressState {
|
|
|
|
|
|
|
|
left: true,
|
|
|
|
|
|
|
|
right: false,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// release all
|
|
|
|
|
|
|
|
PressState::new(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn match_wm_class(&mut self, wm_class_matcher: &WMClass) -> bool {
|
|
|
|
fn match_wm_class(&mut self, wm_class_matcher: &WMClass) -> bool {
|
|
|
@ -274,7 +297,7 @@ lazy_static! {
|
|
|
|
Key::new(Key::KEY_LEFTSHIFT.code()),
|
|
|
|
Key::new(Key::KEY_LEFTSHIFT.code()),
|
|
|
|
Key::new(Key::KEY_RIGHTSHIFT.code()),
|
|
|
|
Key::new(Key::KEY_RIGHTSHIFT.code()),
|
|
|
|
];
|
|
|
|
];
|
|
|
|
static ref CTRL_KEYS: [Key; 2] = [
|
|
|
|
static ref CONTROL_KEYS: [Key; 2] = [
|
|
|
|
Key::new(Key::KEY_LEFTCTRL.code()),
|
|
|
|
Key::new(Key::KEY_LEFTCTRL.code()),
|
|
|
|
Key::new(Key::KEY_RIGHTCTRL.code()),
|
|
|
|
Key::new(Key::KEY_RIGHTCTRL.code()),
|
|
|
|
];
|
|
|
|
];
|
|
|
@ -282,7 +305,7 @@ lazy_static! {
|
|
|
|
Key::new(Key::KEY_LEFTALT.code()),
|
|
|
|
Key::new(Key::KEY_LEFTALT.code()),
|
|
|
|
Key::new(Key::KEY_RIGHTALT.code()),
|
|
|
|
Key::new(Key::KEY_RIGHTALT.code()),
|
|
|
|
];
|
|
|
|
];
|
|
|
|
static ref WIN_KEYS: [Key; 2] = [
|
|
|
|
static ref WINDOWS_KEYS: [Key; 2] = [
|
|
|
|
Key::new(Key::KEY_LEFTMETA.code()),
|
|
|
|
Key::new(Key::KEY_LEFTMETA.code()),
|
|
|
|
Key::new(Key::KEY_RIGHTMETA.code()),
|
|
|
|
Key::new(Key::KEY_RIGHTMETA.code()),
|
|
|
|
];
|
|
|
|
];
|
|
|
|