Keyboard deadkey handling (#752)

* first stab at better dead key handling

* don't send S-
macos-click-through
Keith Simmons 3 years ago committed by GitHub
parent 7a1fa123b8
commit f0a46dbff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,14 +4,6 @@ use glutin::keyboard::Key;
use crate::bridge::UiCommand; use crate::bridge::UiCommand;
use crate::channel_utils::LoggingTx; use crate::channel_utils::LoggingTx;
pub struct KeyboardManager {
command_sender: LoggingTx<UiCommand>,
shift: bool,
ctrl: bool,
alt: bool,
logo: bool,
}
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
fn use_logo(logo: bool) -> bool { fn use_logo(logo: bool) -> bool {
logo 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 { match key {
Key::Character(character_text) => match character_text { Key::Backspace => Some("BS"),
" " => Some(("Space", true)), Key::Escape => Some("Esc"),
"<" => Some(("lt", true)), Key::Delete => Some("Del"),
"\\" => Some(("Bslash", true)), Key::ArrowUp => Some("Up"),
"|" => Some(("Bar", true)), Key::ArrowDown => Some("Down"),
" " => Some(("Tab", true)), Key::ArrowLeft => Some("Left"),
"\n" => Some(("CR", true)), Key::ArrowRight => Some("Right"),
_ => Some((character_text, false)), Key::F1 => Some("F1"),
}, Key::F2 => Some("F2"),
Key::Backspace => Some(("BS", true)), Key::F3 => Some("F3"),
Key::Tab => Some(("Tab", true)), Key::F4 => Some("F4"),
Key::Enter => Some(("CR", true)), Key::F5 => Some("F5"),
Key::Escape => Some(("Esc", true)), Key::F6 => Some("F6"),
Key::Space => Some(("Space", true)), Key::F7 => Some("F7"),
Key::Delete => Some(("Del", true)), Key::F8 => Some("F8"),
Key::ArrowUp => Some(("Up", true)), Key::F9 => Some("F9"),
Key::ArrowDown => Some(("Down", true)), Key::F10 => Some("F10"),
Key::ArrowLeft => Some(("Left", true)), Key::F11 => Some("F11"),
Key::ArrowRight => Some(("Right", true)), Key::F12 => Some("F12"),
Key::F1 => Some(("F1", true)), Key::Insert => Some("Insert"),
Key::F2 => Some(("F2", true)), Key::Home => Some("Home"),
Key::F3 => Some(("F3", true)), Key::End => Some("End"),
Key::F4 => Some(("F4", true)), Key::PageUp => Some("PageUp"),
Key::F5 => Some(("F5", true)), Key::PageDown => Some("PageDown"),
Key::F6 => Some(("F6", true)), _ => None,
Key::F7 => Some(("F7", true)), }
Key::F8 => Some(("F8", true)), }
Key::F9 => Some(("F9", true)),
Key::F10 => Some(("F10", true)), fn is_special(text: &str) -> Option<&str> {
Key::F11 => Some(("F11", true)), match text {
Key::F12 => Some(("F12", true)), " " => Some("Space"),
Key::Insert => Some(("Insert", true)), "<" => Some("lt"),
Key::Home => Some(("Home", true)), "\\" => Some("Bslash"),
Key::End => Some(("End", true)), "|" => Some("Bar"),
Key::PageUp => Some(("PageUp", true)), "\t" => Some("Tab"),
Key::PageDown => Some(("PageDown", true)), "\n" => Some("CR"),
_ => None, _ => None,
} }
} }
pub struct KeyboardManager {
command_sender: LoggingTx<UiCommand>,
ctrl: bool,
alt: bool,
logo: bool,
}
impl KeyboardManager { impl KeyboardManager {
pub fn new(command_sender: LoggingTx<UiCommand>) -> KeyboardManager { pub fn new(command_sender: LoggingTx<UiCommand>) -> KeyboardManager {
KeyboardManager { KeyboardManager {
command_sender, command_sender,
shift: false,
ctrl: false, ctrl: false,
alt: false, alt: false,
logo: false, logo: false,
@ -86,16 +84,15 @@ impl KeyboardManager {
} }
fn format_keybinding_string(&self, special: bool, text: &str) -> String { 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 open = or_empty(special, "<");
let shift = or_empty(self.shift, "S-");
let ctrl = or_empty(self.ctrl, "C-"); let ctrl = or_empty(self.ctrl, "C-");
let alt = or_empty(self.alt, "M-"); let alt = or_empty(self.alt, "M-");
let logo = or_empty(use_logo(self.logo), "D-"); let logo = or_empty(use_logo(self.logo), "D-");
let close = or_empty(special, ">"); 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<()>) { pub fn handle_event(&mut self, event: &Event<()>) {
@ -108,8 +105,18 @@ impl KeyboardManager {
.. ..
} => { } => {
if key_event.state == ElementState::Pressed { if key_event.state == ElementState::Pressed {
if let Some((key_text, special)) = get_key_text(key_event.logical_key) { if let Some(key_text) = is_control_key(key_event.logical_key) {
let keybinding_string = self.format_keybinding_string(special, key_text); 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 self.command_sender
.send(UiCommand::Keyboard(keybinding_string)) .send(UiCommand::Keyboard(keybinding_string))
@ -121,7 +128,6 @@ impl KeyboardManager {
event: WindowEvent::ModifiersChanged(modifiers), event: WindowEvent::ModifiersChanged(modifiers),
.. ..
} => { } => {
self.shift = modifiers.shift_key();
self.ctrl = modifiers.control_key(); self.ctrl = modifiers.control_key();
self.alt = modifiers.alt_key(); self.alt = modifiers.alt_key();
self.logo = modifiers.super_key(); self.logo = modifiers.super_key();

Loading…
Cancel
Save