From 5aaaedb887a7edf758b21c0086b6869c420b9b4a Mon Sep 17 00:00:00 2001 From: Richard Acayan Date: Fri, 26 Jul 2024 19:54:28 -0400 Subject: [PATCH] core: layout: add text property to key parts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some keys may have no XKB key symbol, but still have the ability to emit text. Examples include the "‹" (U+2039) and "›" (U+203A) characters. Add the text property to key parts so they can emit text even with no key symbol. Also, for keys that were not modified by the Function key because they had no XKB key symbol name, modify them. --- src/core/layout.rs | 277 ++++++++++++++++++++++++++++----------------- 1 file changed, 173 insertions(+), 104 deletions(-) diff --git a/src/core/layout.rs b/src/core/layout.rs index 8ec7418..ae8a854 100644 --- a/src/core/layout.rs +++ b/src/core/layout.rs @@ -56,11 +56,21 @@ pub const MOD_ALT: usize = 3; pub const MOD_FN: usize = 4; pub const MODIFIERS_MAX: usize = 4; -pub struct Part { - orig_sym: Keysym, - sym: Keysym, +#[derive(Clone)] +struct KeyValue(Keysym, String); + +impl KeyValue { + fn from(key: Keysym, text: &str) -> KeyValue + { + KeyValue(key, String::from(text)) + } +} + +pub struct Part { + orig: KeyValue, + + val: KeyValue, - // TODO: use accessors here presses: u32, } @@ -103,79 +113,130 @@ impl Part { } } - fn modify_fn(orig_sym: Keysym) -> Keysym + fn modify_fn(orig_sym: &KeyValue) -> KeyValue { match orig_sym { - Keysym::Up => Keysym::Prior, // Page Up - Keysym::Down => Keysym::Next, // Page Down - Keysym::Left => Keysym::Home, - Keysym::Right => Keysym::End, - Keysym::Escape => Keysym::Insert, + KeyValue(Keysym::Up, _) + => KeyValue::from(Keysym::Prior, "⇑"), // Page Up + KeyValue(Keysym::Down, _) + => KeyValue::from(Keysym::Next, "⇓"), // Page Down + KeyValue(Keysym::Left, _) + => KeyValue::from(Keysym::Home, "⇤"), + KeyValue(Keysym::Right, _) + => KeyValue::from(Keysym::End, "⇥"), + KeyValue(Keysym::Escape, _) + => KeyValue::from(Keysym::Insert, "Ins"), - Keysym::_1 => Keysym::F1, - Keysym::_2 => Keysym::F2, - Keysym::_3 => Keysym::F3, - Keysym::_4 => Keysym::F4, - Keysym::_5 => Keysym::F5, - Keysym::_6 => Keysym::F6, - Keysym::_7 => Keysym::F7, - Keysym::_8 => Keysym::F8, - Keysym::_9 => Keysym::F9, - Keysym::_0 => Keysym::F10, + KeyValue(Keysym::_1, _) + => KeyValue::from(Keysym::F1, "F1"), + KeyValue(Keysym::_2, _) + => KeyValue::from(Keysym::F2, "F2"), + KeyValue(Keysym::_3, _) + => KeyValue::from(Keysym::F3, "F3"), + KeyValue(Keysym::_4, _) + => KeyValue::from(Keysym::F4, "F4"), + KeyValue(Keysym::_5, _) + => KeyValue::from(Keysym::F5, "F5"), + KeyValue(Keysym::_6, _) + => KeyValue::from(Keysym::F6, "F6"), + KeyValue(Keysym::_7, _) + => KeyValue::from(Keysym::F7, "F7"), + KeyValue(Keysym::_8, _) + => KeyValue::from(Keysym::F8, "F8"), + KeyValue(Keysym::_9, _) + => KeyValue::from(Keysym::F9, "F9"), + KeyValue(Keysym::_0, _) + => KeyValue::from(Keysym::F10, "F10"), - Keysym::less => Keysym::guillemetleft, - Keysym::greater => Keysym::guillemetright, - // Keysym::braceleft => Keysym::from_char('\u{2039}'), - // Keysym::braceright => Keysym::from_char('\u{203A}'), - Keysym::bracketleft => Keysym::leftsinglequotemark, - Keysym::bracketright => Keysym::rightsinglequotemark, - Keysym::parenleft => Keysym::leftdoublequotemark, - Keysym::parenright => Keysym::rightdoublequotemark, - Keysym::apostrophe => Keysym::singlelowquotemark, - Keysym::quotedbl => Keysym::doublelowquotemark, - Keysym::minus => Keysym::endash, - Keysym::underscore => Keysym::emdash, - Keysym::asciicircum => Keysym::notsign, - Keysym::percent => Keysym::permille, - Keysym::equal => Keysym::approxeq, - Keysym::u => Keysym::mu, - Keysym::a => Keysym::ae, - Keysym::o => Keysym::oe, - Keysym::asterisk => Keysym::degree, - Keysym::period => Keysym::ellipsis, - Keysym::comma => Keysym::periodcentered, - Keysym::exclam => Keysym::exclamdown, - Keysym::question => Keysym::questiondown, - Keysym::bar => Keysym::brokenbar, + KeyValue(Keysym::less, _) + => KeyValue::from(Keysym::guillemetleft, "«"), + KeyValue(Keysym::greater, _) + => KeyValue::from(Keysym::guillemetright, "»"), + KeyValue(Keysym::braceleft, _) + => KeyValue::from(Keysym::NoSymbol, "‹"), + KeyValue(Keysym::braceright, _) + => KeyValue::from(Keysym::NoSymbol, "›"), + KeyValue(Keysym::bracketleft, _) + => KeyValue::from(Keysym::leftsinglequotemark, "‘"), + KeyValue(Keysym::bracketright, _) + => KeyValue::from(Keysym::rightsinglequotemark, "’"), + KeyValue(Keysym::parenleft, _) + => KeyValue::from(Keysym::leftdoublequotemark, "“"), + KeyValue(Keysym::parenright, _) + => KeyValue::from(Keysym::rightdoublequotemark, "”"), + KeyValue(Keysym::apostrophe, _) + => KeyValue::from(Keysym::singlelowquotemark, "‚"), + KeyValue(Keysym::quotedbl, _) + => KeyValue::from(Keysym::doublelowquotemark, "„"), + KeyValue(Keysym::minus, _) + => KeyValue::from(Keysym::endash, "–"), + KeyValue(Keysym::underscore, _) + => KeyValue::from(Keysym::emdash, "—"), + KeyValue(Keysym::asciicircum, _) + => KeyValue::from(Keysym::notsign, "¬"), + KeyValue(Keysym::percent, _) + => KeyValue::from(Keysym::permille, "‰"), + KeyValue(Keysym::equal, _) + => KeyValue::from(Keysym::approxeq, "≈"), + KeyValue(Keysym::u, _) + => KeyValue::from(Keysym::mu, "µ"), + KeyValue(Keysym::a, _) + => KeyValue::from(Keysym::ae, "æ"), + KeyValue(Keysym::o, _) + => KeyValue::from(Keysym::oe, "œ"), + KeyValue(Keysym::asterisk, _) + => KeyValue::from(Keysym::degree, "°"), + KeyValue(Keysym::period, _) + => KeyValue::from(Keysym::ellipsis, "…"), + KeyValue(Keysym::comma, _) + => KeyValue::from(Keysym::periodcentered, "·"), + KeyValue(Keysym::exclam, _) + => KeyValue::from(Keysym::exclamdown, "¡"), + KeyValue(Keysym::question, _) + => KeyValue::from(Keysym::questiondown, "¿"), + KeyValue(Keysym::bar, _) + => KeyValue::from(Keysym::brokenbar, "¦"), - Keysym::e => Keysym::EuroSign, - Keysym::l => Keysym::sterling, - // Keysym::r => Keysym::from_char('\u{20B9}'), - Keysym::y => Keysym::yen, - Keysym::c => Keysym::cent, - // Keysym::p => Keysym::from_char('\u{20BD}'), - // Keysym::b => Keysym::from_char('\u{20B1}'), - // Keysym::h => Keysym::from_char('\u{20B4}'), - // Keysym::z => Keysym::from_char('\u{20BF}'), + KeyValue(Keysym::e, _) + => KeyValue::from(Keysym::EuroSign, "€"), + KeyValue(Keysym::l, _) + => KeyValue::from(Keysym::sterling, "£"), + KeyValue(Keysym::r, _) + => KeyValue::from(Keysym::NoSymbol, "₹"), + KeyValue(Keysym::y, _) + => KeyValue::from(Keysym::yen, "¥"), + KeyValue(Keysym::c, _) + => KeyValue::from(Keysym::cent, "¢"), + KeyValue(Keysym::p, _) + => KeyValue::from(Keysym::NoSymbol, "₽"), + KeyValue(Keysym::b, _) + => KeyValue::from(Keysym::NoSymbol, "₱"), + KeyValue(Keysym::h, _) + => KeyValue::from(Keysym::NoSymbol, "₴"), + KeyValue(Keysym::z, _) + => KeyValue::from(Keysym::NoSymbol, "₿"), - _ => orig_sym, + _ => orig_sym.clone(), } } - fn modify_no_fn(orig_sym: Keysym) -> Keysym + fn modify_no_fn(orig: &KeyValue) -> KeyValue { - match orig_sym { - Keysym::F11 => Keysym::NoSymbol, - Keysym::F12 => Keysym::NoSymbol, - _ => orig_sym, + match orig { + KeyValue(Keysym::F11, _) => KeyValue::from(Keysym::NoSymbol, ""), + KeyValue(Keysym::F12, _) => KeyValue::from(Keysym::NoSymbol, ""), + _ => orig.clone(), } } - fn new(orig_sym: Keysym) -> Part + fn new(orig: KeyValue) -> Part { + let val = Self::modify_no_fn(&orig); + Part { - orig_sym, - sym: Self::modify_no_fn(orig_sym), + orig, + val, + presses: 0, } } @@ -183,7 +244,7 @@ impl Part { #[inline(always)] pub fn sym(&self) -> Keysym { - self.sym + self.val.0 } #[inline(always)] @@ -206,7 +267,7 @@ impl Part { pub fn modifier_id(&self) -> usize { - match self.sym { + match self.val.0 { Keysym::Shift_L => MOD_SHIFT, Keysym::Control_L => MOD_CTRL, Keysym::Alt_L => MOD_ALT, @@ -217,20 +278,28 @@ impl Part { pub fn update_modifiers(&mut self, mod_state: &[ModState]) { - let mut sym = self.orig_sym; + let mut val = self.orig.clone(); if mod_state[MOD_FN - 1] != ModState::Released { - sym = Self::modify_fn(sym); + val = Self::modify_fn(&val); } else { - sym = Self::modify_no_fn(sym); + val = Self::modify_no_fn(&val); } - self.sym = sym; + self.val = val; + } + + pub fn display_label(&self) -> &str + { + match self.val.1.as_ref() { + " " => "␣", + l => l, + } } pub fn display_symbol(&self, mod_state: &[ModState]) -> Keysym { - let mut sym = self.sym; + let mut sym = self.val.0; if mod_state[MOD_SHIFT - 1] != ModState::Released { sym = Self::modify_shift(sym); @@ -250,15 +319,15 @@ pub struct Key { impl Key { fn new(x1: f64, y1: f64, x2: f64, y2: f64, - center: Keysym, - top_left: Keysym, - top_right: Keysym, - bottom_left: Keysym, - bottom_right: Keysym, - left: Keysym, - right: Keysym, - top: Keysym, - bottom: Keysym) -> Key + center: KeyValue, + top_left: KeyValue, + top_right: KeyValue, + bottom_left: KeyValue, + bottom_right: KeyValue, + left: KeyValue, + right: KeyValue, + top: KeyValue, + bottom: KeyValue) -> Key { Key { x1, y1, x2, y2, @@ -285,27 +354,27 @@ pub struct Layout { in_row: u32, } -const KEYSYMS: [(&str, Keysym); 20] = [ - ("\\#", Keysym::numbersign), - ("\\?", Keysym::question), - ("\\@", Keysym::at), - ("\\\\", Keysym::backslash), - ("backspace", Keysym::BackSpace), - ("ctrl", Keysym::Control_L), - ("delete", Keysym::Delete), - ("down", Keysym::Down), - ("enter", Keysym::Return), - ("esc", Keysym::Escape), - ("f11_placeholder", Keysym::F11), - ("f12_placeholder", Keysym::F12), - ("fn", Keysym::XF86_Fn), - ("left", Keysym::Left), - ("loc alt", Keysym::Alt_L), - ("right", Keysym::Right), - ("shift", Keysym::Shift_L), - ("space", Keysym::space), - ("tab", Keysym::Tab), - ("up", Keysym::Up), +const KEYSYMS: [(&str, Keysym, &str); 20] = [ + ("\\#", Keysym::numbersign, "#"), + ("\\?", Keysym::question, "?"), + ("\\@", Keysym::at, "@"), + ("\\\\", Keysym::backslash, "\\"), + ("backspace", Keysym::BackSpace, "⌫"), + ("ctrl", Keysym::Control_L, "Ctrl"), + ("delete", Keysym::Delete, "⌦"), + ("down", Keysym::Down, "↓"), + ("enter", Keysym::Return, "⏎"), + ("esc", Keysym::Escape, "Esc"), + ("f11_placeholder", Keysym::F11, "F11"), + ("f12_placeholder", Keysym::F12, "F12"), + ("fn", Keysym::XF86_Fn, "Fn"), + ("left", Keysym::Left, "←"), + ("loc alt", Keysym::Alt_L, "Alt"), + ("right", Keysym::Right, "→"), + ("shift", Keysym::Shift_L, "⇧"), + ("space", Keysym::space, "␣"), + ("tab", Keysym::Tab, "⭾"), + ("up", Keysym::Up, "↑"), ]; impl Layout { @@ -335,10 +404,10 @@ impl Layout { } } - fn get_keysym_by_name(name: &str) -> Keysym + fn get_keysym_by_name(name: &str) -> KeyValue { - if let Ok(idx) = KEYSYMS.binary_search_by_key(&name, |&(k, _)| k) { - return KEYSYMS[idx].1; + if let Ok(idx) = KEYSYMS.binary_search_by_key(&name, |&(k, _, _)| k) { + return KeyValue::from(KEYSYMS[idx].1, KEYSYMS[idx].2); } let mut chars = name.chars(); @@ -346,8 +415,8 @@ impl Layout { let c1 = chars.next(); let c2 = chars.next(); match (c1, c2) { - (Some(c), None) => Keysym::new(c as u32), - _ => Keysym::NoSymbol, + (Some(c), None) => KeyValue::from(Keysym::new(c as u32), name), + _ => KeyValue::from(Keysym::NoSymbol, ""), } }