fix: remove pty taint from agent detection
This commit is contained in:
parent
9e0dd9412f
commit
0efd8eaad1
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
### Fixed
|
||||
- Agent state detection for non-authoritative agents now comes from screen manifests instead of PTY-first semantic arbitration, so terminal output activity no longer publishes `working`, vetoes visible blockers, or decides idle fallback.
|
||||
- Removed the remaining PTY input-taint debounce from agent detection, so user input, pane resizes, and redraw nudges no longer delay screen/OSC manifest state updates.
|
||||
- Numeric keypad keys that send VT100 application-keypad escape sequences now enter their digits and operators instead of being dropped. (#493)
|
||||
- Codex panes now stay marked working when the live status header uses reasoning-summary text such as `Investigating code output` instead of the literal `Working` label. (#501)
|
||||
- Native pane URL clicks now use Cmd-click on macOS and Ctrl-click on other platforms.
|
||||
|
|
|
|||
216
src/pane.rs
216
src/pane.rs
|
|
@ -32,12 +32,11 @@ mod terminal;
|
|||
mod xtgettcap;
|
||||
|
||||
use self::agent_detection::{
|
||||
agent_caused_pty_activity_active, baseline_pty_causality, decide_detection_screen_read,
|
||||
decide_screen_detection_publish, detection_update_for_publish_with_osc,
|
||||
handle_skipped_detection_update, observe_pty_output_activity, DetectionPublishDecision,
|
||||
DetectionScreenReadDecision, DetectionScreenReadInput, PendingIdleConfirmation,
|
||||
PendingWorkingConfirmation, PostTaintWorkingLease, PtyCausalityTracker,
|
||||
ScreenDetectionPublishInput, AGENT_PENDING_IDLE_RECHECK, AGENT_STARTUP_GRACE_WINDOW,
|
||||
decide_detection_screen_read, decide_screen_detection_publish,
|
||||
detection_update_for_publish_with_osc, mark_detection_content_changed,
|
||||
observe_detection_content_change, DetectionPublishDecision, DetectionScreenReadDecision,
|
||||
DetectionScreenReadInput, PendingIdleConfirmation, ScreenDetectionPublishInput,
|
||||
AGENT_PENDING_IDLE_RECHECK, AGENT_STARTUP_GRACE_WINDOW,
|
||||
};
|
||||
use self::terminal::{GhosttyPaneTerminal, PaneTerminal};
|
||||
pub(crate) use self::terminal::{TerminalDirtyPatch, TerminalDirtyPatchOutcome};
|
||||
|
|
@ -384,8 +383,7 @@ fn spawn_basic_detection_task(
|
|||
pane_id: PaneId,
|
||||
child_pid: Arc<AtomicU32>,
|
||||
terminal: Arc<PaneTerminal>,
|
||||
pty_output_seq: Arc<AtomicU64>,
|
||||
input_write_seq: Arc<AtomicU64>,
|
||||
detection_content_seq: Arc<AtomicU64>,
|
||||
full_lifecycle_authority_active: Arc<AtomicBool>,
|
||||
state_events: mpsc::Sender<AppEvent>,
|
||||
) -> (
|
||||
|
|
@ -414,18 +412,12 @@ fn spawn_basic_detection_task(
|
|||
let mut foreground_shell_exit_reported = false;
|
||||
let mut release_was_active = false;
|
||||
let mut last_detection_text = String::new();
|
||||
let mut last_screen_scan_pty_output_seq = None;
|
||||
let mut pty_causality = PtyCausalityTracker::default();
|
||||
let mut last_screen_scan_detection_content_seq = None;
|
||||
let mut agent_startup_grace_until = None;
|
||||
let mut pending_idle = PendingIdleConfirmation::default();
|
||||
let mut pending_working = PendingWorkingConfirmation::default();
|
||||
let mut post_taint_working = PostTaintWorkingLease::default();
|
||||
|
||||
loop {
|
||||
let now_for_sleep = std::time::Instant::now();
|
||||
let sleep_duration = if pending_working.active() {
|
||||
pending_working.recheck_delay(now_for_sleep)
|
||||
} else if pending_idle.active() {
|
||||
let sleep_duration = if pending_idle.active() {
|
||||
AGENT_PENDING_IDLE_RECHECK
|
||||
} else {
|
||||
std::time::Duration::from_millis(300)
|
||||
|
|
@ -448,12 +440,9 @@ fn spawn_basic_detection_task(
|
|||
foreground_shell_exit_reported = false;
|
||||
release_was_active = false;
|
||||
last_detection_text.clear();
|
||||
last_screen_scan_pty_output_seq = None;
|
||||
pty_causality = PtyCausalityTracker::default();
|
||||
last_screen_scan_detection_content_seq = None;
|
||||
agent_startup_grace_until = None;
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -541,19 +530,12 @@ fn spawn_basic_detection_task(
|
|||
agent_changed = previous_agent != agent;
|
||||
if agent_changed {
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
last_screen_scan_pty_output_seq = None;
|
||||
last_screen_scan_detection_content_seq = None;
|
||||
// A new foreground agent must not inherit OSC
|
||||
// title/progress evidence from the previous process.
|
||||
terminal.clear_agent_osc_state();
|
||||
if agent.is_some() {
|
||||
agent_startup_grace_until = Some(now + AGENT_STARTUP_GRACE_WINDOW);
|
||||
baseline_pty_causality(
|
||||
&mut pty_causality,
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq.load(Ordering::Relaxed),
|
||||
);
|
||||
state = AgentState::Idle;
|
||||
last_visible_idle = true;
|
||||
last_visible_blocker = false;
|
||||
|
|
@ -583,8 +565,6 @@ fn spawn_basic_detection_task(
|
|||
|
||||
if full_lifecycle_authority_active.load(Ordering::Acquire) && !process_exited {
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -592,36 +572,20 @@ fn spawn_basic_detection_task(
|
|||
if process_exited {
|
||||
agent_startup_grace_until = None;
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
} else {
|
||||
if now < until {
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
continue;
|
||||
}
|
||||
baseline_pty_causality(
|
||||
&mut pty_causality,
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq.load(Ordering::Relaxed),
|
||||
);
|
||||
agent_startup_grace_until = None;
|
||||
last_screen_scan_pty_output_seq = None;
|
||||
last_screen_scan_detection_content_seq = None;
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let pty_activity = if agent.is_some() {
|
||||
Some(agent_caused_pty_activity_active(
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq.load(Ordering::Relaxed),
|
||||
&mut pty_causality,
|
||||
now,
|
||||
))
|
||||
let current_detection_content_seq = if agent.is_some() {
|
||||
Some(detection_content_seq.load(Ordering::Relaxed))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
@ -629,33 +593,21 @@ fn spawn_basic_detection_task(
|
|||
state,
|
||||
agent,
|
||||
pending_idle_active: pending_idle.active(),
|
||||
pending_working_active: pending_working.active(),
|
||||
post_taint_working_active: post_taint_working.active(),
|
||||
agent_changed,
|
||||
process_exited,
|
||||
pty_activity,
|
||||
last_screen_scan_pty_output_seq,
|
||||
current_detection_content_seq,
|
||||
last_screen_scan_detection_content_seq,
|
||||
}) {
|
||||
DetectionScreenReadDecision::Read => {}
|
||||
DetectionScreenReadDecision::Skip => continue,
|
||||
}
|
||||
|
||||
let content = terminal.detection_text();
|
||||
last_screen_scan_pty_output_seq = pty_activity.map(|signal| signal.output_seq);
|
||||
last_screen_scan_detection_content_seq = current_detection_content_seq;
|
||||
let content_changed = content != last_detection_text;
|
||||
last_detection_text.clone_from(&content);
|
||||
if !process_exited && crate::detect::should_skip_state_update(agent, &content) {
|
||||
handle_skipped_detection_update(
|
||||
state,
|
||||
pty_activity,
|
||||
&mut post_taint_working,
|
||||
&mut pty_causality,
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq.load(Ordering::Relaxed),
|
||||
now,
|
||||
);
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
continue;
|
||||
}
|
||||
sync_content_change_acquisition(
|
||||
|
|
@ -677,17 +629,7 @@ fn spawn_basic_detection_task(
|
|||
&osc_progress,
|
||||
process_exited,
|
||||
) else {
|
||||
handle_skipped_detection_update(
|
||||
state,
|
||||
pty_activity,
|
||||
&mut post_taint_working,
|
||||
&mut pty_causality,
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq.load(Ordering::Relaxed),
|
||||
now,
|
||||
);
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
continue;
|
||||
};
|
||||
match decide_screen_detection_publish(
|
||||
|
|
@ -700,12 +642,9 @@ fn spawn_basic_detection_task(
|
|||
last_visible_signal_refresh,
|
||||
process_exited,
|
||||
agent_changed,
|
||||
pty_activity,
|
||||
now,
|
||||
},
|
||||
&mut pending_idle,
|
||||
&mut pending_working,
|
||||
&mut post_taint_working,
|
||||
) {
|
||||
DetectionPublishDecision::NoPublish => {}
|
||||
DetectionPublishDecision::Publish {
|
||||
|
|
@ -807,7 +746,7 @@ pub struct PaneRuntime {
|
|||
reported_cwd: Arc<Mutex<Option<std::path::PathBuf>>>,
|
||||
child_wait_completed: Option<Arc<AtomicBool>>,
|
||||
kitty_keyboard_flags: Arc<AtomicU16>,
|
||||
input_write_seq: Arc<AtomicU64>,
|
||||
detection_content_seq: Arc<AtomicU64>,
|
||||
full_lifecycle_authority_active: Arc<AtomicBool>,
|
||||
detect_reset_notify: Arc<Notify>,
|
||||
pending_release: Arc<Mutex<Option<PendingAgentRelease>>>,
|
||||
|
|
@ -1551,25 +1490,24 @@ impl PaneRuntime {
|
|||
let child_pid = Arc::new(AtomicU32::new(child_pid));
|
||||
let reported_cwd = Arc::new(Mutex::new(None));
|
||||
let kitty_keyboard_flags = Arc::new(AtomicU16::new(keyboard_protocol_flags));
|
||||
let input_write_seq = Arc::new(AtomicU64::new(0));
|
||||
let pty_output_seq = Arc::new(AtomicU64::new(0));
|
||||
let detection_content_seq = Arc::new(AtomicU64::new(0));
|
||||
|
||||
let io = {
|
||||
let terminal = terminal.clone();
|
||||
let response_writer = response_tx.clone();
|
||||
let render_notify = render_notify.clone();
|
||||
let render_dirty = render_dirty.clone();
|
||||
let pty_output_seq = pty_output_seq.clone();
|
||||
let detection_content_seq = detection_content_seq.clone();
|
||||
let child_pid = child_pid.clone();
|
||||
let read_events = events.clone();
|
||||
let reported_cwd = reported_cwd.clone();
|
||||
let rt = tokio::runtime::Handle::current();
|
||||
let delay_rt = rt.clone();
|
||||
let on_read = Box::new(move |bytes: &[u8]| {
|
||||
observe_pty_output_activity(bytes, &pty_output_seq);
|
||||
let shell_pid = child_pid.load(Ordering::Acquire);
|
||||
let result =
|
||||
terminal.process_pty_bytes(pane_id, shell_pid, bytes, &response_writer);
|
||||
observe_detection_content_change(bytes, &detection_content_seq);
|
||||
if result.request_render && !render_dirty.swap(true, Ordering::AcqRel) {
|
||||
render_notify.notify_one();
|
||||
}
|
||||
|
|
@ -1618,8 +1556,7 @@ impl PaneRuntime {
|
|||
pane_id,
|
||||
child_pid.clone(),
|
||||
terminal.clone(),
|
||||
pty_output_seq,
|
||||
input_write_seq.clone(),
|
||||
detection_content_seq.clone(),
|
||||
full_lifecycle_authority_active.clone(),
|
||||
events,
|
||||
);
|
||||
|
|
@ -1633,7 +1570,7 @@ impl PaneRuntime {
|
|||
reported_cwd,
|
||||
child_wait_completed: None,
|
||||
kitty_keyboard_flags,
|
||||
input_write_seq,
|
||||
detection_content_seq,
|
||||
full_lifecycle_authority_active,
|
||||
detect_reset_notify,
|
||||
pending_release,
|
||||
|
|
@ -1683,8 +1620,7 @@ impl PaneRuntime {
|
|||
let child_pid = Arc::new(AtomicU32::new(0));
|
||||
let reported_cwd = Arc::new(Mutex::new(None));
|
||||
let child_wait_completed = Arc::new(AtomicBool::new(false));
|
||||
let input_write_seq = Arc::new(AtomicU64::new(0));
|
||||
let pty_output_seq = Arc::new(AtomicU64::new(0));
|
||||
let detection_content_seq = Arc::new(AtomicU64::new(0));
|
||||
let full_lifecycle_authority_active = Arc::new(AtomicBool::new(false));
|
||||
{
|
||||
let child_pid = child_pid.clone();
|
||||
|
|
@ -1717,16 +1653,16 @@ impl PaneRuntime {
|
|||
let response_writer = response_tx.clone();
|
||||
let render_notify = render_notify.clone();
|
||||
let render_dirty = render_dirty.clone();
|
||||
let pty_output_seq = pty_output_seq.clone();
|
||||
let detection_content_seq = detection_content_seq.clone();
|
||||
let child_pid = child_pid.clone();
|
||||
let events = events.clone();
|
||||
let reported_cwd = reported_cwd.clone();
|
||||
let rt = tokio::runtime::Handle::current();
|
||||
let on_read = Box::new(move |bytes: &[u8]| {
|
||||
observe_pty_output_activity(bytes, &pty_output_seq);
|
||||
let shell_pid = child_pid.load(Ordering::Acquire);
|
||||
let result =
|
||||
terminal.process_pty_bytes(pane_id, shell_pid, bytes, &response_writer);
|
||||
observe_detection_content_change(bytes, &detection_content_seq);
|
||||
if result.request_render && !render_dirty.swap(true, Ordering::AcqRel) {
|
||||
render_notify.notify_one();
|
||||
}
|
||||
|
|
@ -1780,8 +1716,7 @@ impl PaneRuntime {
|
|||
let child_pid = child_pid.clone();
|
||||
let terminal = terminal.clone();
|
||||
let state_events = events.clone();
|
||||
let pty_output_seq = pty_output_seq.clone();
|
||||
let input_write_seq_for_task = input_write_seq.clone();
|
||||
let detection_content_seq = detection_content_seq.clone();
|
||||
let full_lifecycle_authority_active_for_task = full_lifecycle_authority_active.clone();
|
||||
let render_notify = render_notify.clone();
|
||||
let render_dirty = render_dirty.clone();
|
||||
|
|
@ -1808,12 +1743,9 @@ impl PaneRuntime {
|
|||
let mut last_visible_working = false;
|
||||
let mut last_visible_signal_refresh = None;
|
||||
let mut last_detection_text = String::new();
|
||||
let mut last_screen_scan_pty_output_seq = None;
|
||||
let mut pty_causality = PtyCausalityTracker::default();
|
||||
let mut last_screen_scan_detection_content_seq = None;
|
||||
let mut agent_startup_grace_until = None;
|
||||
let mut pending_idle = PendingIdleConfirmation::default();
|
||||
let mut pending_working = PendingWorkingConfirmation::default();
|
||||
let mut post_taint_working = PostTaintWorkingLease::default();
|
||||
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
|
||||
|
|
@ -1824,8 +1756,6 @@ impl PaneRuntime {
|
|||
|| terminal.has_transient_default_color_override()
|
||||
{
|
||||
TICK_PENDING_RELEASE
|
||||
} else if pending_working.active() {
|
||||
pending_working.recheck_delay(now_for_tick)
|
||||
} else if pending_idle.active() {
|
||||
AGENT_PENDING_IDLE_RECHECK
|
||||
} else if agent_presence.current_agent().is_none() {
|
||||
|
|
@ -1851,12 +1781,9 @@ impl PaneRuntime {
|
|||
last_visible_working = false;
|
||||
last_visible_signal_refresh = None;
|
||||
last_detection_text.clear();
|
||||
last_screen_scan_pty_output_seq = None;
|
||||
pty_causality = PtyCausalityTracker::default();
|
||||
last_screen_scan_detection_content_seq = None;
|
||||
agent_startup_grace_until = None;
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1951,20 +1878,13 @@ impl PaneRuntime {
|
|||
agent = agent_presence.current_agent();
|
||||
if agent != previous_agent {
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
last_screen_scan_pty_output_seq = None;
|
||||
last_screen_scan_detection_content_seq = None;
|
||||
// A new foreground agent must not inherit OSC
|
||||
// title/progress evidence from the previous process.
|
||||
terminal.clear_agent_osc_state();
|
||||
if agent.is_some() {
|
||||
agent_startup_grace_until =
|
||||
Some(now + AGENT_STARTUP_GRACE_WINDOW);
|
||||
baseline_pty_causality(
|
||||
&mut pty_causality,
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq_for_task.load(Ordering::Relaxed),
|
||||
);
|
||||
state = AgentState::Idle;
|
||||
last_visible_idle = true;
|
||||
last_visible_blocker = false;
|
||||
|
|
@ -2025,45 +1945,27 @@ impl PaneRuntime {
|
|||
&& !process_exited
|
||||
{
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(until) = agent_startup_grace_until {
|
||||
if process_exited {
|
||||
agent_startup_grace_until = None;
|
||||
last_screen_scan_pty_output_seq = None;
|
||||
last_screen_scan_detection_content_seq = None;
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
} else {
|
||||
if now < until {
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
continue;
|
||||
}
|
||||
baseline_pty_causality(
|
||||
&mut pty_causality,
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq_for_task.load(Ordering::Relaxed),
|
||||
);
|
||||
agent_startup_grace_until = None;
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
post_taint_working.clear();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let pty_activity = if agent.is_some() {
|
||||
Some(agent_caused_pty_activity_active(
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq_for_task.load(Ordering::Relaxed),
|
||||
&mut pty_causality,
|
||||
now,
|
||||
))
|
||||
let current_detection_content_seq = if agent.is_some() {
|
||||
Some(detection_content_seq.load(Ordering::Relaxed))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
@ -2071,33 +1973,21 @@ impl PaneRuntime {
|
|||
state,
|
||||
agent,
|
||||
pending_idle_active: pending_idle.active(),
|
||||
pending_working_active: pending_working.active(),
|
||||
post_taint_working_active: post_taint_working.active(),
|
||||
agent_changed,
|
||||
process_exited,
|
||||
pty_activity,
|
||||
last_screen_scan_pty_output_seq,
|
||||
current_detection_content_seq,
|
||||
last_screen_scan_detection_content_seq,
|
||||
}) {
|
||||
DetectionScreenReadDecision::Read => {}
|
||||
DetectionScreenReadDecision::Skip => continue,
|
||||
}
|
||||
|
||||
let content = terminal.detection_text();
|
||||
last_screen_scan_pty_output_seq = pty_activity.map(|signal| signal.output_seq);
|
||||
last_screen_scan_detection_content_seq = current_detection_content_seq;
|
||||
let content_changed = content != last_detection_text;
|
||||
last_detection_text.clone_from(&content);
|
||||
if detect::should_skip_state_update(agent, &content) {
|
||||
handle_skipped_detection_update(
|
||||
state,
|
||||
pty_activity,
|
||||
&mut post_taint_working,
|
||||
&mut pty_causality,
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq_for_task.load(Ordering::Relaxed),
|
||||
now,
|
||||
);
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
continue;
|
||||
}
|
||||
sync_content_change_acquisition(
|
||||
|
|
@ -2119,17 +2009,7 @@ impl PaneRuntime {
|
|||
&osc_progress,
|
||||
process_exited,
|
||||
) else {
|
||||
handle_skipped_detection_update(
|
||||
state,
|
||||
pty_activity,
|
||||
&mut post_taint_working,
|
||||
&mut pty_causality,
|
||||
pty_output_seq.load(Ordering::Relaxed),
|
||||
input_write_seq_for_task.load(Ordering::Relaxed),
|
||||
now,
|
||||
);
|
||||
pending_idle.clear();
|
||||
pending_working.clear();
|
||||
continue;
|
||||
};
|
||||
match decide_screen_detection_publish(
|
||||
|
|
@ -2142,12 +2022,9 @@ impl PaneRuntime {
|
|||
last_visible_signal_refresh,
|
||||
process_exited,
|
||||
agent_changed,
|
||||
pty_activity,
|
||||
now,
|
||||
},
|
||||
&mut pending_idle,
|
||||
&mut pending_working,
|
||||
&mut post_taint_working,
|
||||
) {
|
||||
DetectionPublishDecision::NoPublish => {}
|
||||
DetectionPublishDecision::Publish {
|
||||
|
|
@ -2193,7 +2070,7 @@ impl PaneRuntime {
|
|||
reported_cwd,
|
||||
child_wait_completed: Some(child_wait_completed),
|
||||
kitty_keyboard_flags,
|
||||
input_write_seq,
|
||||
detection_content_seq,
|
||||
full_lifecycle_authority_active,
|
||||
detect_reset_notify,
|
||||
pending_release,
|
||||
|
|
@ -2242,11 +2119,11 @@ impl PaneRuntime {
|
|||
if self.current_size.get() == size {
|
||||
return;
|
||||
}
|
||||
self.input_write_seq.fetch_add(1, Ordering::Relaxed);
|
||||
self.current_size.set(size);
|
||||
let terminal_responses = self
|
||||
.terminal
|
||||
.resize(rows, cols, cell_width_px, cell_height_px);
|
||||
mark_detection_content_changed(&self.detection_content_seq);
|
||||
self.io.resize(
|
||||
rows,
|
||||
cols,
|
||||
|
|
@ -2258,7 +2135,6 @@ impl PaneRuntime {
|
|||
|
||||
#[cfg(unix)]
|
||||
pub fn nudge_child_redraw_after_handoff(&self) {
|
||||
self.input_write_seq.fetch_add(1, Ordering::Relaxed);
|
||||
let (rows, cols, cell_width_px, cell_height_px) = self.current_size.get();
|
||||
self.io
|
||||
.nudge_child_redraw_after_handoff(rows, cols, cell_width_px, cell_height_px);
|
||||
|
|
@ -2397,19 +2273,11 @@ impl PaneRuntime {
|
|||
}
|
||||
|
||||
pub async fn send_bytes(&self, bytes: Bytes) -> Result<(), mpsc::error::SendError<Bytes>> {
|
||||
let result = self.io.send_bytes(bytes).await;
|
||||
if result.is_ok() {
|
||||
self.input_write_seq.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
result
|
||||
self.io.send_bytes(bytes).await
|
||||
}
|
||||
|
||||
pub fn try_send_bytes(&self, bytes: Bytes) -> Result<(), mpsc::error::TrySendError<Bytes>> {
|
||||
let result = self.io.try_send_bytes(bytes);
|
||||
if result.is_ok() {
|
||||
self.input_write_seq.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
result
|
||||
self.io.try_send_bytes(bytes)
|
||||
}
|
||||
|
||||
pub async fn send_paste(&self, text: String) -> Result<(), mpsc::error::SendError<Bytes>> {
|
||||
|
|
@ -2607,7 +2475,7 @@ impl PaneRuntime {
|
|||
reported_cwd: Arc::new(Mutex::new(None)),
|
||||
child_wait_completed: None,
|
||||
kitty_keyboard_flags: Arc::new(AtomicU16::new(0)),
|
||||
input_write_seq: Arc::new(AtomicU64::new(0)),
|
||||
detection_content_seq: Arc::new(AtomicU64::new(0)),
|
||||
full_lifecycle_authority_active: Arc::new(AtomicBool::new(false)),
|
||||
detect_reset_notify: Arc::new(Notify::new()),
|
||||
pending_release: Arc::new(Mutex::new(None)),
|
||||
|
|
@ -2981,7 +2849,7 @@ mod tests {
|
|||
reported_cwd: Arc::new(Mutex::new(None)),
|
||||
child_wait_completed: None,
|
||||
kitty_keyboard_flags: Arc::new(AtomicU16::new(0)),
|
||||
input_write_seq: Arc::new(AtomicU64::new(0)),
|
||||
detection_content_seq: Arc::new(AtomicU64::new(0)),
|
||||
full_lifecycle_authority_active: Arc::new(AtomicBool::new(false)),
|
||||
detect_reset_notify: Arc::new(Notify::new()),
|
||||
pending_release: Arc::new(Mutex::new(None)),
|
||||
|
|
@ -3012,7 +2880,7 @@ mod tests {
|
|||
reported_cwd: Arc::new(Mutex::new(None)),
|
||||
child_wait_completed: None,
|
||||
kitty_keyboard_flags: Arc::new(AtomicU16::new(0)),
|
||||
input_write_seq: Arc::new(AtomicU64::new(0)),
|
||||
detection_content_seq: Arc::new(AtomicU64::new(0)),
|
||||
full_lifecycle_authority_active: Arc::new(AtomicBool::new(false)),
|
||||
detect_reset_notify: Arc::new(Notify::new()),
|
||||
pending_release: Arc::new(Mutex::new(None)),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1733,7 +1733,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn pty_working_fallback_is_ignored_under_full_lifecycle_hook_authority() {
|
||||
fn detected_working_fallback_is_ignored_under_full_lifecycle_hook_authority() {
|
||||
let now = Instant::now();
|
||||
let mut terminal = test_terminal();
|
||||
terminal.set_detected_state(Some(Agent::Kilo), AgentState::Idle);
|
||||
|
|
|
|||
Loading…
Reference in New Issue