From d8af7c41929966a6811cd41c1417f918ac0a8e81 Mon Sep 17 00:00:00 2001 From: ByteBaker <42913098+ByteBaker@users.noreply.github.com> Date: Tue, 3 Sep 2024 10:56:52 +0530 Subject: [PATCH] feat: add some more keyboard mappings (#173) * feat: add some more mappings as in #69 also add macros to generate code in `keyboard.rs` to conveniently generate mappings * fix: macros in keyboard.rs - support custom match cases in key-mapping macros for when one-one mappings of keys aren't available - add docs to the macros --- Cargo.lock | 92 ++++++++++++--- Cargo.toml | 2 +- src/keyboard.rs | 292 ++++++++++++++++++++---------------------------- 3 files changed, 203 insertions(+), 183 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a4dcbc94..17051249 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,6 +139,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "app_units" version = "0.7.6" @@ -755,6 +804,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + [[package]] name = "colored" version = "2.1.0" @@ -1400,17 +1455,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" -version = "0.10.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ + "anstream", + "anstyle", + "env_filter", "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -2820,15 +2885,10 @@ dependencies = [ ] [[package]] -name = "is-terminal" -version = "0.4.13" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -6150,6 +6210,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.10.0" diff --git a/Cargo.toml b/Cargo.toml index db6db4d7..282346bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ cfg_aliases = "0.2" [dependencies] arboard = "3.4.0" crossbeam-channel = "0.5" -env_logger = "0.10" +env_logger = "0.11" euclid = "0.22" getopts = "0.2.17" gleam = "0.15" diff --git a/src/keyboard.rs b/src/keyboard.rs index 96f7b259..f3036c29 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -17,106 +17,107 @@ pub const CMD_OR_ALT: Modifiers = Modifiers::META; #[cfg(not(macos))] pub const CMD_OR_ALT: Modifiers = Modifiers::ALT; +/// Maps [`LogicalKey`] to [`Key`]. +/// +/// Example: +/// 1. `One-one mappings`: +/// ``` +/// logical_to_winit_key!(a, Escape, F1, F2,...) +/// ``` +/// matches [`NamedKey::Escape`] => [`Key::Escape`], [`NamedKey::F1`] => [`Key::F1`], [`NamedKey::F2`] => [`Key::F2`],... +/// +/// 2. `Custom mappings`: +/// ``` +/// logical_to_winit_key!(a, Escape, F1 => F2, F3) +/// ``` +/// matches [`NamedKey::Escape`] => [`Key::Escape`], [`NamedKey::F1`] => [`Key::F2`], [`NamedKey::F3`] => [`Key::F3`],... +macro_rules! logical_to_winit_key { + // Matches an optional token + (@opt $_: ident, $optional: ident) => { + Key::$optional + }; + + (@opt $variant: ident) => { + Key::$variant + }; + + ($key: ident $(,$variant: ident $(=> $matchto: ident)?)+) => { + match $key { + LogicalKey::Character(c) => Key::Character(c.to_string()), + $(LogicalKey::Named(NamedKey::$variant) => logical_to_winit_key!(@opt $variant $(, $matchto)?),)+ + _ => Key::Unidentified, + } + }; +} + fn get_servo_key_from_winit_key(key: &LogicalKey) -> Key { // TODO: figure out how to map NavigateForward, NavigateBackward // TODO: map the remaining keys if possible - match key { - LogicalKey::Character(c) => Key::Character(c.to_string()), + logical_to_winit_key! { + key, // printable: Key1 to Key0 // printable: A to Z - LogicalKey::Named(NamedKey::Escape) => Key::Escape, - LogicalKey::Named(NamedKey::F1) => Key::F1, - LogicalKey::Named(NamedKey::F2) => Key::F2, - LogicalKey::Named(NamedKey::F3) => Key::F3, - LogicalKey::Named(NamedKey::F4) => Key::F4, - LogicalKey::Named(NamedKey::F5) => Key::F5, - LogicalKey::Named(NamedKey::F6) => Key::F6, - LogicalKey::Named(NamedKey::F7) => Key::F7, - LogicalKey::Named(NamedKey::F8) => Key::F8, - LogicalKey::Named(NamedKey::F9) => Key::F9, - LogicalKey::Named(NamedKey::F10) => Key::F10, - LogicalKey::Named(NamedKey::F11) => Key::F11, - LogicalKey::Named(NamedKey::F12) => Key::F12, + Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, // F13 to F15 are not mapped - LogicalKey::Named(NamedKey::PrintScreen) => Key::PrintScreen, + PrintScreen, // Scroll not mapped - LogicalKey::Named(NamedKey::Pause) => Key::Pause, - LogicalKey::Named(NamedKey::Insert) => Key::Insert, - LogicalKey::Named(NamedKey::Home) => Key::Home, - LogicalKey::Named(NamedKey::Delete) => Key::Delete, - LogicalKey::Named(NamedKey::End) => Key::End, - LogicalKey::Named(NamedKey::PageDown) => Key::PageDown, - LogicalKey::Named(NamedKey::PageUp) => Key::PageUp, - LogicalKey::Named(NamedKey::ArrowLeft) => Key::ArrowLeft, - LogicalKey::Named(NamedKey::ArrowUp) => Key::ArrowUp, - LogicalKey::Named(NamedKey::ArrowRight) => Key::ArrowRight, - LogicalKey::Named(NamedKey::ArrowDown) => Key::ArrowDown, - LogicalKey::Named(NamedKey::Backspace) => Key::Backspace, - LogicalKey::Named(NamedKey::Enter) => Key::Enter, + Pause, Insert, Home, Delete, End, PageDown, PageUp, + ArrowLeft, ArrowUp, ArrowRight, ArrowDown, + Backspace, Enter, // printable: Space - LogicalKey::Named(NamedKey::Compose) => Key::Compose, + Compose, // Caret not mapped - LogicalKey::Named(NamedKey::NumLock) => Key::NumLock, + NumLock, // printable: Numpad0 to Numpad9 // AbntC1 and AbntC2 not mapped // printable: Add, Apostrophe, // Apps, At, Ax not mapped // printable: Backslash, - LogicalKey::Named(NamedKey::LaunchApplication2) => Key::LaunchApplication2, - LogicalKey::Named(NamedKey::CapsLock) => Key::CapsLock, + LaunchApplication2, CapsLock, // printable: Colon, Comma, - LogicalKey::Named(NamedKey::Convert) => Key::Convert, + Convert, // not mapped: Decimal, // printable: Divide, Equals, Grave, - LogicalKey::Named(NamedKey::KanaMode) => Key::KanaMode, - LogicalKey::Named(NamedKey::KanjiMode) => Key::KanjiMode, - LogicalKey::Named(NamedKey::Alt) => Key::Alt, + KanaMode, KanjiMode, Alt, // printable: LBracket, - LogicalKey::Named(NamedKey::Control) => Key::Control, - LogicalKey::Named(NamedKey::Shift) => Key::Shift, - LogicalKey::Named(NamedKey::Meta) => Key::Meta, - LogicalKey::Named(NamedKey::LaunchMail) => Key::LaunchMail, + Control, Shift, Meta, LaunchMail, // not mapped: MediaSelect, - LogicalKey::Named(NamedKey::MediaStop) => Key::MediaStop, + MediaStop, // printable: Minus, Multiply, - LogicalKey::Named(NamedKey::AudioVolumeMute) => Key::AudioVolumeMute, - LogicalKey::Named(NamedKey::LaunchApplication1) => Key::LaunchApplication1, + AudioVolumeMute, LaunchApplication1, // not mapped: NavigateForward, NavigateBackward - LogicalKey::Named(NamedKey::MediaTrackNext) => Key::MediaTrackNext, - LogicalKey::Named(NamedKey::NonConvert) => Key::NonConvert, + MediaTrackNext, NonConvert, // printable: NumpadComma, NumpadEnter, NumpadEquals, // not mapped: OEM102, // printable: Period, - LogicalKey::Named(NamedKey::MediaPlayPause) => Key::MediaPlayPause, - LogicalKey::Named(NamedKey::Power) => Key::Power, - LogicalKey::Named(NamedKey::MediaTrackPrevious) => Key::MediaTrackPrevious, + MediaPlayPause, Power, MediaTrackPrevious, // printable RBracket // printable Semicolon, Slash - LogicalKey::Named(NamedKey::Standby) => Key::Standby, + Standby, // not mapped: Stop, // printable Subtract, // not mapped: Sysrq, - LogicalKey::Named(NamedKey::Tab) => Key::Tab, + Tab, // printable: Underline, // not mapped: Unlabeled, - LogicalKey::Named(NamedKey::AudioVolumeDown) => Key::AudioVolumeDown, - LogicalKey::Named(NamedKey::AudioVolumeUp) => Key::AudioVolumeUp, - LogicalKey::Named(NamedKey::WakeUp) => Key::WakeUp, - LogicalKey::Named(NamedKey::BrowserBack) => Key::BrowserBack, - LogicalKey::Named(NamedKey::BrowserFavorites) => Key::BrowserFavorites, - LogicalKey::Named(NamedKey::BrowserForward) => Key::BrowserForward, - LogicalKey::Named(NamedKey::BrowserHome) => Key::BrowserHome, - LogicalKey::Named(NamedKey::BrowserRefresh) => Key::BrowserRefresh, - LogicalKey::Named(NamedKey::BrowserSearch) => Key::BrowserSearch, - LogicalKey::Named(NamedKey::BrowserStop) => Key::BrowserStop, + AudioVolumeDown, AudioVolumeUp, WakeUp, BrowserBack, BrowserFavorites, BrowserForward, BrowserHome, BrowserRefresh, BrowserSearch, BrowserStop, // printable Yen, - LogicalKey::Named(NamedKey::Copy) => Key::Copy, - LogicalKey::Named(NamedKey::Paste) => Key::Paste, - LogicalKey::Named(NamedKey::Cut) => Key::Cut, - _ => Key::Unidentified, + Copy, + Paste, + Cut } } +/// Maps [`KeyCode`] to [`Location`]. +macro_rules! map_key_location { + ($key_code: ident $(, $location: ident : $k1: ident $(| $kn: ident)*)+) => { + match $key_code { + $(KeyCode::$k1 $(| KeyCode::$kn)* => Location::$location,)+ + _ => Location::Standard, + } + }; +} + fn get_servo_location_from_physical_key(physical_key: PhysicalKey) -> Location { let key_code = if let PhysicalKey::Code(key_code) = physical_key { key_code @@ -124,27 +125,47 @@ fn get_servo_location_from_physical_key(physical_key: PhysicalKey) -> Location { return Location::Standard; }; - // TODO: add more numpad keys - match key_code { - KeyCode::ShiftLeft | KeyCode::ControlLeft | KeyCode::AltLeft | KeyCode::SuperLeft => { - Location::Left - } - KeyCode::ShiftRight | KeyCode::ControlRight | KeyCode::AltRight | KeyCode::SuperRight => { - Location::Right + // TODO: Map more locations + map_key_location!( + key_code, + Left: ShiftLeft | ControlLeft | AltLeft | SuperLeft, + Right: ShiftRight | ControlRight | AltRight | SuperRight, + Numpad: Numpad0 | Numpad1 | Numpad2 | Numpad3 | Numpad4 | Numpad5 | Numpad6 | Numpad7 | Numpad8 | Numpad9 + | NumpadComma | NumpadEnter | NumpadEqual | NumpadAdd | NumpadSubtract | NumpadMultiply | NumpadDivide + | NumpadDecimal | NumpadBackspace | NumpadStar + ) +} + +/// Maps [`PhysicalKey`] to [`Code`]. +/// +/// Example: +/// 1. `One-one mappings`: +/// ``` +/// physical_key_to_code!(a, Escape, F1, F2,...) +/// ``` +/// matches [`KeyCode::Escape`] => [`Code::Escape`], [`KeyCode::F1`] => [`Code::F1`], [`KeyCode::F2`] => [`Code::F2`],... +/// +/// 2. `Custom mappings`: +/// ``` +/// physical_key_to_code!(a, Escape, F1 => F2, F3) +/// ``` +/// matches [`KeyCode::Escape`] => [`Code::Escape`], [`KeyCode::F1`] => [`Code::F2`], [`KeyCode::F3`] => [`Code::F3`],... +macro_rules! physical_key_to_code { + // Matches an optional token + (@opt $_: ident, $optional: ident) => { + Code::$optional + }; + + (@opt $variant: ident) => { + Code::$variant + }; + + ($key_code: ident $(, $pk: ident $(=> $matchto: ident)?)+) => { + match $key_code { + $(KeyCode::$pk => physical_key_to_code!(@opt $pk $(, $matchto)?),)+ + _ => Code::Unidentified, } - KeyCode::Numpad0 - | KeyCode::Numpad1 - | KeyCode::Numpad2 - | KeyCode::Numpad3 - | KeyCode::Numpad4 - | KeyCode::Numpad5 - | KeyCode::Numpad6 - | KeyCode::Numpad7 - | KeyCode::Numpad8 - | KeyCode::Numpad9 => Location::Numpad, - KeyCode::NumpadComma | KeyCode::NumpadEnter | KeyCode::NumpadEqual => Location::Numpad, - _ => Location::Standard, - } + }; } fn get_servo_code_from_physical_key(physical_key: PhysicalKey) -> Code { @@ -155,90 +176,23 @@ fn get_servo_code_from_physical_key(physical_key: PhysicalKey) -> Code { }; // TODO: Map more codes - match key_code { - KeyCode::Escape => Code::Escape, - KeyCode::Digit1 => Code::Digit1, - KeyCode::Digit2 => Code::Digit2, - KeyCode::Digit3 => Code::Digit3, - KeyCode::Digit4 => Code::Digit4, - KeyCode::Digit5 => Code::Digit5, - KeyCode::Digit6 => Code::Digit6, - KeyCode::Digit7 => Code::Digit7, - KeyCode::Digit8 => Code::Digit8, - KeyCode::Digit9 => Code::Digit9, - KeyCode::Digit0 => Code::Digit0, - - KeyCode::Backspace => Code::Backspace, - KeyCode::Tab => Code::Tab, - KeyCode::KeyQ => Code::KeyQ, - KeyCode::KeyW => Code::KeyW, - KeyCode::KeyE => Code::KeyE, - KeyCode::KeyR => Code::KeyR, - KeyCode::KeyT => Code::KeyT, - KeyCode::KeyY => Code::KeyY, - KeyCode::KeyU => Code::KeyU, - KeyCode::KeyI => Code::KeyI, - KeyCode::KeyO => Code::KeyO, - KeyCode::KeyP => Code::KeyP, - KeyCode::BracketLeft => Code::BracketLeft, - KeyCode::BracketRight => Code::BracketRight, - KeyCode::Enter => Code::Enter, - - KeyCode::KeyA => Code::KeyA, - KeyCode::KeyS => Code::KeyS, - KeyCode::KeyD => Code::KeyD, - KeyCode::KeyF => Code::KeyF, - KeyCode::KeyG => Code::KeyG, - KeyCode::KeyH => Code::KeyH, - KeyCode::KeyJ => Code::KeyJ, - KeyCode::KeyK => Code::KeyK, - KeyCode::KeyL => Code::KeyL, - KeyCode::Semicolon => Code::Semicolon, - KeyCode::Quote => Code::Quote, - - KeyCode::ShiftLeft => Code::ShiftLeft, - KeyCode::Backslash => Code::Backslash, - KeyCode::KeyZ => Code::KeyZ, - KeyCode::KeyX => Code::KeyX, - KeyCode::KeyC => Code::KeyC, - KeyCode::KeyV => Code::KeyV, - KeyCode::KeyB => Code::KeyB, - KeyCode::KeyN => Code::KeyN, - KeyCode::KeyM => Code::KeyM, - KeyCode::Comma => Code::Comma, - KeyCode::Period => Code::Period, - KeyCode::Slash => Code::Slash, - KeyCode::ShiftRight => Code::ShiftRight, - - KeyCode::Space => Code::Space, - - KeyCode::F1 => Code::F1, - KeyCode::F2 => Code::F2, - KeyCode::F3 => Code::F3, - KeyCode::F4 => Code::F4, - KeyCode::F5 => Code::F5, - KeyCode::F6 => Code::F6, - KeyCode::F7 => Code::F7, - KeyCode::F8 => Code::F8, - KeyCode::F9 => Code::F9, - KeyCode::F10 => Code::F10, - - KeyCode::F11 => Code::F11, - KeyCode::F12 => Code::F12, - - KeyCode::ArrowUp => Code::ArrowUp, - KeyCode::PageUp => Code::PageUp, - KeyCode::ArrowLeft => Code::ArrowLeft, - KeyCode::ArrowRight => Code::ArrowRight, - - KeyCode::Home => Code::Home, - KeyCode::End => Code::End, - KeyCode::ArrowDown => Code::ArrowDown, - KeyCode::PageDown => Code::PageDown, - KeyCode::Insert => Code::Insert, - KeyCode::Delete => Code::Delete, - - _ => Code::Unidentified, + physical_key_to_code! {key_code, + Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, + Backquote, Digit1, Digit2, Digit3, Digit4, Digit5, Digit6, Digit7, Digit8, Digit9, Digit0, Minus, Equal, Backspace, + Tab, KeyQ, KeyW, KeyE, KeyR, KeyT, KeyY, KeyU, KeyI, KeyO, KeyP, BracketLeft, BracketRight, Backslash, + CapsLock, KeyA, KeyS, KeyD, KeyF, KeyG, KeyH, KeyJ, KeyK, KeyL, Semicolon, Quote, Enter, + ShiftLeft, KeyZ, KeyX, KeyC, KeyV, KeyB, KeyN, KeyM, Comma, Period, Slash, ShiftRight, + ControlLeft, AltLeft, Space, AltRight, ControlRight, + PrintScreen, ScrollLock, Pause, + Insert, Home, PageUp, + Delete, End, PageDown, + ArrowUp, ArrowLeft, ArrowDown, ArrowRight, + NumLock, NumpadDivide, NumpadMultiply, NumpadStar, NumpadSubtract, + Numpad7, Numpad8, Numpad9, NumpadAdd, + Numpad4, Numpad5, Numpad6, + Numpad1, Numpad2, Numpad3, NumpadEnter, + Numpad0, NumpadDecimal, + NumpadParenLeft, NumpadParenRight, NumpadComma, NumpadHash, NumpadBackspace } }