From 5a8aefeac98591af9d2fe2e15322899d4619fc56 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Mon, 10 Aug 2026 00:31:57 +0300 Subject: [PATCH] fix: skip unchanged status command renders --- src/app/api.rs | 7 ++++++- src/app/mod.rs | 31 +++++++++++++++++++++++++++++++ src/app/tab_bar_status.rs | 17 ++++++++++------- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/app/api.rs b/src/app/api.rs index 4a2497fc..379369ae 100644 --- a/src/app/api.rs +++ b/src/app/api.rs @@ -64,6 +64,11 @@ impl App { results, cache_updates, } => self.handle_git_status_refreshed(results, cache_updates), + AppEvent::TabBarCommandFinished { + generation, + segment_index, + result, + } => self.handle_tab_bar_command_finished(generation, segment_index, result), ev @ AppEvent::TerminalBell { .. } => { self.handle_internal_event(ev); false @@ -150,7 +155,7 @@ impl App { result, } = ev { - self.handle_tab_bar_command_finished(generation, segment_index, result); + let _ = self.handle_tab_bar_command_finished(generation, segment_index, result); return; } diff --git a/src/app/mod.rs b/src/app/mod.rs index 2e49287c..cca530ce 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -2351,6 +2351,37 @@ mod tests { assert!(!app.git_refresh_in_flight); } + #[test] + fn tab_bar_command_events_render_only_when_visible_output_changes() { + if !crate::platform::status_commands_supported() { + return; + } + + let mut app = test_app(); + app.configure_tab_bar_status( + &[crate::config::TabBarRightEntryConfig::Command { + command: "status".into(), + interval_seconds: 5, + timeout_seconds: 2, + }], + " ", + ); + let generation = app.tab_bar_status_generation; + let event = |generation, output: Option<&str>| AppEvent::TabBarCommandFinished { + generation, + segment_index: 0, + result: Ok(output.map(str::to_string)), + }; + + assert!(!app.handle_internal_event_with_prefix_sync(event(generation, None))); + assert!(app.handle_internal_event_with_prefix_sync(event(generation, Some("ready")))); + assert!(!app.handle_internal_event_with_prefix_sync(event(generation, Some("ready")))); + assert!(!app.handle_internal_event_with_prefix_sync(event( + generation.wrapping_add(1), + Some("stale"), + ))); + } + #[test] fn git_status_event_clears_in_flight_refresh() { let mut app = test_app(); diff --git a/src/app/tab_bar_status.rs b/src/app/tab_bar_status.rs index 3b2f7ecd..54903db6 100644 --- a/src/app/tab_bar_status.rs +++ b/src/app/tab_bar_status.rs @@ -174,16 +174,16 @@ impl App { generation: u64, segment_index: usize, result: Result, String>, - ) { + ) -> bool { if generation != self.tab_bar_status_generation { - return; + return false; } let Some(runtime) = self .tab_bar_commands .iter_mut() .find(|runtime| runtime.segment_index == segment_index) else { - return; + return false; }; runtime.task = None; @@ -194,11 +194,14 @@ impl App { None } }; - if let Some(TabBarStatusSegment::Text(current)) = + let Some(TabBarStatusSegment::Text(current)) = self.state.tab_bar_right.get_mut(segment_index) - { - *current = output; - } + else { + return false; + }; + let changed = *current != output; + *current = output; + changed } }