From f0a46dbff9da43694ecff89a37bacd635788b653 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Fri, 25 Jun 2021 20:41:49 -0700 Subject: [PATCH] Keyboard deadkey handling (#752) * first stab at better dead key handling * don't send S- --- src/window/window_wrapper/keyboard_manager.rs | 110 +++++++++--------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/src/window/window_wrapper/keyboard_manager.rs b/src/window/window_wrapper/keyboard_manager.rs index e3b0a5b..4131b07 100644 --- a/src/window/window_wrapper/keyboard_manager.rs +++ b/src/window/window_wrapper/keyboard_manager.rs @@ -4,14 +4,6 @@ use glutin::keyboard::Key; use crate::bridge::UiCommand; use crate::channel_utils::LoggingTx; -pub struct KeyboardManager { - command_sender: LoggingTx, - shift: bool, - ctrl: bool, - alt: bool, - logo: bool, -} - #[cfg(not(target_os = "windows"))] fn use_logo(logo: bool) -> bool { logo @@ -32,53 +24,59 @@ fn or_empty(condition: bool, text: &str) -> &str { } } -fn get_key_text(key: Key<'static>) -> Option<(&str, bool)> { +fn is_control_key(key: Key<'static>) -> Option<&str> { match key { - Key::Character(character_text) => match character_text { - " " => Some(("Space", true)), - "<" => Some(("lt", true)), - "\\" => Some(("Bslash", true)), - "|" => Some(("Bar", true)), - " " => Some(("Tab", true)), - "\n" => Some(("CR", true)), - _ => Some((character_text, false)), - }, - Key::Backspace => Some(("BS", true)), - Key::Tab => Some(("Tab", true)), - Key::Enter => Some(("CR", true)), - Key::Escape => Some(("Esc", true)), - Key::Space => Some(("Space", true)), - Key::Delete => Some(("Del", true)), - Key::ArrowUp => Some(("Up", true)), - Key::ArrowDown => Some(("Down", true)), - Key::ArrowLeft => Some(("Left", true)), - Key::ArrowRight => Some(("Right", true)), - Key::F1 => Some(("F1", true)), - Key::F2 => Some(("F2", true)), - Key::F3 => Some(("F3", true)), - Key::F4 => Some(("F4", true)), - Key::F5 => Some(("F5", true)), - Key::F6 => Some(("F6", true)), - Key::F7 => Some(("F7", true)), - Key::F8 => Some(("F8", true)), - Key::F9 => Some(("F9", true)), - Key::F10 => Some(("F10", true)), - Key::F11 => Some(("F11", true)), - Key::F12 => Some(("F12", true)), - Key::Insert => Some(("Insert", true)), - Key::Home => Some(("Home", true)), - Key::End => Some(("End", true)), - Key::PageUp => Some(("PageUp", true)), - Key::PageDown => Some(("PageDown", true)), + Key::Backspace => Some("BS"), + Key::Escape => Some("Esc"), + Key::Delete => Some("Del"), + Key::ArrowUp => Some("Up"), + Key::ArrowDown => Some("Down"), + Key::ArrowLeft => Some("Left"), + Key::ArrowRight => Some("Right"), + Key::F1 => Some("F1"), + Key::F2 => Some("F2"), + Key::F3 => Some("F3"), + Key::F4 => Some("F4"), + Key::F5 => Some("F5"), + Key::F6 => Some("F6"), + Key::F7 => Some("F7"), + Key::F8 => Some("F8"), + Key::F9 => Some("F9"), + Key::F10 => Some("F10"), + Key::F11 => Some("F11"), + Key::F12 => Some("F12"), + Key::Insert => Some("Insert"), + Key::Home => Some("Home"), + Key::End => Some("End"), + Key::PageUp => Some("PageUp"), + Key::PageDown => Some("PageDown"), + _ => None, + } +} + +fn is_special(text: &str) -> Option<&str> { + match text { + " " => Some("Space"), + "<" => Some("lt"), + "\\" => Some("Bslash"), + "|" => Some("Bar"), + "\t" => Some("Tab"), + "\n" => Some("CR"), _ => None, } } +pub struct KeyboardManager { + command_sender: LoggingTx, + ctrl: bool, + alt: bool, + logo: bool, +} + impl KeyboardManager { pub fn new(command_sender: LoggingTx) -> KeyboardManager { KeyboardManager { command_sender, - shift: false, ctrl: false, alt: false, logo: false, @@ -86,16 +84,15 @@ impl KeyboardManager { } fn format_keybinding_string(&self, special: bool, text: &str) -> String { - let special = special || self.shift || self.ctrl || self.alt || self.logo; + let special = special || self.ctrl || self.alt || self.logo; let open = or_empty(special, "<"); - let shift = or_empty(self.shift, "S-"); let ctrl = or_empty(self.ctrl, "C-"); let alt = or_empty(self.alt, "M-"); let logo = or_empty(use_logo(self.logo), "D-"); let close = or_empty(special, ">"); - format!("{}{}{}{}{}{}{}", open, shift, ctrl, alt, logo, text, close) + format!("{}{}{}{}{}{}", open, ctrl, alt, logo, text, close) } pub fn handle_event(&mut self, event: &Event<()>) { @@ -108,8 +105,18 @@ impl KeyboardManager { .. } => { if key_event.state == ElementState::Pressed { - if let Some((key_text, special)) = get_key_text(key_event.logical_key) { - let keybinding_string = self.format_keybinding_string(special, key_text); + if let Some(key_text) = is_control_key(key_event.logical_key) { + let keybinding_string = self.format_keybinding_string(true, key_text); + + self.command_sender + .send(UiCommand::Keyboard(keybinding_string)) + .expect("Could not send keyboard ui command"); + } else if let Some(key_text) = key_event.text { + let keybinding_string = if let Some(escaped_text) = is_special(key_text) { + self.format_keybinding_string(true, escaped_text) + } else { + self.format_keybinding_string(false, key_text) + }; self.command_sender .send(UiCommand::Keyboard(keybinding_string)) @@ -121,7 +128,6 @@ impl KeyboardManager { event: WindowEvent::ModifiersChanged(modifiers), .. } => { - self.shift = modifiers.shift_key(); self.ctrl = modifiers.control_key(); self.alt = modifiers.alt_key(); self.logo = modifiers.super_key();