Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions journal/2026-03-18/fix_scroll_lag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Fix result scrolling lag

- Investigated the result-pane `j`/`k` navigation lag in the TUI.
- Root cause: the UI thread only handled one input event per 100ms render tick and used a bounded UI action channel, which could block on repeated key presses.
- Fix approach: switch the UI action channel to unbounded, increase the UI refresh cadence, and drain all pending crossterm events each frame so held/repeated keys are processed promptly.
10 changes: 5 additions & 5 deletions src/ui/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
time::Duration,
};

use crossbeam_channel::{bounded, select, tick};
use crossbeam_channel::{select, tick, unbounded};
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers, poll};
use log::{debug, error};
use ratatui::{
Expand All @@ -24,7 +24,7 @@ pub struct Manager {

impl Manager {
pub fn new() -> (Manager, crossbeam_channel::Receiver<state::action::Ui>) {
let (tx, rx) = bounded::<state::action::Ui>(1);
let (tx, rx) = unbounded::<state::action::Ui>();

(Manager { action_tx: tx }, rx)
}
Expand All @@ -34,7 +34,7 @@ impl Manager {
pub fn run(mut self, state: Arc<RwLock<state::state::State>>) -> thread::JoinHandle<()> {
thread::spawn(move || {
let mut terminal = setup_terminal();
let ticker = tick(Duration::from_millis(100));
let ticker = tick(Duration::from_millis(16));

loop {
select! {
Expand All @@ -46,8 +46,8 @@ impl Manager {
}

terminal.draw(|frame| self.render(frame, &state)).unwrap();
if poll(Duration::from_secs(0)).unwrap() {
self.handle_crossterm_events().unwrap()
while poll(Duration::from_secs(0)).unwrap() {
self.handle_crossterm_events().unwrap();
}
}
}
Expand Down