Fix cursor position reports being ignored

When we receive a cursor position report, we only store the result;
we'll act on it only when we receive the primary DA reply.  Make sure
we don't discard the query state until then.

Fixes 06ede39ec9 (Degrade gracefully when failing to receive cursor
position report, 2025-09-23)
This commit is contained in:
Johannes Altmanninger
2025-09-26 09:18:46 +02:00
parent 74d3832610
commit e9ae143bab
3 changed files with 40 additions and 4 deletions

View File

@@ -2617,7 +2617,7 @@ fn handle_char_event(&mut self, injected_event: Option<CharEvent>) -> ControlFlo
Response(CursorPosition(cursor_pos)),
) => {
cursor_pos_query.result = Some(cursor_pos);
maybe_query
return ControlFlow::Continue(());
}
(
Some(TerminalQuery::CursorPosition(cursor_pos_query)),

View File

@@ -150,7 +150,12 @@ class SpawnedProc(object):
"""
def __init__(
self, name="fish", timeout=TIMEOUT_SECS, env=os.environ.copy(), **kwargs
self,
name="fish",
timeout=TIMEOUT_SECS,
env=os.environ.copy(),
scroll_up_content_supported: bool = False,
**kwargs,
):
"""Construct from a name, timeout, and environment.
@@ -179,8 +184,21 @@ class SpawnedProc(object):
)
self.spawn.delaybeforesend = None
self.prompt_counter = 0
if scroll_up_content_supported:
# XTGETTCAP
key = bytes.hex(b"indn")
value = bytes.hex(b"dont-care")
self.spawn.send(f"\x1bP1+r{key}={value}\x1b\\")
if env.get("TERM") != "dumb":
self.spawn.send("\x1b[?123c") # Primary Device Attribute
self.send_primary_device_attribute()
def send_cursor_position_report(self, *, y: int, x: int):
assert x != 0
assert y != 0
self.spawn.send(f"\x1b[{y};{x}R")
def send_primary_device_attribute(self):
self.spawn.send("\x1b[?123c") # Primary Device Attribute
def time_since_first_message(self):
"""Return a delta in seconds since the first message, or 0 if this is the first."""
@@ -341,7 +359,7 @@ class SpawnedProc(object):
filename=m.filename,
lineno=m.lineno,
etext=etext,
**colors
**colors,
)
)
print("")

View File

@@ -0,0 +1,18 @@
#!/usr/bin/env python3
from pexpect_helper import SpawnedProc, control
import os
env = os.environ.copy()
env["TERM"] = "not-dumb"
sp = SpawnedProc(env=env, scroll_up_content_supported=True)
sendline, expect_prompt = sp.sendline, sp.expect_prompt
expect_prompt()
sendline("bind ctrl-g scrollback-push")
expect_prompt()
sp.send(control("g"))
sp.send_cursor_position_report(y=10, x=5)
sp.send_primary_device_attribute()
sp.expect_str("\x1b[9S\x1b[9A")