From 3cb53d7a5d949db1857559d9d5f856e725811655 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 6 Apr 2026 19:07:25 -0400 Subject: [PATCH] simplify main ui event loop Signed-off-by: Kent Overstreet --- src/user/mod.rs | 82 ++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 62 deletions(-) diff --git a/src/user/mod.rs b/src/user/mod.rs index 2d01e0a..b637e7d 100644 --- a/src/user/mod.rs +++ b/src/user/mod.rs @@ -312,29 +312,6 @@ fn is_global_event(event: &ratatui::crossterm::event::Event) -> bool { } } -fn diff_mind_state( - cur: &crate::mind::MindState, - prev: &crate::mind::MindState, - dirty: &mut bool, -) { - if cur.dmn.label() != prev.dmn.label() || cur.dmn_turns != prev.dmn_turns { - *dirty = true; - } - // Input consumed — Mind started a turn with it - if !prev.input.is_empty() && cur.input.is_empty() { - *dirty = true; - } - if cur.turn_active != prev.turn_active { - *dirty = true; - } - if cur.scoring_in_flight != prev.scoring_in_flight { - *dirty = true; - } - if cur.compaction_in_flight != prev.compaction_in_flight { - *dirty = true; - } -} - pub async fn run( mut app: tui::App, mind: &crate::mind::Mind, @@ -384,8 +361,6 @@ pub async fn run( let agent_changed = agent.lock().await.changed.clone(); let mut turn_watch = mind.turn_watch(); - let mut dirty = true; - let mut prev_mind = shared_mind.lock().unwrap().clone(); let mut pending: Vec = Vec::new(); terminal.hide_cursor()?; @@ -417,17 +392,12 @@ pub async fn run( } } - _ = agent_changed.notified() => { - dirty = true; - } + _ = agent_changed.notified() => {} - _ = turn_watch.changed() => { - dirty = true; - } + _ = turn_watch.changed() => {} Some(channels) = channel_rx.recv() => { app.set_channel_status(channels); - dirty = true; } } @@ -439,14 +409,9 @@ pub async fn run( let model = ag.model().to_string(); ag.notify(format!("model: {}", model)); startup_done = true; - dirty = true; } } - { - let cur = shared_mind.lock().unwrap(); - diff_mind_state(&cur, &prev_mind, &mut dirty); - prev_mind = cur.clone(); - } + while let Ok(_notif) = notify_rx.try_recv() { let tx = channel_tx.clone(); tokio::spawn(async move { @@ -457,24 +422,26 @@ pub async fn run( if !pending.is_empty() { idle_state.user_activity(); } - while !pending.is_empty() { + let mut dirty = false; + + while !pending.is_empty() || dirty { let global_pos = pending.iter().position(|e| is_global_event(e)) .unwrap_or(pending.len()); - if global_pos > 0 { - let mut frame = terminal.get_frame(); - let area = frame.area(); - screens[active_screen - 1].tick(&mut frame, area, &pending[..global_pos], &mut app); - drop(frame); - terminal.flush()?; - terminal.swap_buffers(); - terminal.backend_mut().flush()?; - dirty = false; - } + let mut frame = terminal.get_frame(); + let area = frame.area(); + screens[active_screen - 1].tick(&mut frame, area, &pending[..global_pos], &mut app); + drop(frame); + terminal.flush()?; + terminal.swap_buffers(); + terminal.backend_mut().flush()?; + dirty = false; pending = pending.split_off(global_pos); if pending.is_empty() { break; } + dirty = true; + // Global event is first — handle it use ratatui::crossterm::event::{Event, KeyCode, KeyModifiers}; let event = pending.remove(0); @@ -495,21 +462,12 @@ pub async fn run( } } } - Event::Resize(_, _) => { let _ = terminal.clear(); } + Event::Resize(_, _) => { + let _ = terminal.autoresize(); + let _ = terminal.clear(); + } _ => {} } - dirty = true; - } - - if dirty { - let mut frame = terminal.get_frame(); - let area = frame.area(); - screens[active_screen - 1].tick(&mut frame, area, &[], &mut app); - drop(frame); - terminal.flush()?; - terminal.swap_buffers(); - terminal.backend_mut().flush()?; - dirty = false; } if app.should_quit {