From 4b7def2d7443f01d164e15a4c4285ffc8f642f84 Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Mon, 28 Sep 2026 18:02:45 +0800 Subject: [PATCH] fix(lsp): close a window's documents when the window closes Documents were only closed by sync_window, which runs when a window's buffer set changes. Closing a window never ran it, so no didClose was sent, the idle shutdown never started, and a language server lived on until quit (forever, with the app retired to the tray). --- src/ui/app.rs | 11 ++++++++++- src/ui/lsp/editor.rs | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/ui/app.rs b/src/ui/app.rs index be79bfb0..19835f31 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -1605,6 +1605,11 @@ impl Tty7App { crate::ui::tray::init(cx); } app.refresh_shells(cx); + // Backstop for every other way a window goes away (a workspace + // closed from elsewhere): its language-server documents go with it. + let app_id = cx.entity_id(); + cx.on_release(move |_, cx| crate::ui::lsp::LspStore::sync_window(app_id, Vec::new(), cx)) + .detach(); cx.on_app_quit(|app, cx| { app.save_session(cx); crate::core::window_state::WindowState::from_bounds(app.window_bounds).save(); @@ -1670,7 +1675,10 @@ impl Tty7App { if asked { return false; } - app.update(cx, |app, cx| app.prepare_window_close(cx)); + app.update(cx, |app, cx| { + app.prepare_window_close(cx); + app.lsp_window_closed(cx); + }); true }); @@ -1772,6 +1780,7 @@ impl Tty7App { return; } self.prepare_window_close(cx); + self.lsp_window_closed(cx); window.remove_window(); } diff --git a/src/ui/lsp/editor.rs b/src/ui/lsp/editor.rs index cda872be..26d5a355 100644 --- a/src/ui/lsp/editor.rs +++ b/src/ui/lsp/editor.rs @@ -52,6 +52,13 @@ impl Tty7App { LspStore::sync_window(cx.entity_id(), buffers, cx); } + /// The window is closing: every document it owns is closed now, so an + /// idle server can wind down instead of outliving the window (with a + /// tray icon the app itself keeps running). + pub(crate) fn lsp_window_closed(&self, cx: &mut Context) { + LspStore::sync_window(cx.entity_id(), Vec::new(), cx); + } + /// A buffer's text changed. pub(crate) fn lsp_buffer_edited(&self, id: BufferId, cx: &mut Context) { if let Some(f) = self.editor_local_file(id) {