Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ff2b7fff2b | |||
| f4879090f6 |
Generated
+1
-1
@@ -436,7 +436,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dosh"
|
||||
version = "1.0.0-rc6"
|
||||
version = "1.0.0-rc7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "dosh"
|
||||
version = "1.0.0-rc6"
|
||||
version = "1.0.0-rc7"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
|
||||
|
||||
+39
-3
@@ -4401,8 +4401,9 @@ async fn run_terminal(
|
||||
if input_matches_escape(&bytes, escape_key.as_deref()) {
|
||||
break;
|
||||
}
|
||||
let saw_focus_in = input_contains_focus_in(&bytes);
|
||||
if !forward_only
|
||||
&& input_contains_focus_in(&bytes)
|
||||
&& saw_focus_in
|
||||
&& last_focus_repaint_at.elapsed() >= FOCUS_REPAINT_COOLDOWN
|
||||
{
|
||||
last_focus_repaint_at = Instant::now();
|
||||
@@ -4436,6 +4437,10 @@ async fn run_terminal(
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
bytes = strip_terminal_focus_reports(&bytes);
|
||||
if bytes.is_empty() {
|
||||
continue;
|
||||
}
|
||||
if should_strip_stale_terminal_reports(
|
||||
last_packet_at.elapsed(),
|
||||
stale_terminal_input_suppress_until,
|
||||
@@ -5641,6 +5646,26 @@ fn input_contains_focus_in(bytes: &[u8]) -> bool {
|
||||
contains_bytes(bytes, b"\x1b[I") || contains_bytes(bytes, b"\x9bI")
|
||||
}
|
||||
|
||||
fn strip_terminal_focus_reports(bytes: &[u8]) -> Vec<u8> {
|
||||
let mut out = Vec::with_capacity(bytes.len());
|
||||
let mut offset = 0;
|
||||
while offset < bytes.len() {
|
||||
match bytes.get(offset..) {
|
||||
Some([0x1b, b'[', b'I' | b'O', ..]) => {
|
||||
offset += 3;
|
||||
}
|
||||
Some([0x9b, b'I' | b'O', ..]) => {
|
||||
offset += 2;
|
||||
}
|
||||
_ => {
|
||||
out.push(bytes[offset]);
|
||||
offset += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
fn should_repaint_idle_alternate_screen(
|
||||
alternate_screen: bool,
|
||||
last_terminal_frame_at: Instant,
|
||||
@@ -7347,8 +7372,8 @@ mod tests {
|
||||
should_hold_during_startup_gate, should_hold_post_submit_input,
|
||||
should_repaint_idle_alternate_screen, split_after_command_submit, ssh_destination_host,
|
||||
ssh_username, ssh_with_user, startup_command, status_ssh_target, strip_stale_mouse_reports,
|
||||
toml_bare_key_or_quoted, update_check_requested, update_version_status,
|
||||
upsert_managed_block, valid_forward_host, vscode_safe_alias,
|
||||
strip_terminal_focus_reports, toml_bare_key_or_quoted, update_check_requested,
|
||||
update_version_status, upsert_managed_block, valid_forward_host, vscode_safe_alias,
|
||||
};
|
||||
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
|
||||
use dosh::native::EnvVar;
|
||||
@@ -8661,6 +8686,17 @@ mod tests {
|
||||
assert!(!input_contains_focus_in(b"\x1b[A"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn focus_reports_are_never_forwarded_as_user_input() {
|
||||
assert_eq!(strip_terminal_focus_reports(b"\x1b[Ihello\x1b[O"), b"hello");
|
||||
assert_eq!(strip_terminal_focus_reports(b"\x9bIhello\x9bO"), b"hello");
|
||||
assert_eq!(strip_terminal_focus_reports(b"\x1b[A"), b"\x1b[A");
|
||||
assert_eq!(
|
||||
strip_terminal_focus_reports(b"before\x1b[Iafter"),
|
||||
b"beforeafter"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn idle_repaint_only_runs_for_stale_alternate_screen() {
|
||||
let now = Instant::now();
|
||||
|
||||
Reference in New Issue
Block a user