aboutsummaryrefslogtreecommitdiff
path: root/src/input/model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/model.rs')
-rw-r--r--src/input/model.rs44
1 files changed, 34 insertions, 10 deletions
diff --git a/src/input/model.rs b/src/input/model.rs
index cada5506..e45ef378 100644
--- a/src/input/model.rs
+++ b/src/input/model.rs
@@ -3,6 +3,7 @@ use crossterm::event::KeyboardEnhancementFlags;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use serde::{Deserialize, Serialize};
+#[cfg(any(windows, test))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct WindowsKeyRecord {
pub key_down: bool,
@@ -32,11 +33,13 @@ impl TextCommit {
}
}
+#[cfg(any(windows, test))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PhysicalKeyId(u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum KeyIdentity {
+ #[cfg(any(windows, test))]
Physical(PhysicalKeyId),
Semantic(KeyCode),
}
@@ -47,12 +50,14 @@ pub(crate) enum KeySource {
Vt {
bytes: Vec<u8>,
},
+ #[cfg(any(windows, test))]
WindowsConsole {
record: WindowsKeyRecord,
physical_key: Option<PhysicalKeyId>,
},
}
+#[cfg(any(windows, test))]
impl WindowsKeyRecord {
fn physical_key_id(self) -> Option<PhysicalKeyId> {
const ENHANCED_KEY: u32 = 0x0100;
@@ -73,6 +78,7 @@ pub struct TerminalKey {
pub repeat_count: u16,
pub shifted_codepoint: Option<u32>,
pub generated_text: Option<String>,
+ physical_identity_hint: bool,
source: KeySource,
}
@@ -85,6 +91,7 @@ impl TerminalKey {
repeat_count: 1,
shifted_codepoint: None,
generated_text: None,
+ physical_identity_hint: false,
source: KeySource::Synthesized,
}
}
@@ -112,7 +119,6 @@ impl TerminalKey {
self
}
- #[allow(dead_code)] // Reserved for the upcoming raw input parser to preserve shifted/base key pairs.
pub fn with_shifted_codepoint(mut self, shifted_codepoint: u32) -> Self {
self.shifted_codepoint = Some(shifted_codepoint);
self
@@ -132,19 +138,27 @@ impl TerminalKey {
self
}
+ #[cfg(any(windows, test))]
pub fn with_windows_record(mut self, record: WindowsKeyRecord) -> Self {
self.repeat_count = if self.kind == crossterm::event::KeyEventKind::Release {
1
} else {
record.repeat_count.max(1)
};
+ let physical_key = record.physical_key_id();
+ self.physical_identity_hint = physical_key.is_some();
self.source = KeySource::WindowsConsole {
- physical_key: record.physical_key_id(),
+ physical_key,
record,
};
self
}
+ pub(crate) fn with_physical_identity_hint(mut self, physical: bool) -> Self {
+ self.physical_identity_hint = physical;
+ self
+ }
+
#[cfg(any(windows, test))]
pub(crate) fn vt_bytes(&self) -> Option<&[u8]> {
match &self.source {
@@ -163,26 +177,36 @@ impl TerminalKey {
pub(crate) fn identity(&self) -> KeyIdentity {
match self.source {
+ #[cfg(any(windows, test))]
KeySource::WindowsConsole {
physical_key: Some(physical_key),
..
} => KeyIdentity::Physical(physical_key),
+ #[cfg(any(windows, test))]
KeySource::WindowsConsole {
physical_key: None, ..
- }
- | KeySource::Synthesized
- | KeySource::Vt { .. } => KeyIdentity::Semantic(self.code),
+ } => KeyIdentity::Semantic(self.code),
+ KeySource::Synthesized | KeySource::Vt { .. } => KeyIdentity::Semantic(self.code),
}
}
pub(crate) fn has_physical_identity(&self) -> bool {
- matches!(
- self.source,
+ self.physical_identity_hint || self.physical_key_id().is_some()
+ }
+
+ pub(crate) fn physical_key_id(&self) -> Option<u32> {
+ match &self.source {
+ #[cfg(any(windows, test))]
KeySource::WindowsConsole {
- physical_key: Some(_),
+ physical_key: Some(PhysicalKeyId(id)),
..
- }
- )
+ } => Some(*id),
+ #[cfg(any(windows, test))]
+ KeySource::WindowsConsole {
+ physical_key: None, ..
+ } => None,
+ KeySource::Synthesized | KeySource::Vt { .. } => None,
+ }
}
pub fn with_text_commit(mut self) -> Self {