aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-28 16:19:42 +0300
committerGitHub <noreply@github.com>2026-09-28 16:19:42 +0300
commit80c0c07250d22f69d3fa05cb1700302d66180eb8 (patch)
tree9e1903d65c83263354be4b2166f3a7c92dc2a8e2 /src/client
parent8c8cb49c237eec2f82192dd831ec7308905f2c0a (diff)
perf: send scrolling pane output as row shifts and skip blank cells (#4711)
* perf: send scrolling pane output as row shifts and skip blank cells * fix: keep expanded scroll patches disjoint for the fast presentation path
Diffstat (limited to 'src/client')
-rw-r--r--src/client/handshake.rs1
-rw-r--r--src/client/mod.rs22
2 files changed, 13 insertions, 10 deletions
diff --git a/src/client/handshake.rs b/src/client/handshake.rs
index f25cc1b0..2520286c 100644
--- a/src/client/handshake.rs
+++ b/src/client/handshake.rs
@@ -200,6 +200,7 @@ pub(super) fn do_handshake(
surface_active,
surface_reuse: true,
surface_delta: true,
+ surface_scroll: true,
snapshot_codecs: vec![SNAPSHOT_CODEC_V1.into()],
surface_codecs: vec![SURFACE_CODEC_V1.into()],
input_codecs: vec![INPUT_CODEC_V1.into()],
diff --git a/src/client/mod.rs b/src/client/mod.rs
index 2cec6d2d..b78517ac 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -145,6 +145,16 @@ use crate::protocol::{self, ClientMessage, ServerMessage, MAX_GRAPHICS_FRAME_SIZ
use crate::protocol::{AttachScrollDirection, AttachScrollSource, NotifyKind};
use crate::server::socket_paths::client_socket_path;
+/// The decoder for whichever optional surface encodings this connection negotiated.
+fn negotiated_surface_decoder(
+ negotiation: &endpoint::EndpointNegotiation,
+) -> Option<protocol::surface_reuse::Decoder> {
+ let reuse = negotiation.supports_capability(protocol::surface_reuse::CAPABILITY);
+ let delta = negotiation.supports_capability(protocol::surface_delta::CAPABILITY);
+ let scroll = negotiation.supports_capability(protocol::surface_scroll::CAPABILITY);
+ (reuse || delta || scroll).then(|| protocol::surface_reuse::Decoder::new(delta, scroll))
+}
+
fn run_client_with_mode(
attach_request: Option<(String, bool)>,
attach_escape: Option<AttachEscapeState>,
@@ -588,10 +598,7 @@ async fn run_client_loop(
handshake.endpoint_methods.unwrap_or_default(),
handshake.endpoint_capabilities.unwrap_or_default(),
);
- let surface_reuse = negotiation.supports_capability(protocol::surface_reuse::CAPABILITY);
- let surface_delta = negotiation.supports_capability(protocol::surface_delta::CAPABILITY);
- let surface_decoder = (surface_reuse || surface_delta)
- .then(|| protocol::surface_reuse::Decoder::new(surface_delta));
+ let surface_decoder = negotiated_surface_decoder(&negotiation);
let transport = start_endpoint_transport(
stream,
(),
@@ -1285,10 +1292,7 @@ async fn run_client_loop(
) {
continue;
}
- let surface_reuse =
- negotiation.supports_capability(protocol::surface_reuse::CAPABILITY);
- let surface_delta =
- negotiation.supports_capability(protocol::surface_delta::CAPABILITY);
+ let surface_decoder = negotiated_surface_decoder(&negotiation);
let agent_view_projection_supported = negotiation.supports_capability(
crate::protocol::endpoint::AGENT_VIEW_PROJECTION_CAPABILITY,
);
@@ -1313,8 +1317,6 @@ async fn run_client_loop(
if let Some(frame) = frame {
state.present_frame(frame);
}
- let surface_decoder = (surface_reuse || surface_delta)
- .then(|| protocol::surface_reuse::Decoder::new(surface_delta));
let reader_tx = event_tx.clone();
std::thread::spawn(move || {
server_reader_thread(