diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-02 21:53:48 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-02 21:54:05 +0300 |
| commit | 848554517ae6473caf61f738d60def90f77e1dc9 (patch) | |
| tree | 3bddc83e2ffd84a11ed73012dd0d2c1f28555102 /src/server | |
| parent | 32146f19d87448d8e3bb4019be6b8d9ff1cb72ee (diff) | |
fix: keep copy feedback above retained pane updates
refs #555
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/headless.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/server/headless.rs b/src/server/headless.rs index 5521f59f..f0363ba1 100644 --- a/src/server/headless.rs +++ b/src/server/headless.rs @@ -3216,6 +3216,7 @@ impl HeadlessServer { && self.app.state.copy_mode.is_none() && self.app.state.context_menu.is_none() && self.app.state.toast.is_none() + && self.app.state.copy_feedback.is_none() && !self.app.full_redraw_pending } @@ -7275,6 +7276,48 @@ next_tab = "" } #[tokio::test] + async fn retained_pty_update_declines_while_copy_feedback_is_visible() { + let (mut server, client_rx, pane_id) = retained_test_server(b"aaaa"); + server.app.state.copy_feedback = Some(crate::app::state::CopyFeedback { + message: "copied to clipboard".to_owned(), + }); + server.render_and_stream(); + let initial = read_server_frame( + client_rx + .recv_timeout(Duration::from_millis(100)) + .expect("initial frame"), + ); + let initial_text = frame_text(&initial); + assert!( + initial_text.contains("copied to clipboard"), + "expected initial full frame to include copy feedback" + ); + + let feedback_row = initial_text + .lines() + .position(|line| line.contains("copied to clipboard")) + .expect("copy feedback row") as u16; + let inner_rect = server.app.state.view.pane_infos[0].inner_rect; + let pane_row = feedback_row + .checked_sub(inner_rect.y) + .expect("copy feedback should overlap the pane") + + 1; + assert!(pane_row <= inner_rect.height); + let runtime = server + .app + .state + .runtime_for_pane_in_workspace(&server.app.terminal_runtimes, 0, pane_id) + .expect("runtime"); + runtime.test_process_pty_bytes(format!("\x1b[{pane_row};1Hzzzz").as_bytes()); + + assert!(!server.render_retained_pty_update_and_stream()); + assert!( + client_rx.recv_timeout(Duration::from_millis(50)).is_err(), + "retained path should not stream a frame that can overwrite copy feedback cells" + ); + } + + #[tokio::test] async fn retained_pty_update_matches_full_render_frame() { let initial = b"\x1b[6 qleft \xe4\xb8\xad"; let update = b"\r\x1b[44mZ\x1b[0m"; |
