From b9a363f423caa507f56711c934f39059609985b7 Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Sun, 24 Jul 2022 19:52:06 -0600 Subject: [PATCH 1/7] Add support for Super, Hyper, and Meta modifiers This will only work in a terminal supporting the kitty keyboard protocol. --- src/event.rs | 9 +++++++- src/event/sys/unix/parse.rs | 42 ++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/event.rs b/src/event.rs index e32ea9515..6d0ff10db 100644 --- a/src/event.rs +++ b/src/event.rs @@ -534,12 +534,19 @@ pub enum MouseButton { } bitflags! { - /// Represents key modifiers (shift, control, alt). + /// Represents key modifiers (shift, control, alt, etc.). + /// + /// **Note:** `SUPER`, `HYPER`, and `META` can only be read if + /// [`KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES`] has been enabled with + /// [`PushKeyboardEnhancementFlags`]. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct KeyModifiers: u8 { const SHIFT = 0b0000_0001; const CONTROL = 0b0000_0010; const ALT = 0b0000_0100; + const SUPER = 0b0000_1000; + const HYPER = 0b0001_0000; + const META = 0b0010_0000; const NONE = 0b0000_0000; } } diff --git a/src/event/sys/unix/parse.rs b/src/event/sys/unix/parse.rs index 37d5ecf70..923a4124a 100644 --- a/src/event/sys/unix/parse.rs +++ b/src/event/sys/unix/parse.rs @@ -251,6 +251,15 @@ fn parse_modifiers(mask: u8) -> KeyModifiers { if modifier_mask & 4 != 0 { modifiers |= KeyModifiers::CONTROL; } + if modifier_mask & 8 != 0 { + modifiers |= KeyModifiers::SUPER; + } + if modifier_mask & 16 != 0 { + modifiers |= KeyModifiers::HYPER; + } + if modifier_mask & 32 != 0 { + modifiers |= KeyModifiers::META; + } modifiers } @@ -266,7 +275,13 @@ fn parse_key_event_kind(kind: u8) -> KeyEventKind { pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> Result> { assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [ - let modifier_mask = buffer[buffer.len() - 2]; + let modifier_mask = if buffer.len() > 3 { + (buffer[buffer.len() - 2] as char) + .to_digit(10) + .ok_or(could_not_parse_event_error())? as u8 + } else { + 0 + }; let key = buffer[buffer.len() - 1]; let modifiers = parse_modifiers(modifier_mask); @@ -1170,4 +1185,29 @@ mod tests { )))), ); } + + #[test] + fn test_parse_csi_u_encoded_key_code_with_extra_modifiers() { + assert_eq!( + parse_csi_u_encoded_key_code(b"\x1B[97;9u").unwrap(), + Some(InternalEvent::Event(Event::Key(KeyEvent::new( + KeyCode::Char('a'), + KeyModifiers::SUPER + )))), + ); + assert_eq!( + parse_csi_u_encoded_key_code(b"\x1B[97;17u").unwrap(), + Some(InternalEvent::Event(Event::Key(KeyEvent::new( + KeyCode::Char('a'), + KeyModifiers::HYPER + )))), + ); + assert_eq!( + parse_csi_u_encoded_key_code(b"\x1B[97;37u").unwrap(), + Some(InternalEvent::Event(Event::Key(KeyEvent::new( + KeyCode::Char('a'), + KeyModifiers::META | KeyModifiers::CONTROL + )))), + ); + } } From 7994d73cd3ced9c7103087b50cfed4764797d110 Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Sun, 24 Jul 2022 23:29:24 -0600 Subject: [PATCH 2/7] Fix modifier parsing for release events for special keys --- src/event/sys/unix/parse.rs | 56 ++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/event/sys/unix/parse.rs b/src/event/sys/unix/parse.rs index 923a4124a..58c0590ee 100644 --- a/src/event/sys/unix/parse.rs +++ b/src/event/sys/unix/parse.rs @@ -169,6 +169,7 @@ pub(crate) fn parse_csi(buffer: &[u8]) -> Result> { b'<' => return parse_csi_sgr_mouse(buffer), b'I' => Some(Event::FocusGained), b'O' => Some(Event::FocusLost), + b';' => return parse_csi_modifier_key_code(buffer), b'0'..=b'9' => { // Numbered escape code. if buffer.len() == 3 { @@ -274,17 +275,32 @@ fn parse_key_event_kind(kind: u8) -> KeyEventKind { pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> Result> { assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [ + // + let s = std::str::from_utf8(&buffer[2..buffer.len() - 1]) + .map_err(|_| could_not_parse_event_error())?; + let mut split = s.split(';'); - let modifier_mask = if buffer.len() > 3 { - (buffer[buffer.len() - 2] as char) - .to_digit(10) - .ok_or(could_not_parse_event_error())? as u8 - } else { - 0 - }; - let key = buffer[buffer.len() - 1]; + split.next(); - let modifiers = parse_modifiers(modifier_mask); + let (modifiers, kind) = + if let Ok((modifier_mask, kind_code)) = modifier_and_kind_parsed(&mut split) { + ( + parse_modifiers(modifier_mask), + parse_key_event_kind(kind_code), + ) + } else if buffer.len() > 3 { + ( + parse_modifiers( + (buffer[buffer.len() - 2] as char) + .to_digit(10) + .ok_or(could_not_parse_event_error())? as u8, + ), + KeyEventKind::Press, + ) + } else { + (KeyModifiers::NONE, KeyEventKind::Press) + }; + let key = buffer[buffer.len() - 1]; let keycode = match key { b'A' => KeyCode::Up, @@ -300,7 +316,7 @@ pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> Result return Err(could_not_parse_event_error()), }; - let input_event = Event::Key(KeyEvent::new(keycode, modifiers)); + let input_event = Event::Key(KeyEvent::new_with_kind(keycode, modifiers, kind)); Ok(Some(InternalEvent::Event(input_event))) } @@ -1210,4 +1226,24 @@ mod tests { )))), ); } + + #[test] + fn test_parse_csi_special_key_code_with_types() { + assert_eq!( + parse_event(b"\x1B[;1:3B", false).unwrap(), + Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind( + KeyCode::Down, + KeyModifiers::empty(), + KeyEventKind::Release, + )))), + ); + assert_eq!( + parse_event(b"\x1B[1;1:3B", false).unwrap(), + Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind( + KeyCode::Down, + KeyModifiers::empty(), + KeyEventKind::Release, + )))), + ); + } } From ef684f9f30b4b27b1823559bf9597a4de9a7be44 Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Mon, 1 Aug 2022 00:07:58 -0600 Subject: [PATCH 3/7] Move Hyper/Meta into state field, add Num/Caps Lock to state field --- src/event.rs | 27 +++++++- src/event/sys/unix/parse.rs | 119 +++++++++++++++++++++++++++++++----- 2 files changed, 128 insertions(+), 18 deletions(-) diff --git a/src/event.rs b/src/event.rs index 6d0ff10db..c089ac953 100644 --- a/src/event.rs +++ b/src/event.rs @@ -536,7 +536,7 @@ pub enum MouseButton { bitflags! { /// Represents key modifiers (shift, control, alt, etc.). /// - /// **Note:** `SUPER`, `HYPER`, and `META` can only be read if + /// **Note:** `SUPER` can only be read if /// [`KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES`] has been enabled with /// [`PushKeyboardEnhancementFlags`]. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -545,8 +545,6 @@ bitflags! { const CONTROL = 0b0000_0010; const ALT = 0b0000_0100; const SUPER = 0b0000_1000; - const HYPER = 0b0001_0000; - const META = 0b0010_0000; const NONE = 0b0000_0000; } } @@ -562,10 +560,33 @@ pub enum KeyEventKind { bitflags! { /// Represents extra state about the key event. + /// + /// **Note:** This state can only be read if + /// [`KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES`] has been enabled with + /// [`PushKeyboardEnhancementFlags`]. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct KeyEventState: u8 { /// The key event origins from the keypad. const KEYPAD = 0b0000_0001; + /// The Hyper modifier was held for this key event. + /// + /// This modifier is uncommon; thus, it is not stored in [`KeyEvent.state`] to avoid + /// confusion or failures to match key events. + const MODIFIER_HYPER = 0b0000_0010; + /// The Meta modifier was held for this key event. + /// + /// This modifier is uncommon; thus, it is not stored in [`KeyEvent.state`] to avoid + /// confusion or failures to match key events. + const MODIFIER_META = 0b0000_0100; + /// Caps Lock was enabled for this key event. + /// + /// **Note:** this is set for the initial press of Num Lock itself. + const CAPS_LOCK = 0b0000_1000; + /// Num Lock was enabled for this key event. + /// + /// **Note:** this is set for the initial press of Num Lock itself. + const NUM_LOCK = 0b0000_1000; + const NONE = 0b0000_0000; } } diff --git a/src/event/sys/unix/parse.rs b/src/event/sys/unix/parse.rs index 58c0590ee..2bcab95dd 100644 --- a/src/event/sys/unix/parse.rs +++ b/src/event/sys/unix/parse.rs @@ -255,13 +255,25 @@ fn parse_modifiers(mask: u8) -> KeyModifiers { if modifier_mask & 8 != 0 { modifiers |= KeyModifiers::SUPER; } + modifiers +} + +fn parse_modifiers_to_state(mask: u8) -> KeyEventState { + let modifier_mask = mask.saturating_sub(1); + let mut state = KeyEventState::empty(); if modifier_mask & 16 != 0 { - modifiers |= KeyModifiers::HYPER; + state |= KeyEventState::MODIFIER_HYPER; } if modifier_mask & 32 != 0 { - modifiers |= KeyModifiers::META; + state |= KeyEventState::MODIFIER_META; } - modifiers + if modifier_mask & 64 != 0 { + state |= KeyEventState::CAPS_LOCK; + } + if modifier_mask & 128 != 0 { + state |= KeyEventState::NUM_LOCK; + } + state } fn parse_key_event_kind(kind: u8) -> KeyEventKind { @@ -435,17 +447,18 @@ pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> Result(&mut split)?; - let (mut modifiers, kind) = + let (mut modifiers, kind, state_from_modifiers) = if let Ok((modifier_mask, kind_code)) = modifier_and_kind_parsed(&mut split) { ( parse_modifiers(modifier_mask), parse_key_event_kind(kind_code), + parse_modifiers_to_state(modifier_mask), ) } else { - (KeyModifiers::NONE, KeyEventKind::Press) + (KeyModifiers::NONE, KeyEventKind::Press, KeyEventState::NONE) }; - let (keycode, state) = { + let (keycode, mut state_from_keycode) = { if let Some((special_key_code, state)) = translate_functional_key_code(codepoint) { (special_key_code, state) } else if let Some(c) = char::from_u32(codepoint) { @@ -486,12 +499,24 @@ pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> Result { modifiers.set(KeyModifiers::SHIFT, true) } + ModifierKeyCode::LeftSuper | ModifierKeyCode::RightSuper => { + modifiers.set(KeyModifiers::SUPER, true) + } + ModifierKeyCode::LeftHyper | ModifierKeyCode::RightHyper => { + state_from_keycode.set(KeyEventState::MODIFIER_HYPER, true) + } + ModifierKeyCode::LeftMeta | ModifierKeyCode::RightMeta => { + state_from_keycode.set(KeyEventState::MODIFIER_META, true) + } _ => {} } } let input_event = Event::Key(KeyEvent::new_with_kind_and_state( - keycode, modifiers, kind, state, + keycode, + modifiers, + kind, + state_from_keycode | state_from_modifiers, )); Ok(Some(InternalEvent::Event(input_event))) @@ -1200,6 +1225,36 @@ mod tests { KeyEventKind::Release, )))), ); + assert_eq!( + parse_csi_u_encoded_key_code(b"\x1B[57450u").unwrap(), + Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind( + KeyCode::Modifier(ModifierKeyCode::RightSuper), + KeyModifiers::SUPER, + KeyEventKind::Press, + )))), + ); + assert_eq!( + parse_csi_u_encoded_key_code(b"\x1B[57451u").unwrap(), + Some(InternalEvent::Event(Event::Key( + KeyEvent::new_with_kind_and_state( + KeyCode::Modifier(ModifierKeyCode::RightHyper), + KeyModifiers::NONE, + KeyEventKind::Press, + KeyEventState::MODIFIER_HYPER, + ) + ))), + ); + assert_eq!( + parse_csi_u_encoded_key_code(b"\x1B[57452u").unwrap(), + Some(InternalEvent::Event(Event::Key( + KeyEvent::new_with_kind_and_state( + KeyCode::Modifier(ModifierKeyCode::RightMeta), + KeyModifiers::NONE, + KeyEventKind::Press, + KeyEventState::MODIFIER_META, + ) + ))), + ); } #[test] @@ -1211,19 +1266,53 @@ mod tests { KeyModifiers::SUPER )))), ); + } + + #[test] + fn test_parse_csi_u_encoded_key_code_with_extra_state() { assert_eq!( parse_csi_u_encoded_key_code(b"\x1B[97;17u").unwrap(), - Some(InternalEvent::Event(Event::Key(KeyEvent::new( - KeyCode::Char('a'), - KeyModifiers::HYPER - )))), + Some(InternalEvent::Event(Event::Key( + KeyEvent::new_with_kind_and_state( + KeyCode::Char('a'), + KeyModifiers::empty(), + KeyEventKind::Press, + KeyEventState::MODIFIER_HYPER, + ) + ))), ); assert_eq!( parse_csi_u_encoded_key_code(b"\x1B[97;37u").unwrap(), - Some(InternalEvent::Event(Event::Key(KeyEvent::new( - KeyCode::Char('a'), - KeyModifiers::META | KeyModifiers::CONTROL - )))), + Some(InternalEvent::Event(Event::Key( + KeyEvent::new_with_kind_and_state( + KeyCode::Char('a'), + KeyModifiers::CONTROL, + KeyEventKind::Press, + KeyEventState::MODIFIER_META, + ) + ))), + ); + assert_eq!( + parse_csi_u_encoded_key_code(b"\x1B[97;65u").unwrap(), + Some(InternalEvent::Event(Event::Key( + KeyEvent::new_with_kind_and_state( + KeyCode::Char('a'), + KeyModifiers::empty(), + KeyEventKind::Press, + KeyEventState::CAPS_LOCK, + ) + ))), + ); + assert_eq!( + parse_csi_u_encoded_key_code(b"\x1B[49;129u").unwrap(), + Some(InternalEvent::Event(Event::Key( + KeyEvent::new_with_kind_and_state( + KeyCode::Char('1'), + KeyModifiers::empty(), + KeyEventKind::Press, + KeyEventState::NUM_LOCK, + ) + ))), ); } From 4417f62e3f60195ec0f9cce2b49b9db5575a0dc0 Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Mon, 1 Aug 2022 00:12:17 -0600 Subject: [PATCH 4/7] Fix docs error --- src/event.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/event.rs b/src/event.rs index c089ac953..e42e97945 100644 --- a/src/event.rs +++ b/src/event.rs @@ -570,12 +570,12 @@ bitflags! { const KEYPAD = 0b0000_0001; /// The Hyper modifier was held for this key event. /// - /// This modifier is uncommon; thus, it is not stored in [`KeyEvent.state`] to avoid + /// This modifier is uncommon; thus, it is not stored in `KeyEvent.state` to avoid /// confusion or failures to match key events. const MODIFIER_HYPER = 0b0000_0010; /// The Meta modifier was held for this key event. /// - /// This modifier is uncommon; thus, it is not stored in [`KeyEvent.state`] to avoid + /// This modifier is uncommon; thus, it is not stored in `KeyEvent.state` to avoid /// confusion or failures to match key events. const MODIFIER_META = 0b0000_0100; /// Caps Lock was enabled for this key event. From 07c181344279983e1b0ebabbbcbbf135dc895c7c Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Mon, 1 Aug 2022 01:00:22 -0600 Subject: [PATCH 5/7] Fix clippy error --- src/event/sys/unix/parse.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/sys/unix/parse.rs b/src/event/sys/unix/parse.rs index 2bcab95dd..85a6d0695 100644 --- a/src/event/sys/unix/parse.rs +++ b/src/event/sys/unix/parse.rs @@ -305,7 +305,7 @@ pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> Result Date: Tue, 2 Aug 2022 23:06:54 -0600 Subject: [PATCH 6/7] Move Hyper/Meta back to modifiers --- src/event.rs | 14 ++----- src/event/sys/unix/parse.rs | 79 +++++++++++++++---------------------- 2 files changed, 34 insertions(+), 59 deletions(-) diff --git a/src/event.rs b/src/event.rs index e42e97945..42411b543 100644 --- a/src/event.rs +++ b/src/event.rs @@ -536,7 +536,7 @@ pub enum MouseButton { bitflags! { /// Represents key modifiers (shift, control, alt, etc.). /// - /// **Note:** `SUPER` can only be read if + /// **Note:** `SUPER`, `HYPER`, and `META` can only be read if /// [`KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES`] has been enabled with /// [`PushKeyboardEnhancementFlags`]. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -545,6 +545,8 @@ bitflags! { const CONTROL = 0b0000_0010; const ALT = 0b0000_0100; const SUPER = 0b0000_1000; + const HYPER = 0b0001_0000; + const META = 0b0010_0000; const NONE = 0b0000_0000; } } @@ -568,16 +570,6 @@ bitflags! { pub struct KeyEventState: u8 { /// The key event origins from the keypad. const KEYPAD = 0b0000_0001; - /// The Hyper modifier was held for this key event. - /// - /// This modifier is uncommon; thus, it is not stored in `KeyEvent.state` to avoid - /// confusion or failures to match key events. - const MODIFIER_HYPER = 0b0000_0010; - /// The Meta modifier was held for this key event. - /// - /// This modifier is uncommon; thus, it is not stored in `KeyEvent.state` to avoid - /// confusion or failures to match key events. - const MODIFIER_META = 0b0000_0100; /// Caps Lock was enabled for this key event. /// /// **Note:** this is set for the initial press of Num Lock itself. diff --git a/src/event/sys/unix/parse.rs b/src/event/sys/unix/parse.rs index 85a6d0695..d96a2f366 100644 --- a/src/event/sys/unix/parse.rs +++ b/src/event/sys/unix/parse.rs @@ -255,18 +255,18 @@ fn parse_modifiers(mask: u8) -> KeyModifiers { if modifier_mask & 8 != 0 { modifiers |= KeyModifiers::SUPER; } + if modifier_mask & 16 != 0 { + modifiers |= KeyModifiers::HYPER; + } + if modifier_mask & 32 != 0 { + modifiers |= KeyModifiers::META; + } modifiers } fn parse_modifiers_to_state(mask: u8) -> KeyEventState { let modifier_mask = mask.saturating_sub(1); let mut state = KeyEventState::empty(); - if modifier_mask & 16 != 0 { - state |= KeyEventState::MODIFIER_HYPER; - } - if modifier_mask & 32 != 0 { - state |= KeyEventState::MODIFIER_META; - } if modifier_mask & 64 != 0 { state |= KeyEventState::CAPS_LOCK; } @@ -458,7 +458,7 @@ pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> Result Result { - state_from_keycode.set(KeyEventState::MODIFIER_HYPER, true) + modifiers.set(KeyModifiers::HYPER, true) } ModifierKeyCode::LeftMeta | ModifierKeyCode::RightMeta => { - state_from_keycode.set(KeyEventState::MODIFIER_META, true) + modifiers.set(KeyModifiers::META, true) } _ => {} } @@ -1227,33 +1227,24 @@ mod tests { ); assert_eq!( parse_csi_u_encoded_key_code(b"\x1B[57450u").unwrap(), - Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind( + Some(InternalEvent::Event(Event::Key(KeyEvent::new( KeyCode::Modifier(ModifierKeyCode::RightSuper), KeyModifiers::SUPER, - KeyEventKind::Press, )))), ); assert_eq!( parse_csi_u_encoded_key_code(b"\x1B[57451u").unwrap(), - Some(InternalEvent::Event(Event::Key( - KeyEvent::new_with_kind_and_state( - KeyCode::Modifier(ModifierKeyCode::RightHyper), - KeyModifiers::NONE, - KeyEventKind::Press, - KeyEventState::MODIFIER_HYPER, - ) - ))), + Some(InternalEvent::Event(Event::Key(KeyEvent::new( + KeyCode::Modifier(ModifierKeyCode::RightHyper), + KeyModifiers::HYPER, + )))), ); assert_eq!( parse_csi_u_encoded_key_code(b"\x1B[57452u").unwrap(), - Some(InternalEvent::Event(Event::Key( - KeyEvent::new_with_kind_and_state( - KeyCode::Modifier(ModifierKeyCode::RightMeta), - KeyModifiers::NONE, - KeyEventKind::Press, - KeyEventState::MODIFIER_META, - ) - ))), + Some(InternalEvent::Event(Event::Key(KeyEvent::new( + KeyCode::Modifier(ModifierKeyCode::RightMeta), + KeyModifiers::META, + )))), ); } @@ -1266,32 +1257,24 @@ mod tests { KeyModifiers::SUPER )))), ); - } - - #[test] - fn test_parse_csi_u_encoded_key_code_with_extra_state() { assert_eq!( parse_csi_u_encoded_key_code(b"\x1B[97;17u").unwrap(), - Some(InternalEvent::Event(Event::Key( - KeyEvent::new_with_kind_and_state( - KeyCode::Char('a'), - KeyModifiers::empty(), - KeyEventKind::Press, - KeyEventState::MODIFIER_HYPER, - ) - ))), + Some(InternalEvent::Event(Event::Key(KeyEvent::new( + KeyCode::Char('a'), + KeyModifiers::HYPER, + )))), ); assert_eq!( - parse_csi_u_encoded_key_code(b"\x1B[97;37u").unwrap(), - Some(InternalEvent::Event(Event::Key( - KeyEvent::new_with_kind_and_state( - KeyCode::Char('a'), - KeyModifiers::CONTROL, - KeyEventKind::Press, - KeyEventState::MODIFIER_META, - ) - ))), + parse_csi_u_encoded_key_code(b"\x1B[97;33u").unwrap(), + Some(InternalEvent::Event(Event::Key(KeyEvent::new( + KeyCode::Char('a'), + KeyModifiers::META, + )))), ); + } + + #[test] + fn test_parse_csi_u_encoded_key_code_with_extra_state() { assert_eq!( parse_csi_u_encoded_key_code(b"\x1B[97;65u").unwrap(), Some(InternalEvent::Event(Event::Key( From 7345feb7a76014f1b919d5b8637cf3a946af8ec9 Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Tue, 2 Aug 2022 23:29:31 -0600 Subject: [PATCH 7/7] Add keyboard enhancement flags to event-read example --- examples/event-read.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/examples/event-read.rs b/examples/event-read.rs index 2a32cefba..549e05a91 100644 --- a/examples/event-read.rs +++ b/examples/event-read.rs @@ -4,7 +4,9 @@ use std::io::stdout; -use crossterm::event::poll; +use crossterm::event::{ + poll, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags, +}; use crossterm::{ cursor::position, event::{ @@ -70,13 +72,27 @@ fn main() -> Result<()> { enable_raw_mode()?; let mut stdout = stdout(); - execute!(stdout, EnableFocusChange, EnableMouseCapture)?; + execute!( + stdout, + EnableFocusChange, + EnableMouseCapture, + PushKeyboardEnhancementFlags( + KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES + | KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES + | KeyboardEnhancementFlags::REPORT_EVENT_TYPES + ) + )?; if let Err(e) = print_events() { println!("Error: {:?}\r", e); } - execute!(stdout, DisableFocusChange, DisableMouseCapture)?; + execute!( + stdout, + PopKeyboardEnhancementFlags, + DisableFocusChange, + DisableMouseCapture + )?; disable_raw_mode() }