Implement modmap

pull/39/head
Takashi Kokubun 2 years ago
parent fe696a8956
commit aa3dd2efe3
No known key found for this signature in database
GPG Key ID: 6FFC433B12EE23DD

@ -1,48 +1,4 @@
modmap:
- name: Global
remap:
# CapsLock/Ctrl_L -> Esc
CapsLock: Esc
Ctrl_L: Esc
# HHKB: [Alt_L] [Muhenkan] [Space] [Henkan] [KatakanaHiragana]
Alt_L: Ctrl_R # for Ctrl+Click
Muhenkan: Ctrl_L
Henkan: Shift_L
- name: Kana -> Windows
wm_class:
not: jetbrains-idea
remap:
# Use Windows since Alt is annoying in Electron apps (Slack, Nocturn)
KatakanaHiragana: Win_L
- name: Kana -> Alt
wm_class:
only: jetbrains-idea
remap:
# Use Alt since Windows is annoying in IDEA
KatakanaHiragana: Alt_L
keymap:
- name: Global
remap:
# Underscore without Shift
RO: Shift-RO
# SKK hack for Chrome
C-j: C-m
C-m:
remap:
C-j: a
- name: Default (Nocturn, etc.)
wm_class:
not: [Google-chrome, Slack, Gnome-terminal, jetbrains-idea]
remap:
# Emacs basic
C-b: left
C-f: right
C-p: up
C-n: down
a: b

@ -16,7 +16,9 @@ use std::{error, fs};
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Config {
#[serde(default = "Vec::new")]
pub modmap: Vec<Modmap>,
#[serde(default = "Vec::new")]
pub keymap: Vec<Keymap>,
}

@ -13,8 +13,30 @@ use std::fs::read_dir;
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::AsRawFd;
static SEPARATOR: &str =
"------------------------------------------------------------------------------";
pub fn event_loop(mut input_devices: Vec<Device>, config: &Config) -> Result<(), Box<dyn Error>> {
for device in &mut input_devices {
device
.grab()
.map_err(|e| format!("Failed to grab device '{}': {}", device_name(device), e))?;
}
let mut output_device =
build_device().map_err(|e| format!("Failed to build an output device: {}", e))?;
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 {
on_event(event, &mut output_device, &config)?;
} else {
output_device.emit(&[event])?;
}
}
}
}
}
}
pub fn select_device(device_opts: &Vec<String>) -> Result<Vec<Device>, Box<dyn Error>> {
let mut path_devices = list_devices()?;
@ -57,31 +79,6 @@ pub fn select_device(device_opts: &Vec<String>) -> Result<Vec<Device>, Box<dyn E
return Ok(path_devices.into_values().collect());
}
pub fn event_loop(mut input_devices: Vec<Device>, _config: &Config) -> Result<(), Box<dyn Error>> {
for device in &mut input_devices {
device
.grab()
.map_err(|e| format!("Failed to grab device '{}': {}", device_name(device), e))?;
}
let mut output_device =
build_device().map_err(|e| format!("Failed to build an output device: {}", e))?;
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 {
on_event(event, &mut output_device)?;
} else {
output_device.emit(&[event])?;
}
}
}
}
}
}
fn select_readable(devices: &Vec<Device>) -> Result<FdSet, Box<dyn Error>> {
let mut read_fds = FdSet::new();
for device in devices {
@ -150,3 +147,6 @@ fn is_keyboard(device: &Device) -> bool {
None => false,
}
}
static SEPARATOR: &str =
"------------------------------------------------------------------------------";

@ -1,17 +1,20 @@
use evdev::uinput::VirtualDevice;
use evdev::{EventType, InputEvent, InputEventKind};
use evdev::{EventType, InputEvent, Key};
use std::error::Error;
use crate::Config;
pub fn on_event(event: InputEvent, device: &mut VirtualDevice) -> Result<(), Box<dyn Error>> {
println!("event: {:?}", event);
if event.kind() == InputEventKind::Key(evdev::Key::KEY_A) {
device.emit(&[InputEvent::new(
EventType::KEY,
evdev::Key::KEY_B.code(),
event.value(),
)])?;
} else {
device.emit(&[event])?;
// Handle EventType::KEY
pub fn on_event(event: InputEvent, device: &mut VirtualDevice, config: &Config) -> Result<(), Box<dyn Error>> {
let mut key = &Key::new(event.code());
// Perform modmap
for modmap in &config.modmap {
if let Some(modmap_key) = modmap.remap.get(&key) {
key = modmap_key;
break;
}
}
device.emit(&[InputEvent::new(EventType::KEY, key.code(), event.value())])?;
Ok(())
}

Loading…
Cancel
Save