aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-07 21:12:44 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-07 21:13:34 +0300
commit0a684b4130e7e82074831a7af8db5f1af8fed84d (patch)
treeb0537fe0a8c494ce399f89a1c5399e3c048ed2dc /src
parent1e1d06328cc9aefa354b7ce463f9f2d254395662 (diff)
fix: clear done status on repeated pane focus
Diffstat (limited to 'src')
-rw-r--r--src/app/agents.rs1
-rw-r--r--src/app/api/agents.rs64
-rw-r--r--src/app/api/panes.rs35
3 files changed, 100 insertions, 0 deletions
diff --git a/src/app/agents.rs b/src/app/agents.rs
index 0a03901d..bec375b9 100644
--- a/src/app/agents.rs
+++ b/src/app/agents.rs
@@ -38,6 +38,7 @@ impl App {
let resolved = self.resolve_terminal_target(target)?;
self.state
.focus_pane_in_workspace(resolved.ws_idx, resolved.pane_id);
+ self.state.mark_active_tab_seen();
self.state.settle_terminal_mode_after_focus();
self.agent_info(resolved.ws_idx, resolved.pane_id)
.ok_or_else(|| TerminalTargetError::NotFound {
diff --git a/src/app/api/agents.rs b/src/app/api/agents.rs
index 7293823f..b66924ec 100644
--- a/src/app/api/agents.rs
+++ b/src/app/api/agents.rs
@@ -202,3 +202,67 @@ fn agent_not_found(id: String, target: &str) -> String {
format!("agent target {target} not found"),
)
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::{
+ api::schema::{AgentStatus, SuccessResponse},
+ app::Mode,
+ config::Config,
+ detect::{Agent, AgentState},
+ workspace::Workspace,
+ };
+
+ fn app_with_agent() -> App {
+ let (_api_tx, api_rx) = tokio::sync::mpsc::unbounded_channel();
+ let mut app = App::new(
+ &Config::default(),
+ true,
+ None,
+ api_rx,
+ crate::api::EventHub::default(),
+ );
+ app.state.workspaces = vec![Workspace::test_new("agent")];
+ app.state.ensure_test_terminals();
+ app.state.active = Some(0);
+ app.state.selected = 0;
+ app.state.mode = Mode::Terminal;
+ app
+ }
+
+ #[test]
+ fn agent_focus_marks_already_focused_done_agent_seen() {
+ let mut app = app_with_agent();
+ app.state.outer_terminal_focus = Some(false);
+
+ let pane_id = app.state.workspaces[0].tabs[0].root_pane;
+ let terminal_id = app.state.workspaces[0].tabs[0].panes[&pane_id]
+ .attached_terminal_id
+ .clone();
+ app.state
+ .terminals
+ .get_mut(&terminal_id)
+ .unwrap()
+ .set_detected_state(Some(Agent::Pi), AgentState::Idle);
+ app.state.workspaces[0].tabs[0]
+ .panes
+ .get_mut(&pane_id)
+ .unwrap()
+ .seen = false;
+ app.state.workspaces[0].tabs[0].layout.focus_pane(pane_id);
+
+ let response = app.handle_agent_focus(
+ "req".into(),
+ AgentTarget {
+ target: "pi".into(),
+ },
+ );
+
+ let success: SuccessResponse = serde_json::from_str(&response).unwrap();
+ let ResponseResult::AgentInfo { agent } = success.result else {
+ panic!("expected agent info response");
+ };
+ assert_eq!(agent.agent_status, AgentStatus::Idle);
+ }
+}
diff --git a/src/app/api/panes.rs b/src/app/api/panes.rs
index fdda8750..cf7b594d 100644
--- a/src/app/api/panes.rs
+++ b/src/app/api/panes.rs
@@ -166,6 +166,7 @@ impl App {
};
self.state.focus_pane_in_workspace(ws_idx, pane_id);
+ self.state.mark_active_tab_seen();
self.state.settle_terminal_mode_after_focus();
let Some(pane) = self.pane_info(ws_idx, pane_id) else {
@@ -3505,6 +3506,40 @@ mod tests {
}
#[test]
+ fn api_pane_focus_marks_already_focused_done_pane_seen() {
+ let mut app = app_with_linked_worktree();
+ app.state.active = Some(0);
+ app.state.selected = 0;
+ app.state.outer_terminal_focus = Some(false);
+
+ let pane_id = app.state.workspaces[0].tabs[0].root_pane;
+ let terminal_id = app.state.workspaces[0].tabs[0].panes[&pane_id]
+ .attached_terminal_id
+ .clone();
+ app.state.terminals.get_mut(&terminal_id).unwrap().state = crate::detect::AgentState::Idle;
+ app.state.workspaces[0].tabs[0]
+ .panes
+ .get_mut(&pane_id)
+ .unwrap()
+ .seen = false;
+ app.state.workspaces[0].tabs[0].layout.focus_pane(pane_id);
+
+ let public_pane_id = app.public_pane_id(0, pane_id).unwrap();
+ let response = app.handle_pane_focus(
+ "req".into(),
+ PaneTarget {
+ pane_id: public_pane_id,
+ },
+ );
+
+ let success: SuccessResponse = serde_json::from_str(&response).unwrap();
+ let ResponseResult::PaneInfo { pane } = success.result else {
+ panic!("expected pane info response");
+ };
+ assert_eq!(pane.agent_status, crate::api::schema::AgentStatus::Idle);
+ }
+
+ #[test]
fn api_pane_focus_rejects_invalid_pane_id() {
let mut app = app_with_linked_worktree();