From 24a7234858b1a60b85f57e9b1663698cb44b4c37 Mon Sep 17 00:00:00 2001 From: vzex Date: Sun, 19 Dec 2021 01:09:52 +0800 Subject: [PATCH] add more support for dead key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit list user cases for dead key and modify key(alt), on mac: 1 (us keyboard):[options+e u]=>ú 2 (us keyboard):[options+8]=>• 3 (chinese keyboard) ime:[nihao space]=>你好 4 (Austria keyboard):[= a] => á 5 (Austria keyboard):[= q] =>`q 6 (Austria keyboard):[= =] =>´´q 7 (Austria keyboard):[= shift+= q] =>´`q 8 (Austria keyboard):[= esc] =>´ and leave insert mode 9 (Austria keyboard):[= left] =>´ and move caret to left --- src/window/keyboard_manager.rs | 43 ++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/window/keyboard_manager.rs b/src/window/keyboard_manager.rs index 682f420..81b7bcd 100644 --- a/src/window/keyboard_manager.rs +++ b/src/window/keyboard_manager.rs @@ -1,5 +1,6 @@ use glutin::event::{ElementState, Event, KeyEvent, WindowEvent}; use glutin::keyboard::Key; +use glutin::keyboard::Key::Dead; use glutin::platform::modifier_supplement::KeyEventExtModifierSupplement; @@ -16,6 +17,7 @@ pub struct KeyboardManager { shift: bool, ctrl: bool, alt: bool, + pre_is_dead: Option, logo: bool, ignore_input_this_frame: bool, queued_input_events: Vec, @@ -27,6 +29,7 @@ impl KeyboardManager { shift: false, ctrl: false, alt: false, + pre_is_dead: None, logo: false, ignore_input_this_frame: false, queued_input_events: Vec::new(), @@ -79,23 +82,34 @@ impl KeyboardManager { if !self.should_ignore_input(&settings) { // If we have a keyboard event this frame + let mut pre_is_dead = self.pre_is_dead; for input_event in self.queued_input_events.iter() { match input_event { InputEvent::KeyEvent(key_event) => { // And a key was pressed if key_event.state == ElementState::Pressed { - if let Some(keybinding) = self.maybe_get_keybinding(key_event) { + if let Some(keybinding) = + self.maybe_get_keybinding(key_event, &mut pre_is_dead) + { EVENT_AGGREGATOR .send(UiCommand::Serial(SerialCommand::Keyboard(keybinding))); } + } else if key_event.state == ElementState::Released { + // dead key detect here + if let Dead(dead_key) = key_event.logical_key { + pre_is_dead = dead_key; //should wait for the next input text_with_all_modifiers, and ignore the next ime. + } } } InputEvent::ImeInput(raw_input) => { - EVENT_AGGREGATOR - .send(UiCommand::Serial(SerialCommand::Keyboard(raw_input.to_string()))); + if pre_is_dead.is_none() { + EVENT_AGGREGATOR + .send(UiCommand::Serial(SerialCommand::Keyboard(raw_input.to_string()))); + } } } } + self.pre_is_dead = pre_is_dead; } // Regardless of whether this was a valid keyboard input or not, rest ignoring and @@ -111,14 +125,29 @@ impl KeyboardManager { self.ignore_input_this_frame || (self.logo && !settings.use_logo) } - fn maybe_get_keybinding(&self, key_event: &KeyEvent) -> Option { + fn maybe_get_keybinding( + &self, + key_event: &KeyEvent, + pre_is_dead: &mut Option, + ) -> Option { // Determine if this key event represents a key which won't ever // present text. - if let Some(key_text) = is_control_key(key_event.logical_key) { - Some(self.format_keybinding_string(true, true, key_text)) + if pre_is_dead.is_some() { + //recover dead key to normal character + let real_char = String::from(pre_is_dead.unwrap()); + *pre_is_dead = None; + Some(real_char + &self.format_keybinding_string(true, true, key_text)) + } else { + Some(self.format_keybinding_string(true, true, key_text)) + } } else { - let key_text = key_event.text; + let key_text = if pre_is_dead.is_none() { + key_event.text + } else { + key_event.text_with_all_modifiers() + }; + *pre_is_dead = None; if let Some(ori_key_text) = key_text { let mut key_text = ori_key_text; if self.alt {