diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-08-01 04:27:50 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-01 04:27:50 +0300 |
| commit | b76adc155d979705a353fd6dc87c702f9dfc6c22 (patch) | |
| tree | f613254e0cfbfd2b4450a6a5f3ee7c0ba8136976 /src/app/input/clipboard.rs | |
| parent | 8d190eddda2c74afa3dc043f8ec8020ffd7b5a94 (diff) | |
fix(input): preserve native key lifecycle across routing (#2142)
refs #2077
Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
Diffstat (limited to 'src/app/input/clipboard.rs')
| -rw-r--r-- | src/app/input/clipboard.rs | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/src/app/input/clipboard.rs b/src/app/input/clipboard.rs index db3fa9f2..62ac1ca9 100644 --- a/src/app/input/clipboard.rs +++ b/src/app/input/clipboard.rs @@ -5,7 +5,9 @@ use crate::{ input::TerminalKey, }; -fn is_retained_selection_copy_key(key: TerminalKey) -> bool { +use super::{ConsumedInputLease, InputLeaseKey}; + +fn is_retained_selection_copy_key(key: &TerminalKey) -> bool { matches!(key.code, KeyCode::Char('c' | 'C')) && matches!(key.modifiers, KeyModifiers::CONTROL | KeyModifiers::SUPER) } @@ -31,7 +33,7 @@ impl App { key: TerminalKey, ) -> bool { if self.state.copy_on_select - || !is_retained_selection_copy_key(key) + || !is_retained_selection_copy_key(&key) || !self .state .selection @@ -46,7 +48,10 @@ impl App { return false; } - self.suppressed_repeat_keys.insert((source_id, key.code)); + self.input_leases.insert_consumed( + InputLeaseKey::new(source_id, &key), + ConsumedInputLease::SuppressRepeats, + ); true } } @@ -132,11 +137,19 @@ mod tests { assert_visible_selection(&app); assert!(app.event_rx.try_recv().is_err()); - let ctrl_c = TerminalKey::new(KeyCode::Char('c'), KeyModifiers::CONTROL); + let ctrl_c = TerminalKey::new(KeyCode::Char('c'), KeyModifiers::CONTROL) + .with_windows_record(crate::input::WindowsKeyRecord { + key_down: true, + repeat_count: 1, + virtual_key_code: 0x43, + virtual_scan_code: 0x2e, + unicode: 'c' as u16, + control_key_state: 0x0008, + }); let source_id = 41; app.route_client_events_from( source_id, - vec![crate::raw_input::RawInputEvent::Key(ctrl_c)], + vec![crate::raw_input::RawInputEvent::Key(ctrl_c.clone())], false, ); @@ -156,29 +169,39 @@ mod tests { app.route_client_events_from( source_id, - vec![crate::raw_input::RawInputEvent::Key( - ctrl_c.with_kind(KeyEventKind::Repeat), - )], + vec![ + crate::raw_input::RawInputEvent::Key(ctrl_c.clone()), + crate::raw_input::RawInputEvent::Key( + ctrl_c.clone().with_kind(KeyEventKind::Repeat), + ), + ], false, ); + assert_eq!(app.input_leases.len(), 1); assert!(app.event_rx.try_recv().is_err()); assert!(input_rx.try_recv().is_err()); app.route_client_events_from( source_id, vec![crate::raw_input::RawInputEvent::Key( - ctrl_c.with_kind(KeyEventKind::Release), + ctrl_c.clone().with_kind(KeyEventKind::Release), )], false, ); + assert!(app.input_leases.is_empty()); app.route_client_events_from( source_id, - vec![crate::raw_input::RawInputEvent::Key(ctrl_c)], + vec![crate::raw_input::RawInputEvent::Key(ctrl_c.clone())], false, ); + let expected = if cfg!(windows) { + b"\x1b[67;46;99;1;8;1_".as_slice() + } else { + b"\x03".as_slice() + }; assert_eq!( input_rx.try_recv().expect("forwarded Ctrl-C").as_ref(), - b"\x03" + expected ); assert!(app.event_rx.try_recv().is_err()); } |
