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/selection.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/selection.rs')
| -rw-r--r-- | src/selection.rs | 64 |
1 files changed, 24 insertions, 40 deletions
diff --git a/src/selection.rs b/src/selection.rs index 08af95f5..7290b8f0 100644 --- a/src/selection.rs +++ b/src/selection.rs @@ -32,9 +32,9 @@ enum Phase { /// A text selection within a terminal pane. #[derive(Debug, Clone)] -pub struct Selection { +pub struct Selection<P = PaneId> { /// Which pane the selection belongs to. - pub pane_id: PaneId, + pub pane_id: P, /// Anchor position in screen-buffer coordinates (row, col). anchor: (u32, u16), /// Current/final position in screen-buffer coordinates (row, col). @@ -43,15 +43,10 @@ pub struct Selection { phase: Phase, } -impl Selection { +impl<P> Selection<P> { /// Start a potential selection. This records the anchor but doesn't /// make anything visible yet — the user might just be clicking. - pub fn anchor( - pane_id: PaneId, - viewport_row: u16, - col: u16, - metrics: Option<ScrollMetrics>, - ) -> Self { + pub fn anchor(pane_id: P, viewport_row: u16, col: u16, metrics: Option<ScrollMetrics>) -> Self { let anchor = (absolute_row_for_viewport_row(viewport_row, metrics), col); Self { pane_id, @@ -61,29 +56,25 @@ impl Selection { } } - /// Create an active selection from an explicit viewport-row range. - pub(crate) fn range( - pane_id: PaneId, - viewport_row: u16, - start_col: u16, - end_col: u16, - metrics: Option<ScrollMetrics>, - ) -> Self { - let row = absolute_row_for_viewport_row(viewport_row, metrics); + pub(crate) fn absolute_anchor(pane_id: P, anchor: (u32, u16)) -> Self { + Self { + pane_id, + anchor, + cursor: anchor, + phase: Phase::Anchored, + } + } + + pub(crate) fn absolute_range(pane_id: P, anchor: (u32, u16), cursor: (u32, u16)) -> Self { Self { pane_id, - anchor: (row, start_col), - cursor: (row, end_col), + anchor, + cursor, phase: Phase::Dragging, } } - pub(crate) fn line_range( - pane_id: PaneId, - anchor_row: u32, - cursor_row: u32, - end_col: u16, - ) -> Self { + pub(crate) fn line_range(pane_id: P, anchor_row: u32, cursor_row: u32, end_col: u16) -> Self { let (anchor_col, cursor_col) = if anchor_row <= cursor_row { (0, end_col) } else { @@ -97,13 +88,6 @@ impl Selection { } } - pub(crate) fn absolute_row_for_viewport( - viewport_row: u16, - metrics: Option<ScrollMetrics>, - ) -> u32 { - absolute_row_for_viewport_row(viewport_row, metrics) - } - /// Convert the anchor's absolute row and pane-relative column back to /// screen coordinates. Adds the pane origin before clamping so the /// returned (screen_row, screen_col) can be compared directly against @@ -160,16 +144,12 @@ impl Selection { } /// Whether this selection was already finalized. + #[cfg(test)] pub fn is_finalized(&self) -> bool { self.phase == Phase::Done } /// Whether the user just clicked without dragging (not a selection). - pub fn was_just_click(&self) -> bool { - self.phase == Phase::Anchored - } - - /// Whether the user just clicked without dragging (not a selection). pub fn is_just_click(&self) -> bool { self.phase == Phase::Anchored } @@ -240,6 +220,10 @@ fn viewport_top_row(metrics: Option<ScrollMetrics>) -> u32 { .unwrap_or(0) as u32 } +pub(crate) fn absolute_row_for_viewport(viewport_row: u16, metrics: Option<ScrollMetrics>) -> u32 { + absolute_row_for_viewport_row(viewport_row, metrics) +} + fn absolute_row_for_viewport_row(viewport_row: u16, metrics: Option<ScrollMetrics>) -> u32 { viewport_top_row(metrics) + u32::from(viewport_row) } @@ -485,7 +469,7 @@ mod tests { #[test] fn click_without_drag() { let mut sel = Selection::anchor(PaneId::from_raw(0), 5, 10, None); - assert!(sel.was_just_click()); + assert!(sel.is_just_click()); let copied = sel.finish(); assert!(!copied); } @@ -495,7 +479,7 @@ mod tests { let mut sel = Selection::anchor(PaneId::from_raw(0), 5, 10, None); sel.drag(20, 7, Rect::new(10, 5, 80, 24), None); assert!(sel.is_visible()); - assert!(!sel.was_just_click()); + assert!(!sel.is_just_click()); let copied = sel.finish(); assert!(copied); } |
