diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-01 15:48:22 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-01 15:48:22 +0300 |
| commit | 207be3c771d281baae6e5fa0fb74be9a056e97a2 (patch) | |
| tree | d7b037ecdf629224a048c841d11659efdc23507d /src/input/model.rs | |
| parent | 8a6d697308162874a236c84aac0b0f8c7ac01f83 (diff) | |
refactor: render the shell in the client (#3487)
* feat: add opt-in client-rendered shell
* feat: add client-owned shell mouse controls
* feat: complete client-owned shell chrome
* feat: add client-owned shell settings and notifications
* feat: run client shell custom commands
* feat: render popup terminals in client shell
* feat: add client-owned scrollback and copy mode
* fix: preserve client worktree trust defaults
* feat: render startup diagnostics in client shell
* feat: render onboarding in client shell
* feat: render product announcements in client shell
* feat: render release notes in client shell
* feat: render mobile switcher in client shell
* feat: render kitty graphics in client shell
* fix: preserve client shell lifecycle coherence
* refactor: route client shell commands through endpoint connections
* refactor: make the client-rendered shell the default
* refactor: remove monolithic launch mode
* refactor: complete client-rendered shell cutover
* perf: retain client pane surface updates
* perf: scale retained pane surface updates
* perf: remove remote pane input latency
* test: make client shell checks platform-independent
* fix: prevent client timer starvation
* test: fix client shell platform gates
* test: accept retained surfaces in cross-area checks
* test: make client mode assertions platform-neutral
* fix: badge only outdated integrations
Diffstat (limited to 'src/input/model.rs')
| -rw-r--r-- | src/input/model.rs | 44 |
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 { |
