aboutsummaryrefslogtreecommitdiff
path: root/src/server/headless.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/headless.rs')
-rw-r--r--src/server/headless.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/server/headless.rs b/src/server/headless.rs
index 720b43f2..9c21aa1b 100644
--- a/src/server/headless.rs
+++ b/src/server/headless.rs
@@ -3462,6 +3462,7 @@ impl HeadlessServer {
fn retained_pty_update_allowed_by_app_state(&self) -> bool {
self.app.state.mode == app::Mode::Terminal
+ && self.app.state.popup_pane.is_none()
&& self.app.state.selection.is_none()
&& self.app.state.copy_mode.is_none()
&& self.app.state.context_menu.is_none()
@@ -7801,6 +7802,136 @@ next_tab = ""
}
#[tokio::test]
+ async fn retained_pty_update_declines_while_popup_is_visible() {
+ let (mut server, client_rx, _) = retained_test_server(b"tiled");
+ let popup_runtime =
+ crate::terminal::TerminalRuntime::test_with_screen_bytes(40, 12, b"popup-aaaa");
+ let (_, terminal_id) = server.app.install_test_popup_runtime(popup_runtime);
+
+ server.render_and_stream();
+ let initial = read_server_frame(
+ client_rx
+ .recv_timeout(Duration::from_millis(100))
+ .expect("initial popup frame"),
+ );
+ assert!(frame_text(&initial).contains("popup-aaaa"));
+ server
+ .app
+ .terminal_runtimes
+ .get(&terminal_id)
+ .unwrap()
+ .test_process_pty_bytes(b"\rZ");
+
+ assert!(!server.render_retained_pty_update_and_stream());
+ server.render_and_stream();
+ let updated = read_server_frame(
+ client_rx
+ .recv_timeout(Duration::from_millis(100))
+ .expect("full popup fallback frame"),
+ );
+ assert!(frame_text(&updated).contains("Zopup-aaaa"));
+ }
+
+ #[tokio::test]
+ async fn popup_forces_host_mouse_capture_for_headless_client() {
+ let mut server = test_headless_server();
+ let (client_tx, client_control_rx, _client_rx) = test_client_writer();
+ server.clients.insert(
+ 1,
+ ClientConnection::new(
+ (80, 24),
+ crate::kitty_graphics::HostCellSize::default(),
+ crate::terminal_theme::TerminalTheme::default(),
+ None,
+ 1,
+ RenderEncoding::SemanticFrame,
+ Some(client_tx),
+ ),
+ );
+ server.app.state.mouse_capture = false;
+ let popup_runtime =
+ crate::terminal::TerminalRuntime::test_with_screen_bytes(40, 12, b"popup");
+ server.app.install_test_popup_runtime(popup_runtime);
+
+ server.stream_host_mouse_capture_mode();
+
+ assert!(matches!(
+ read_server_message(
+ client_control_rx
+ .recv_timeout(Duration::from_millis(100))
+ .expect("mouse capture message")
+ ),
+ ServerMessage::MouseCapture { enabled: true }
+ ));
+ }
+
+ #[tokio::test]
+ async fn virtual_render_uses_popup_cursor() {
+ let (mut server, _client_rx, _) = retained_test_server(b"\x1b[2;2H");
+ let popup_runtime =
+ crate::terminal::TerminalRuntime::test_with_screen_bytes(40, 12, b"\x1b[4;5H");
+ let (_, terminal_id) = server.app.install_test_popup_runtime(popup_runtime);
+
+ let (_, cursor) = crate::server::render_stream::render_virtual_with_runtime_registry(
+ &mut server.app.state,
+ &server.app.terminal_runtimes,
+ ratatui::layout::Rect::new(0, 0, 80, 24),
+ true,
+ crate::kitty_graphics::HostCellSize::default(),
+ );
+ let (_, inner) =
+ crate::ui::popup_pane_rects(&server.app.state, server.app.state.view.terminal_area)
+ .unwrap();
+ let expected = server
+ .app
+ .terminal_runtimes
+ .get(&terminal_id)
+ .unwrap()
+ .cursor_state(inner, true)
+ .unwrap();
+
+ assert_eq!(
+ cursor,
+ Some(crate::protocol::CursorState {
+ x: expected.x,
+ y: expected.y,
+ visible: expected.visible,
+ shape: expected.shape,
+ })
+ );
+ }
+
+ #[tokio::test]
+ async fn virtual_render_does_not_resize_directly_attached_popup() {
+ let (mut server, _client_rx, _) = retained_test_server(b"tiled");
+ let popup_runtime = crate::terminal::TerminalRuntime::test_with_screen_bytes(50, 13, b"");
+ let (_, terminal_id) = server.app.install_test_popup_runtime(popup_runtime);
+ server
+ .app
+ .state
+ .direct_attach_resize_locks
+ .insert(terminal_id.clone());
+
+ let _ = crate::server::render_stream::render_virtual_with_runtime_registry(
+ &mut server.app.state,
+ &server.app.terminal_runtimes,
+ ratatui::layout::Rect::new(0, 0, 80, 24),
+ true,
+ crate::kitty_graphics::HostCellSize::default(),
+ );
+
+ assert_eq!(
+ server
+ .app
+ .terminal_runtimes
+ .get(&terminal_id)
+ .unwrap()
+ .current_size(),
+ (13, 50)
+ );
+ }
+
+ #[tokio::test]
async fn retained_pty_update_declines_while_toast_is_visible() {
let (mut server, client_rx, pane_id) = retained_test_server(b"aaaa");
server.app.state.toast = Some(crate::app::state::ToastNotification {