diff options
Diffstat (limited to 'src/client/handshake.rs')
| -rw-r--r-- | src/client/handshake.rs | 43 |
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)); + } +} |
