aboutsummaryrefslogtreecommitdiff
path: root/src/pane
diff options
context:
space:
mode:
Diffstat (limited to 'src/pane')
-rw-r--r--src/pane/osc.rs10
-rw-r--r--src/pane/terminal.rs32
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();