aboutsummaryrefslogtreecommitdiff
path: root/src/server/headless
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/headless')
-rw-r--r--src/server/headless/notifications.rs6
-rw-r--r--src/server/headless/tests/mod.rs32
2 files changed, 38 insertions, 0 deletions
diff --git a/src/server/headless/notifications.rs b/src/server/headless/notifications.rs
index 39938b74..722f95c5 100644
--- a/src/server/headless/notifications.rs
+++ b/src/server/headless/notifications.rs
@@ -321,6 +321,9 @@ impl HeadlessServer {
///
/// Returns true if the event changed visual state (requiring a re-render).
pub(super) fn handle_internal_event_with_forwarding(&mut self, mut ev: AppEvent) -> bool {
+ if self.host_shutdown_requested.load(Ordering::Acquire) {
+ return false;
+ }
let mut focused_worktree_response = if let AppEvent::WorktreeAddFinished(result) = &mut ev {
result
.api_request
@@ -752,6 +755,9 @@ impl HeadlessServer {
let mut had_event = false;
let mut changed = false;
for _ in 0..limit {
+ if self.host_shutdown_requested.load(Ordering::Acquire) {
+ break;
+ }
let Ok(ev) = self.app.event_rx.try_recv() else {
break;
};
diff --git a/src/server/headless/tests/mod.rs b/src/server/headless/tests/mod.rs
index 60f89d63..cf6d389b 100644
--- a/src/server/headless/tests/mod.rs
+++ b/src/server/headless/tests/mod.rs
@@ -96,6 +96,7 @@ fn test_headless_server_with_event_hub(event_hub: api::EventHub) -> HeadlessServ
headless_size,
effective_size: headless_size,
shutting_down: false,
+ host_shutdown_requested: Arc::new(AtomicBool::new(false)),
handoff_in_progress: false,
#[cfg(unix)]
pending_handoff_repaint_nudge: false,
@@ -4186,6 +4187,37 @@ fn changed_git_refresh_requests_headless_render() {
}
#[tokio::test]
+async fn host_shutdown_preserves_panes_from_queued_and_selected_death_events() {
+ let mut server = test_headless_server();
+ let workspace = crate::workspace::Workspace::test_new("host-shutdown");
+ let pane_id = workspace.tabs[0].root_pane;
+ server.app.state.workspaces = vec![workspace];
+ server.app.state.ensure_test_terminals();
+ server.app.state.active = Some(0);
+ let event = || AppEvent::PaneDied {
+ pane_id,
+ exit_reason: crate::platform::ChildExitReason::Exited,
+ };
+ server.app.event_tx.try_send(event()).unwrap();
+ server
+ .host_shutdown_requested
+ .store(true, Ordering::Release);
+ assert_eq!(
+ server.drain_internal_events_with_forwarding_up_to(16),
+ (false, false)
+ );
+ assert!(!server.handle_internal_event_with_forwarding(event()));
+ assert!(server.app.find_pane(pane_id).is_some());
+ assert!(server.app.event_rx.try_recv().is_ok());
+ server
+ .host_shutdown_requested
+ .store(false, Ordering::Release);
+ assert!(server.handle_internal_event_with_forwarding(event()));
+ assert!(server.app.find_pane(pane_id).is_none());
+ shutdown_test_runtimes(&mut server);
+}
+
+#[tokio::test]
async fn pane_death_reconciles_each_client_view_and_focus() {
let mut server = test_headless_server();
let mut workspace = crate::workspace::Workspace::test_new("pane-death-views");