diff options
Diffstat (limited to 'src/pane')
| -rw-r--r-- | src/pane/osc.rs | 10 | ||||
| -rw-r--r-- | src/pane/terminal.rs | 32 |
2 files changed, 38 insertions, 4 deletions
diff --git a/src/pane/osc.rs b/src/pane/osc.rs index 16ee8fee..a281af77 100644 --- a/src/pane/osc.rs +++ b/src/pane/osc.rs @@ -464,13 +464,14 @@ pub(super) struct AgentOscStateTracker { } impl AgentOscStateTracker { - pub(super) fn observe(&mut self, bytes: &[u8]) { + pub(super) fn observe(&mut self, bytes: &[u8]) -> bool { let (collector, latest_title, terminal_title, latest_progress) = ( &mut self.collector, &mut self.latest_title, &mut self.terminal_title, &mut self.latest_progress, ); + let mut terminal_title_changed = false; collector.observe(bytes, |body| { let Some((command, payload)) = parse_agent_osc_body(body) else { return; @@ -478,8 +479,10 @@ impl AgentOscStateTracker { match command { b"0" | b"2" => { let title = sanitize_agent_osc_string(payload, AGENT_OSC_MAX_CHARS); - *terminal_title = (!title.is_empty()).then_some(title.clone()); - *latest_title = (!title.is_empty()).then_some(title); + let title = (!title.is_empty()).then_some(title); + terminal_title_changed |= *terminal_title != title; + *terminal_title = title.clone(); + *latest_title = title; } b"9" => { *latest_progress = @@ -488,6 +491,7 @@ impl AgentOscStateTracker { _ => {} } }); + terminal_title_changed } pub(super) fn terminal_title(&self) -> Option<&str> { diff --git a/src/pane/terminal.rs b/src/pane/terminal.rs index 9575ad6f..3524df21 100644 --- a/src/pane/terminal.rs +++ b/src/pane/terminal.rs @@ -146,6 +146,7 @@ impl InputState { pub(crate) struct ProcessBytesResult { pub request_render: bool, pub render_delay: Option<Duration>, + pub terminal_title_changed: bool, pub terminal_bells: u16, pub clipboard_writes: Vec<Vec<u8>>, pub reported_cwd: Option<std::path::PathBuf>, @@ -1201,6 +1202,7 @@ impl GhosttyPaneTerminal { return ProcessBytesResult { request_render: false, render_delay: None, + terminal_title_changed: false, terminal_bells: 0, clipboard_writes: Vec::new(), reported_cwd: None, @@ -1233,7 +1235,7 @@ impl GhosttyPaneTerminal { "agent OSC evidence observed" ); } - core.agent_osc_state.observe(bytes); + let terminal_title_changed = core.agent_osc_state.observe(bytes); let alternate_screen = core .terminal @@ -1335,6 +1337,7 @@ impl GhosttyPaneTerminal { ProcessBytesResult { request_render, render_delay, + terminal_title_changed, terminal_bells, clipboard_writes, reported_cwd, @@ -3777,6 +3780,33 @@ mod tests { } #[test] + fn process_pty_bytes_reports_only_completed_title_changes() { + let (tx, _rx) = mpsc::channel(4); + let terminal = crate::ghostty::Terminal::new(80, 24, 100).unwrap(); + let pane = GhosttyPaneTerminal::new(terminal, tx.clone()).unwrap(); + let pane_id = PaneId::from_raw(1); + + assert!( + !pane + .process_pty_bytes(pane_id, 0, b"\x1b]0;buil", &tx) + .terminal_title_changed + ); + assert!( + pane.process_pty_bytes(pane_id, 0, b"ding\x07", &tx) + .terminal_title_changed + ); + assert!( + !pane + .process_pty_bytes(pane_id, 0, b"\x1b]2;building\x07", &tx) + .terminal_title_changed + ); + assert!( + pane.process_pty_bytes(pane_id, 0, b"\x1b]2;done\x07", &tx) + .terminal_title_changed + ); + } + + #[test] fn process_pty_bytes_surfaces_clipboard_writes_without_other_results() { let (tx, _rx) = mpsc::channel(4); let terminal = crate::ghostty::Terminal::new(80, 24, 100).unwrap(); |
