aboutsummaryrefslogtreecommitdiff
path: root/src/client/handshake.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/handshake.rs')
-rw-r--r--src/client/handshake.rs43
1 files changed, 38 insertions, 5 deletions
diff --git a/src/client/handshake.rs b/src/client/handshake.rs
index 69e2f52f..f25cc1b0 100644
--- a/src/client/handshake.rs
+++ b/src/client/handshake.rs
@@ -69,6 +69,17 @@ pub(super) fn direct_graphics_profile_values(
supported && !blocked_transport && terminals
}
+/// Server-owned files require a shared filesystem; the host terminal profile alone
+/// cannot establish that for a saved SSH endpoint.
+fn direct_graphics_capability(
+ local_transport: bool,
+ exact_cell_size: bool,
+ cell_size: (u32, u32),
+ profile_allowed: bool,
+) -> bool {
+ local_transport && exact_cell_size && cell_size.0 > 0 && cell_size.1 > 0 && profile_allowed
+}
+
#[cfg(unix)]
fn direct_graphics_profile_allowed() -> bool {
let term_program = std::env::var("TERM_PROGRAM").unwrap_or_default();
@@ -138,6 +149,7 @@ pub(crate) fn probe_endpoint_negotiation(
false,
false,
false,
+ false, // This probe uses an SSH bridge, not a shared filesystem.
)
.map_err(io::Error::other)?;
Ok(super::endpoint::EndpointNegotiation::new(
@@ -150,7 +162,8 @@ pub(crate) fn probe_endpoint_negotiation(
///
/// Direct terminal clients retain the same-install private protocol. Client-owned
/// shells use the stable endpoint generation and negotiate whole codecs without
-/// comparing Herdr build versions.
+/// comparing Herdr build versions. `local_transport` means the endpoint shares the
+/// client's filesystem, not merely that its bridge exposes a local socket.
pub(super) fn do_handshake(
stream: &mut LocalStream,
cols: u16,
@@ -162,6 +175,7 @@ pub(super) fn do_handshake(
endpoint_keybindings: bool,
mouse_capture: bool,
surface_active: bool,
+ local_transport: bool,
) -> Result<HandshakeResult, ClientError> {
stream
.set_nonblocking(false)
@@ -175,10 +189,12 @@ pub(super) fn do_handshake(
cell_height_px,
surface_size,
pixel_mouse: exact_cell_size && cfg!(unix),
- direct_graphics: exact_cell_size
- && cell_width_px > 0
- && cell_height_px > 0
- && direct_graphics_profile_allowed(),
+ direct_graphics: direct_graphics_capability(
+ local_transport,
+ exact_cell_size,
+ (cell_width_px, cell_height_px),
+ direct_graphics_profile_allowed(),
+ ),
endpoint_keybindings,
mouse_capture,
surface_active,
@@ -295,3 +311,20 @@ pub(super) fn do_handshake(
))),
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn direct_graphics_requires_local_transport_even_on_supported_host_terminal() {
+ let supported = direct_graphics_profile_values("ghostty", "", false, false, true);
+ assert!(supported);
+ assert!(direct_graphics_capability(true, true, (8, 16), supported));
+ assert!(!direct_graphics_capability(false, true, (8, 16), supported));
+ assert!(!direct_graphics_capability(true, false, (8, 16), supported));
+ assert!(!direct_graphics_capability(true, true, (0, 16), supported));
+ assert!(!direct_graphics_capability(true, true, (8, 0), supported));
+ assert!(!direct_graphics_capability(true, true, (8, 16), false));
+ }
+}