mirror of
https://github.com/k0kubun/xremap
synced 2024-11-02 03:40:25 +00:00
Implement keymap
This commit is contained in:
parent
f5695d3bc2
commit
c57dbee606
@ -1,8 +1,8 @@
|
||||
modmap:
|
||||
- name: Global
|
||||
remap:
|
||||
a: b
|
||||
# modmap:
|
||||
# - name: Global
|
||||
# remap:
|
||||
# a: b
|
||||
keymap:
|
||||
- name: Global
|
||||
remap:
|
||||
C-i: C-h
|
||||
C-i: C-u
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::config::keypress::{parse_keypress, KeyPress};
|
||||
use crate::config::key_press::{parse_key_press, KeyPress};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::config::actions::Actions;
|
||||
@ -31,8 +31,8 @@ impl<'de> Deserialize<'de> for Action {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
let keypress = parse_keypress(value).map_err(de::Error::custom)?;
|
||||
Ok(Action::KeyPress(keypress))
|
||||
let key_press = parse_key_press(value).map_err(de::Error::custom)?;
|
||||
Ok(Action::KeyPress(key_press))
|
||||
}
|
||||
|
||||
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
|
||||
@ -44,12 +44,12 @@ impl<'de> Deserialize<'de> for Action {
|
||||
Some("remap") => {
|
||||
let mut action: HashMap<KeyPress, Vec<Action>> = HashMap::new();
|
||||
let remap = map.next_value::<HashMap<KeyPress, Actions>>()?;
|
||||
for (keypress, actions) in remap.into_iter() {
|
||||
for (key_press, actions) in remap.into_iter() {
|
||||
let actions = match actions {
|
||||
Actions::Action(action) => vec![action],
|
||||
Actions::Actions(actions) => actions,
|
||||
};
|
||||
action.insert(keypress, actions);
|
||||
action.insert(key_press, actions);
|
||||
}
|
||||
Action::Remap(action)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::config::action::Action;
|
||||
use crate::config::keypress::parse_keypress;
|
||||
use crate::config::key_press::parse_key_press;
|
||||
use serde::de;
|
||||
use serde::de::{value, MapAccess, SeqAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
@ -29,8 +29,8 @@ impl<'de> Deserialize<'de> for Actions {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
let keypress = parse_keypress(value).map_err(de::Error::custom)?;
|
||||
Ok(Actions::Action(Action::KeyPress(keypress)))
|
||||
let key_press = parse_key_press(value).map_err(de::Error::custom)?;
|
||||
Ok(Actions::Action(Action::KeyPress(key_press)))
|
||||
}
|
||||
|
||||
fn visit_seq<S>(self, seq: S) -> Result<Self::Value, S::Error>
|
||||
|
@ -40,7 +40,7 @@ impl<'de> Deserialize<'de> for KeyPress {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
parse_keypress(value).map_err(de::Error::custom)
|
||||
parse_key_press(value).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ impl<'de> Deserialize<'de> for KeyPress {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_keypress(input: &str) -> Result<KeyPress, Box<dyn error::Error>> {
|
||||
pub fn parse_key_press(input: &str) -> Result<KeyPress, Box<dyn error::Error>> {
|
||||
let keys: Vec<&str> = input.split("-").collect();
|
||||
if let Some((key, modifiers)) = keys.split_last() {
|
||||
let mut shift = false;
|
||||
@ -75,7 +75,7 @@ pub fn parse_keypress(input: &str) -> Result<KeyPress, Box<dyn error::Error>> {
|
||||
windows,
|
||||
})
|
||||
} else {
|
||||
Err(format!("empty keypress: {}", input).into())
|
||||
Err(format!("empty key_press: {}", input).into())
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::config::action::Action;
|
||||
use crate::config::actions::Actions;
|
||||
use crate::config::keypress::KeyPress;
|
||||
use crate::config::key_press::KeyPress;
|
||||
use crate::config::wm_class::WMClass;
|
||||
use serde::de::{MapAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
@ -36,12 +36,12 @@ where
|
||||
{
|
||||
let mut keymap = HashMap::new();
|
||||
|
||||
while let Some(keypress) = map.next_key::<KeyPress>()? {
|
||||
while let Some(key_press) = map.next_key::<KeyPress>()? {
|
||||
let actions = match map.next_value::<Actions>()? {
|
||||
Actions::Action(action) => vec![action],
|
||||
Actions::Actions(actions) => actions,
|
||||
};
|
||||
keymap.insert(keypress, actions);
|
||||
keymap.insert(key_press, actions);
|
||||
}
|
||||
|
||||
Ok(keymap)
|
||||
|
@ -1,8 +1,8 @@
|
||||
mod action;
|
||||
pub mod action;
|
||||
mod actions;
|
||||
mod key;
|
||||
pub mod key_press;
|
||||
mod keymap;
|
||||
pub mod keypress;
|
||||
mod modmap;
|
||||
mod wm_class;
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
use crate::config::action::Action;
|
||||
use crate::config::key_press::{KeyPress, Modifier};
|
||||
use crate::Config;
|
||||
use evdev::uinput::VirtualDevice;
|
||||
use evdev::{EventType, InputEvent, Key};
|
||||
use std::error::Error;
|
||||
use lazy_static::lazy_static;
|
||||
use crate::Config;
|
||||
use crate::config::keypress::Modifier;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
|
||||
pub struct EventHandler {
|
||||
pub config: Config,
|
||||
pub device: VirtualDevice,
|
||||
device: VirtualDevice,
|
||||
shift: bool,
|
||||
control: bool,
|
||||
alt: bool,
|
||||
@ -16,9 +16,8 @@ pub struct EventHandler {
|
||||
}
|
||||
|
||||
impl EventHandler {
|
||||
pub fn new(config: Config, device: VirtualDevice) -> EventHandler {
|
||||
pub fn new(device: VirtualDevice) -> EventHandler {
|
||||
EventHandler {
|
||||
config,
|
||||
device,
|
||||
shift: false,
|
||||
control: false,
|
||||
@ -28,28 +27,95 @@ impl EventHandler {
|
||||
}
|
||||
|
||||
// Handle EventType::KEY
|
||||
pub fn on_event(&mut self, event: InputEvent) -> Result<(), Box<dyn Error>> {
|
||||
pub fn on_event(&mut self, event: InputEvent, config: &Config) -> Result<(), Box<dyn Error>> {
|
||||
let mut key = Key::new(event.code());
|
||||
// println!("=> {}: {:?}", event.value(), &key);
|
||||
|
||||
// Perform modmap
|
||||
for modmap in &self.config.modmap {
|
||||
// Apply modmap
|
||||
for modmap in &config.modmap {
|
||||
if let Some(modmap_key) = modmap.remap.get(&key) {
|
||||
key = modmap_key.clone();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform keymap
|
||||
// Apply keymap
|
||||
if let Some(modifier) = MODIFIER_KEYS.get(&key.code()) {
|
||||
self.update_modifier(modifier, event.value());
|
||||
} else if let Some(actions) = self.find_keymap(config, &key, event.value()) {
|
||||
for action in actions {
|
||||
self.dispatch_action(action)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.device.emit(&[InputEvent::new(EventType::KEY, key.code(), event.value())])?;
|
||||
self.send_key(&key, event.value())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn send_event(&mut self, event: InputEvent) -> Result<(), Box<dyn Error>> {
|
||||
self.device.emit(&[event])?;
|
||||
pub fn send_event(&mut self, event: InputEvent) -> std::io::Result<()> {
|
||||
// if event.event_type() == EventType::KEY { println!("{}: {:?}", event.value(), Key::new(event.code())); }
|
||||
self.device.emit(&[event])
|
||||
}
|
||||
|
||||
fn send_key(&mut self, key: &Key, value: i32) -> std::io::Result<()> {
|
||||
let event = InputEvent::new(EventType::KEY, key.code(), value);
|
||||
self.send_event(event)
|
||||
}
|
||||
|
||||
fn find_keymap<'a>(
|
||||
&self,
|
||||
config: &'a Config,
|
||||
key: &Key,
|
||||
value: i32,
|
||||
) -> Option<&'a Vec<Action>> {
|
||||
if !is_pressed(value) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let key_press = KeyPress {
|
||||
key: key.clone(),
|
||||
shift: self.shift,
|
||||
control: self.control,
|
||||
alt: self.alt,
|
||||
windows: self.windows,
|
||||
};
|
||||
for keymap in &config.keymap {
|
||||
if let Some(actions) = keymap.remap.get(&key_press) {
|
||||
return Some(actions);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn dispatch_action(&mut self, action: &Action) -> Result<(), Box<dyn Error>> {
|
||||
match action {
|
||||
Action::KeyPress(key_press) => {
|
||||
self.send_modifier(self.shift, key_press.shift, &SHIFT_KEY)?;
|
||||
self.send_modifier(self.control, key_press.control, &CONTROL_KEY)?;
|
||||
self.send_modifier(self.alt, key_press.alt, &ALT_KEY)?;
|
||||
self.send_modifier(self.windows, key_press.windows, &WINDOWS_KEY)?;
|
||||
|
||||
self.send_key(&key_press.key, PRESS)?;
|
||||
self.send_key(&key_press.key, RELEASE)?;
|
||||
|
||||
self.send_modifier(key_press.windows, self.windows, &WINDOWS_KEY)?;
|
||||
self.send_modifier(key_press.alt, self.alt, &ALT_KEY)?;
|
||||
self.send_modifier(key_press.control, self.control, &CONTROL_KEY)?;
|
||||
self.send_modifier(key_press.shift, self.shift, &SHIFT_KEY)?;
|
||||
}
|
||||
Action::Remap(_remap) => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_modifier(&mut self, from: bool, to: bool, key: &Key) -> Result<(), Box<dyn Error>> {
|
||||
if !from && to {
|
||||
self.send_key(key, PRESS)?;
|
||||
}
|
||||
if from && !to {
|
||||
self.send_key(key, RELEASE)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -68,7 +134,7 @@ fn is_pressed(value: i32) -> bool {
|
||||
}
|
||||
|
||||
// InputEvent#value
|
||||
// static RELEASE: i32 = 0;
|
||||
static RELEASE: i32 = 0;
|
||||
static PRESS: i32 = 1;
|
||||
static REPEAT: i32 = 2;
|
||||
|
||||
@ -87,4 +153,9 @@ lazy_static! {
|
||||
(Key::KEY_LEFTMETA.code(), Modifier::Windows),
|
||||
(Key::KEY_RIGHTMETA.code(), Modifier::Windows),
|
||||
].into_iter().collect();
|
||||
|
||||
static ref SHIFT_KEY: Key = Key::new(Key::KEY_LEFTSHIFT.code());
|
||||
static ref CONTROL_KEY: Key = Key::new(Key::KEY_LEFTCTRL.code());
|
||||
static ref ALT_KEY: Key = Key::new(Key::KEY_LEFTALT.code());
|
||||
static ref WINDOWS_KEY: Key = Key::new(Key::KEY_LEFTMETA.code());
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
extern crate evdev;
|
||||
extern crate nix;
|
||||
|
||||
use crate::event_handler::EventHandler;
|
||||
use crate::output::build_device;
|
||||
use crate::event_handler::{EventHandler};
|
||||
use crate::Config;
|
||||
use evdev::{Device, EventType, Key};
|
||||
use nix::sys::select::select;
|
||||
@ -13,7 +13,7 @@ use std::fs::read_dir;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
pub fn event_loop(mut input_devices: Vec<Device>, config: Config) -> Result<(), Box<dyn Error>> {
|
||||
pub fn event_loop(mut input_devices: Vec<Device>, config: &Config) -> Result<(), Box<dyn Error>> {
|
||||
for device in &mut input_devices {
|
||||
device
|
||||
.grab()
|
||||
@ -22,14 +22,14 @@ pub fn event_loop(mut input_devices: Vec<Device>, config: Config) -> Result<(),
|
||||
let output_device =
|
||||
build_device().map_err(|e| format!("Failed to build an output device: {}", e))?;
|
||||
|
||||
let mut handler = EventHandler::new(config, output_device);
|
||||
let mut handler = EventHandler::new(output_device);
|
||||
loop {
|
||||
let readable_fds = select_readable(&input_devices)?;
|
||||
for input_device in &mut input_devices {
|
||||
if readable_fds.contains(input_device.as_raw_fd()) {
|
||||
for event in input_device.fetch_events()? {
|
||||
if event.event_type() == EventType::KEY {
|
||||
handler.on_event(event)?;
|
||||
handler.on_event(event, config)?;
|
||||
} else {
|
||||
handler.send_event(event)?;
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ use std::process::exit;
|
||||
extern crate getopts;
|
||||
|
||||
mod config;
|
||||
mod event_handler;
|
||||
mod input;
|
||||
mod output;
|
||||
mod event_handler;
|
||||
|
||||
fn usage(program: &str, opts: Options) -> String {
|
||||
let brief = format!("Usage: {} CONFIG [options]", program);
|
||||
@ -53,7 +53,7 @@ fn main() {
|
||||
Err(e) => abort(&format!("Failed to select devices: {}", e)),
|
||||
};
|
||||
|
||||
if let Err(e) = event_loop(input_devices, config) {
|
||||
if let Err(e) = event_loop(input_devices, &config) {
|
||||
abort(&format!("Error: {}", e));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user