mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-23 00:01:08 +00:00
+2
-1
@@ -3113,7 +3113,8 @@ impl AppState {
|
||||
let sound = sound_for_toast_kind(kind, suppress_active_tab_notifications)
|
||||
.filter(|_| self.sound.allows(known_agent));
|
||||
let build_toast = || {
|
||||
let workspace_label = self.workspaces[ws_idx].display_name();
|
||||
let workspace_label =
|
||||
self.workspaces[ws_idx].display_name_from_terminals(&self.terminals);
|
||||
let context =
|
||||
notification_context(&self.workspaces[ws_idx], &workspace_label, ws_idx, pane_id);
|
||||
ToastNotification {
|
||||
|
||||
@@ -2412,6 +2412,21 @@ mod tests {
|
||||
assert!(app.state.toast.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unchanged_git_status_drain_has_no_render_impact() {
|
||||
let mut app = test_app();
|
||||
app.git_refresh_in_flight = true;
|
||||
app.event_tx
|
||||
.try_send(AppEvent::GitStatusRefreshed {
|
||||
results: Vec::new(),
|
||||
cache_updates: Vec::new(),
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
assert!(!app.drain_internal_events());
|
||||
assert!(!app.git_refresh_in_flight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn internal_event_drain_limits_work_per_tick() {
|
||||
let mut app = test_app();
|
||||
|
||||
+14
-7
@@ -586,26 +586,33 @@ impl App {
|
||||
|
||||
pub(crate) fn drain_internal_events(&mut self) -> bool {
|
||||
self.drain_internal_events_up_to(super::APP_EVENT_DRAIN_LIMIT)
|
||||
.1
|
||||
}
|
||||
|
||||
pub(crate) fn drain_all_internal_events(&mut self) -> bool {
|
||||
let mut had_event = false;
|
||||
while self.drain_internal_events_up_to(super::APP_EVENT_DRAIN_LIMIT) {
|
||||
had_event = true;
|
||||
let mut changed = false;
|
||||
loop {
|
||||
let (had_event, batch_changed) =
|
||||
self.drain_internal_events_up_to(super::APP_EVENT_DRAIN_LIMIT);
|
||||
changed |= batch_changed;
|
||||
if !had_event {
|
||||
break;
|
||||
}
|
||||
}
|
||||
had_event
|
||||
changed
|
||||
}
|
||||
|
||||
fn drain_internal_events_up_to(&mut self, limit: usize) -> bool {
|
||||
fn drain_internal_events_up_to(&mut self, limit: usize) -> (bool, bool) {
|
||||
let mut had_event = false;
|
||||
let mut changed = false;
|
||||
for _ in 0..limit {
|
||||
let Ok(ev) = self.event_rx.try_recv() else {
|
||||
break;
|
||||
};
|
||||
had_event = true;
|
||||
self.handle_internal_event_with_prefix_sync(ev);
|
||||
changed |= self.handle_internal_event_with_prefix_sync(ev);
|
||||
}
|
||||
had_event
|
||||
(had_event, changed)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -197,12 +197,12 @@ fn workspace_row_height(app: &AppState, ws: &crate::workspace::Workspace, indent
|
||||
let (state, seen) = ws.aggregate_state(&app.terminals);
|
||||
let label = if indented {
|
||||
grouped_child_display_label(
|
||||
&ws.display_name(),
|
||||
&ws.display_name_from_terminals(&app.terminals),
|
||||
ws.branch().as_deref(),
|
||||
ws.custom_name.is_some(),
|
||||
)
|
||||
} else {
|
||||
ws.display_name()
|
||||
ws.display_name_from_terminals(&app.terminals)
|
||||
};
|
||||
let token_values = ws.metadata_tokens.values();
|
||||
tokens::space_rows(
|
||||
|
||||
+46
-11
@@ -1093,16 +1093,31 @@ impl Workspace {
|
||||
.or_else(|| Some(self.identity_cwd.clone()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn display_name(&self) -> String {
|
||||
if let Some(name) = &self.custom_name {
|
||||
return name.clone();
|
||||
}
|
||||
|
||||
if self.cached_identity_cwd == self.identity_cwd {
|
||||
self.cached_auto_label.clone()
|
||||
} else {
|
||||
fallback_label_from_cwd(&self.identity_cwd)
|
||||
self.automatic_display_name_for_cwd(&self.identity_cwd)
|
||||
}
|
||||
|
||||
pub(crate) fn display_name_from_terminals(
|
||||
&self,
|
||||
terminals: &HashMap<TerminalId, TerminalState>,
|
||||
) -> String {
|
||||
if let Some(name) = &self.custom_name {
|
||||
return name.clone();
|
||||
}
|
||||
|
||||
let cwd = self
|
||||
.tabs
|
||||
.first()
|
||||
.and_then(|tab| tab.terminal_id(tab.root_pane))
|
||||
.and_then(|terminal_id| terminals.get(terminal_id))
|
||||
.map(|terminal| &terminal.cwd)
|
||||
.unwrap_or(&self.identity_cwd);
|
||||
self.automatic_display_name_for_cwd(cwd)
|
||||
}
|
||||
|
||||
pub fn display_name_from(
|
||||
@@ -1115,16 +1130,18 @@ impl Workspace {
|
||||
}
|
||||
|
||||
self.resolved_identity_cwd_from(terminals, terminal_runtimes)
|
||||
.map(|cwd| {
|
||||
if cwd == self.cached_identity_cwd {
|
||||
self.cached_auto_label.clone()
|
||||
} else {
|
||||
fallback_label_from_cwd(&cwd)
|
||||
}
|
||||
})
|
||||
.map(|cwd| self.automatic_display_name_for_cwd(&cwd))
|
||||
.unwrap_or_else(|| "workspace".into())
|
||||
}
|
||||
|
||||
fn automatic_display_name_for_cwd(&self, cwd: &std::path::Path) -> String {
|
||||
if cwd == self.cached_identity_cwd {
|
||||
self.cached_auto_label.clone()
|
||||
} else {
|
||||
fallback_label_from_cwd(cwd)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn branch(&self) -> Option<String> {
|
||||
self.cached_git_branch.clone()
|
||||
}
|
||||
@@ -1642,6 +1659,24 @@ mod tests {
|
||||
assert_eq!(ws.display_name(), "cached-repo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn terminal_aware_display_name_uses_latest_admitted_identity_cache() {
|
||||
let mut ws = Workspace::test_new("ignored");
|
||||
let root_pane = ws.tabs[0].root_pane;
|
||||
let terminal_id = ws.tabs[0].terminal_id(root_pane).unwrap().clone();
|
||||
ws.custom_name = None;
|
||||
ws.identity_cwd = PathBuf::from("/old/workspace");
|
||||
ws.cached_identity_cwd = PathBuf::from("/new/repo/deep");
|
||||
ws.cached_auto_label = "repo".into();
|
||||
let terminals = HashMap::from([(
|
||||
terminal_id.clone(),
|
||||
TerminalState::new(terminal_id, PathBuf::from("/new/repo/deep")),
|
||||
)]);
|
||||
|
||||
assert_eq!(ws.display_name_from_terminals(&terminals), "repo");
|
||||
assert_eq!(ws.display_name(), "workspace");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_identity_follows_first_tab_root_pane_cwd() {
|
||||
let mut ws = Workspace::test_new("ignored");
|
||||
|
||||
Reference in New Issue
Block a user