Preserve alternate screen snapshots and speed builds
This commit is contained in:
+5
-3
@@ -27,6 +27,8 @@ vt100 = "0.15"
|
||||
tempfile = "3.14"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = "thin"
|
||||
strip = true
|
||||
opt-level = 2
|
||||
codegen-units = 16
|
||||
incremental = true
|
||||
lto = false
|
||||
strip = false
|
||||
|
||||
+15
-4
@@ -277,7 +277,7 @@ async fn handle_bootstrap_attach(
|
||||
session.parser.set_size(req.rows, req.cols);
|
||||
}
|
||||
let client_id = crypto::random_16();
|
||||
let snapshot = session.parser.screen().state_formatted();
|
||||
let snapshot = screen_snapshot(session.parser.screen());
|
||||
let screen = session.parser.screen().clone();
|
||||
let output_seq = session.output_seq;
|
||||
session.clients.insert(
|
||||
@@ -385,7 +385,7 @@ async fn handle_ticket_attach(
|
||||
session.parser.set_size(req.rows, req.cols);
|
||||
}
|
||||
let client_id = crypto::random_16();
|
||||
let snapshot = session.parser.screen().state_formatted();
|
||||
let snapshot = screen_snapshot(session.parser.screen());
|
||||
let screen = session.parser.screen().clone();
|
||||
let output_seq = session.output_seq;
|
||||
session.clients.insert(
|
||||
@@ -491,7 +491,7 @@ async fn handle_resume(
|
||||
session.pty.resize(req.cols, req.rows)?;
|
||||
session.parser.set_size(req.rows, req.cols);
|
||||
}
|
||||
let snapshot = session.parser.screen().state_formatted();
|
||||
let snapshot = screen_snapshot(session.parser.screen());
|
||||
client.last_screen = Some(session.parser.screen().clone());
|
||||
(client.send_seq, session.output_seq, snapshot)
|
||||
};
|
||||
@@ -675,7 +675,7 @@ async fn broadcast_output(
|
||||
let current_screen = session.parser.screen().clone();
|
||||
let (bytes, snapshot) = if client.pending.len() >= retransmit_window {
|
||||
client.pending.clear();
|
||||
(current_screen.state_formatted(), true)
|
||||
(screen_snapshot(¤t_screen), true)
|
||||
} else {
|
||||
(output.bytes.clone(), false)
|
||||
};
|
||||
@@ -758,6 +758,17 @@ async fn broadcast_session_exit(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn screen_snapshot(screen: &vt100::Screen) -> Vec<u8> {
|
||||
let mut bytes = Vec::new();
|
||||
if screen.alternate_screen() {
|
||||
bytes.extend_from_slice(b"\x1b[?1049h");
|
||||
} else {
|
||||
bytes.extend_from_slice(b"\x1b[?1049l");
|
||||
}
|
||||
bytes.extend(screen.state_formatted());
|
||||
bytes
|
||||
}
|
||||
|
||||
async fn retransmit_pending(
|
||||
state: &Arc<Mutex<ServerState>>,
|
||||
socket: &Arc<UdpSocket>,
|
||||
|
||||
@@ -572,6 +572,63 @@ fn live_output_forwards_terminal_control_sequences() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resume_snapshot_preserves_alternate_screen_mode() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let port = free_udp_port();
|
||||
let config = write_server_config(&dir, port);
|
||||
let mut server = start_server(&dir, &config);
|
||||
let (socket, bootstrap, ok) = direct_attach(&config, port, "read-write");
|
||||
|
||||
let input = Input {
|
||||
bytes: b"printf '\\033[?1049hALT_SNAPSHOT'\n".to_vec(),
|
||||
};
|
||||
send_encrypted(
|
||||
&socket,
|
||||
port,
|
||||
PacketKind::Input,
|
||||
ok.client_id,
|
||||
2,
|
||||
0,
|
||||
&bootstrap.session_key,
|
||||
&protocol::to_body(&input).unwrap(),
|
||||
);
|
||||
let _ = collect_frame_text(&socket, &bootstrap.session_key, 500);
|
||||
let new_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
|
||||
new_socket
|
||||
.set_read_timeout(Some(Duration::from_secs(2)))
|
||||
.unwrap();
|
||||
|
||||
let resume = ResumeRequest {
|
||||
session: "default".to_string(),
|
||||
last_rendered_seq: ok.initial_seq,
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
};
|
||||
send_encrypted(
|
||||
&new_socket,
|
||||
port,
|
||||
PacketKind::ResumeRequest,
|
||||
ok.client_id,
|
||||
3,
|
||||
0,
|
||||
&bootstrap.session_key,
|
||||
&protocol::to_body(&resume).unwrap(),
|
||||
);
|
||||
let (_header, resume_frame) =
|
||||
recv_frame(&new_socket, &bootstrap.session_key).expect("resume response");
|
||||
|
||||
let _ = server.kill();
|
||||
let _ = server.wait();
|
||||
|
||||
assert!(resume_frame.snapshot);
|
||||
assert!(
|
||||
resume_frame.bytes.starts_with(b"\x1b[?1049h"),
|
||||
"snapshot did not enter alternate screen first: {:?}",
|
||||
String::from_utf8_lossy(&resume_frame.bytes)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resume_updates_udp_endpoint_for_roaming() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user