Fix for tmux: correct cursor restoration and fix CSI u detection

This commit is contained in:
Andrea Alberti 2025-08-28 16:38:15 +02:00
parent dd7afaa64a
commit 56c7d9ca7b
2 changed files with 77 additions and 15 deletions

View file

@ -21,6 +21,37 @@ impl Mux {
}
}
pub fn tmux_has_csi_u() -> bool {
let output = time!(
"Querying tmux for CSI u support",
std::process::Command::new("tmux")
.args(["display-message", "-p", "#{extended-keys},#{extended-keys-format}"])
.output()
);
match output {
Ok(o) if o.status.success() => {
// Success case: The command ran and exited with code 0.
let stdout = String::from_utf8_lossy(&o.stdout);
stdout.trim() == "on,csi-u"
}
Ok(o) => {
// Execution Error: The command ran but failed.
error!(
"Querying tmux for CSI u support failed with status {:?}: {}",
o.status,
String::from_utf8_lossy(&o.stderr)
);
false
}
Err(e) => {
// Spawn Error: The command could not be started.
error!("Failed to spawn `tmux display-message` for CSI u query: {}", e);
false
}
}
}
pub fn tmux_passthrough() {
let output = time!(
"Running `tmux set -p allow-passthrough on`",

View file

@ -30,6 +30,30 @@ impl Term {
yazi_adapter::Mux::tmux_passthrough();
}
let mut csi_u_supported = false; // This will hold the result of our detection.
if TMUX.get() {
// --- TMUX-SPECIFIC LOGIC ---
// 1. Reliably detect CSI u support by querying tmux's own options.
csi_u_supported = Mux::tmux_has_csi_u();
// 2. Send only the essential queries, skipping the problematic cursor ones.
execute!(
TTY.writer(),
Print(Mux::csi("\x1b[0c")), // Request device attributes
EnterAlternateScreen,
EnableBracketedPaste,
yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), EnableMouseCapture),
)?;
// 3. Read the terminal's response, but do NOT call store().
// This allows tmux's native alternate screen restoration to work.
Emulator::read_until_da1();
Mux::tmux_drain()?;
} else {
// --- ORIGINAL LOGIC FOR NON-TMUX TERMINALS ---
// 1. Send all original queries, as they may be supported by other terminals.
execute!(
TTY.writer(),
yazi_term::If(!TMUX.get(), EnterAlternateScreen),
@ -42,11 +66,18 @@ impl Term {
yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), EnableMouseCapture),
)?;
// 2. Use the original logic to parse the response and store the cursor state.
let resp = Emulator::read_until_da1();
Mux::tmux_drain()?;
yazi_term::RestoreCursor::store(&resp);
CSI_U.store(resp.contains("\x1b[?0u"), Ordering::Relaxed);
// 3. Check the ANSI response for CSI u support, as before.
if resp.contains("\x1b[?0u") {
csi_u_supported = true;
}
}
CSI_U.store(csi_u_supported, Ordering::Relaxed);
if CSI_U.load(Ordering::Relaxed) {
PushKeyboardEnhancementFlags(
KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES