Skip to content

Commit 036cc72

Browse files
committed
feat(tui2): make transcript scrollbar draggable
Support click/drag on the transcript scrollbar track/thumb. Use tui-scrollbar's hit testing and drag interaction state, plus a small pointer-capture flag so dragging doesn't fall through into transcript selection when the view becomes pinned to bottom. Skip scrollbar hit-testing when the scrollbar is auto-hidden at bottom, so the reserved column is not an invisible interactive region. Move the interaction glue out of app.rs into transcript_scrollbar_ui. Return an explicit TranscriptScrollbarMouseHandling enum, and expand docs for reserved column layout and track/thumb theme heuristics.
1 parent b86de4b commit 036cc72

File tree

4 files changed

+509
-9
lines changed

4 files changed

+509
-9
lines changed

codex-rs/tui2/src/app.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ use crate::transcript_copy_ui::TranscriptCopyUi;
2121
use crate::transcript_multi_click::TranscriptMultiClick;
2222
use crate::transcript_scrollbar::render_transcript_scrollbar_if_active;
2323
use crate::transcript_scrollbar::split_transcript_area;
24+
use crate::transcript_scrollbar_ui::TranscriptScrollbarMouseEvent;
25+
use crate::transcript_scrollbar_ui::TranscriptScrollbarMouseHandling;
26+
use crate::transcript_scrollbar_ui::TranscriptScrollbarUi;
2427
use crate::transcript_selection::TRANSCRIPT_GUTTER_COLS;
2528
use crate::transcript_selection::TranscriptSelection;
2629
use crate::transcript_selection::TranscriptSelectionPoint;
@@ -337,6 +340,7 @@ pub(crate) struct App {
337340
transcript_view_top: usize,
338341
transcript_total_lines: usize,
339342
transcript_copy_ui: TranscriptCopyUi,
343+
transcript_scrollbar_ui: TranscriptScrollbarUi,
340344

341345
// Pager overlay state (Transcript or Static like Diff)
342346
pub(crate) overlay: Option<Overlay>,
@@ -502,6 +506,7 @@ impl App {
502506
transcript_view_top: 0,
503507
transcript_total_lines: 0,
504508
transcript_copy_ui: TranscriptCopyUi::new_with_shortcut(copy_selection_shortcut),
509+
transcript_scrollbar_ui: TranscriptScrollbarUi::default(),
505510
overlay: None,
506511
deferred_history_lines: Vec::new(),
507512
has_emitted_history_lines: false,
@@ -866,17 +871,38 @@ impl App {
866871
width,
867872
height: transcript_height,
868873
};
869-
let (transcript_area, _) = split_transcript_area(transcript_full_area);
874+
let (transcript_area, transcript_scrollbar_area) =
875+
split_transcript_area(transcript_full_area);
870876
let base_x = transcript_area.x.saturating_add(TRANSCRIPT_GUTTER_COLS);
871877
let max_x = transcript_area.right().saturating_sub(1);
872878

879+
if matches!(
880+
self.transcript_scrollbar_ui
881+
.handle_mouse_event(TranscriptScrollbarMouseEvent {
882+
tui,
883+
mouse_event,
884+
transcript_area,
885+
scrollbar_area: transcript_scrollbar_area,
886+
transcript_cells: &self.transcript_cells,
887+
transcript_view_cache: &mut self.transcript_view_cache,
888+
transcript_scroll: &mut self.transcript_scroll,
889+
transcript_view_top: &mut self.transcript_view_top,
890+
transcript_total_lines: &mut self.transcript_total_lines,
891+
mouse_scroll_state: &mut self.scroll_state,
892+
}),
893+
TranscriptScrollbarMouseHandling::Handled
894+
) {
895+
return;
896+
}
897+
873898
// Treat the transcript as the only interactive region for transcript selection.
874899
//
875900
// This prevents clicks in the composer/footer from starting or extending a transcript
876901
// selection, while still allowing a left-click outside the transcript to clear an
877902
// existing highlight.
878-
if mouse_event.row < transcript_full_area.y
879-
|| mouse_event.row >= transcript_full_area.bottom()
903+
if !self.transcript_scrollbar_ui.pointer_capture_active()
904+
&& (mouse_event.row < transcript_full_area.y
905+
|| mouse_event.row >= transcript_full_area.bottom())
880906
{
881907
if matches!(
882908
mouse_event.kind,
@@ -2124,6 +2150,7 @@ mod tests {
21242150
transcript_copy_ui: TranscriptCopyUi::new_with_shortcut(
21252151
CopySelectionShortcut::CtrlShiftC,
21262152
),
2153+
transcript_scrollbar_ui: TranscriptScrollbarUi::default(),
21272154
overlay: None,
21282155
deferred_history_lines: Vec::new(),
21292156
has_emitted_history_lines: false,
@@ -2175,6 +2202,7 @@ mod tests {
21752202
transcript_copy_ui: TranscriptCopyUi::new_with_shortcut(
21762203
CopySelectionShortcut::CtrlShiftC,
21772204
),
2205+
transcript_scrollbar_ui: TranscriptScrollbarUi::default(),
21782206
overlay: None,
21792207
deferred_history_lines: Vec::new(),
21802208
has_emitted_history_lines: false,

codex-rs/tui2/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ mod transcript_copy_ui;
8181
mod transcript_multi_click;
8282
mod transcript_render;
8383
mod transcript_scrollbar;
84+
mod transcript_scrollbar_ui;
8485
mod transcript_selection;
8586
mod transcript_view_cache;
8687
mod tui;

0 commit comments

Comments
 (0)