Skip to content

Commit 5351d6c

Browse files
committed
Restore terminal state on TUI setup failure
Use an armed cleanup guard so failed setup and teardown paths restore raw mode, alternate-screen state, cursor shape, and cursor visibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c0a29a6-f8d2-452f-8c71-04d22df87777
1 parent 9981189 commit 5351d6c

1 file changed

Lines changed: 37 additions & 1 deletion

File tree

tools/wta/src/main.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use agent_client_protocol as acp;
4545
use anyhow::{bail, Context, Result};
4646
use clap::{Parser, Subcommand};
4747
use crossterm::{
48-
cursor::SetCursorStyle,
48+
cursor::{SetCursorStyle, Show},
4949
execute,
5050
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
5151
};
@@ -2664,6 +2664,40 @@ async fn discover_pane_identity(shell_mgr: &ShellManager) -> Option<(String, Str
26642664
None
26652665
}
26662666

2667+
struct TuiRestoreGuard {
2668+
armed: bool,
2669+
}
2670+
2671+
impl TuiRestoreGuard {
2672+
fn new() -> Self {
2673+
Self { armed: true }
2674+
}
2675+
2676+
fn disarm(&mut self) {
2677+
self.armed = false;
2678+
}
2679+
}
2680+
2681+
impl Drop for TuiRestoreGuard {
2682+
fn drop(&mut self) {
2683+
if !self.armed {
2684+
return;
2685+
}
2686+
2687+
let _ = disable_raw_mode();
2688+
let mut stdout = io::stdout();
2689+
// Agent panes start with alternate-scroll enabled, so restore that known state.
2690+
let _ = write!(stdout, "\x1b[?1007h");
2691+
let _ = stdout.flush();
2692+
let _ = execute!(
2693+
stdout,
2694+
SetCursorStyle::DefaultUserShape,
2695+
LeaveAlternateScreen,
2696+
Show
2697+
);
2698+
}
2699+
}
2700+
26672701
async fn run_acp_tui_mode(
26682702
cli: Cli,
26692703
shell_mgr: Arc<ShellManager>,
@@ -2675,6 +2709,7 @@ async fn run_acp_tui_mode(
26752709
connect_master_pipe: String,
26762710
) -> Result<()> {
26772711
enable_raw_mode()?;
2712+
let mut restore_guard = TuiRestoreGuard::new();
26782713
let mut stdout = io::stdout();
26792714
// Keep mouse capture off so native click-drag selection continues to work.
26802715
// Disable xterm alternate-scroll mode while the TUI is active so wheel
@@ -2715,6 +2750,7 @@ async fn run_acp_tui_mode(
27152750
LeaveAlternateScreen
27162751
)?;
27172752
terminal.show_cursor()?;
2753+
restore_guard.disarm();
27182754

27192755
if let Err(e) = result {
27202756
// This is the real exit point for a TUI/helper failure (connection

0 commit comments

Comments
 (0)