From 96bdeca2acf40db05cdddcda37e915d6bf0fcda6 Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Mon, 5 Aug 2024 21:24:01 +0200 Subject: [PATCH] Terminate thread when pane is closed/removed (#14) --- crates/debugger_ui/src/debugger_panel.rs | 87 +++++++++++++++--------- crates/workspace/src/pane.rs | 14 ++-- crates/workspace/src/workspace.rs | 5 +- 3 files changed, 62 insertions(+), 44 deletions(-) diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 71b072f9bb..7c8cbb76a7 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -21,11 +21,11 @@ use std::{collections::HashMap, sync::Arc}; use task::DebugRequestType; use ui::prelude::*; use util::{merge_json_value_into, ResultExt}; -use workspace::Pane; use workspace::{ dock::{DockPosition, Panel, PanelEvent}, Workspace, }; +use workspace::{pane, Pane}; enum DebugCurrentRowHighlight {} @@ -67,44 +67,49 @@ impl DebugPanel { let project = workspace.project().clone(); - let _subscriptions = vec![cx.subscribe(&project, { - move |this: &mut Self, _, event, cx| match event { - project::Event::DebugClientEvent { payload, client_id } => { - let client = this.debug_client_by_id(*client_id, cx); + let _subscriptions = vec![ + cx.subscribe(&pane, Self::handle_pane_event), + cx.subscribe(&project, { + move |this: &mut Self, _, event, cx| match event { + project::Event::DebugClientEvent { payload, client_id } => { + let client = this.debug_client_by_id(*client_id, cx); - match payload { - Payload::Event(event) => { - Self::handle_debug_client_events(this, client, event, cx); - } - Payload::Request(request) => { - if StartDebugging::COMMAND == request.command { - Self::handle_start_debugging_request(this, client, request, cx) + match payload { + Payload::Event(event) => { + Self::handle_debug_client_events(this, client, event, cx); + } + Payload::Request(request) => { + if StartDebugging::COMMAND == request.command { + Self::handle_start_debugging_request( + this, client, request, cx, + ) .log_err(); + } } + _ => unreachable!(), } - _ => unreachable!(), } - } - project::Event::DebugClientStarted(client_id) => { - let client = this.debug_client_by_id(*client_id, cx); - cx.spawn(|_, _| async move { - client.initialize().await?; + project::Event::DebugClientStarted(client_id) => { + let client = this.debug_client_by_id(*client_id, cx); + cx.spawn(|_, _| async move { + client.initialize().await?; - // send correct request based on adapter config - match client.config().request { - DebugRequestType::Launch => { - client.launch(client.request_args()).await + // send correct request based on adapter config + match client.config().request { + DebugRequestType::Launch => { + client.launch(client.request_args()).await + } + DebugRequestType::Attach => { + client.attach(client.request_args()).await + } } - DebugRequestType::Attach => { - client.attach(client.request_args()).await - } - } - }) - .detach_and_log_err(cx); + }) + .detach_and_log_err(cx); + } + _ => {} } - _ => {} - } - })]; + }), + ]; Self { pane, @@ -140,6 +145,26 @@ impl DebugPanel { .unwrap() } + fn handle_pane_event( + &mut self, + _: View, + event: &pane::Event, + cx: &mut ViewContext, + ) { + if let pane::Event::RemovedItem { item } = event { + let thread_panel = item.downcast::().unwrap(); + + thread_panel.update(cx, |pane, cx| { + let thread_id = pane.thread_id(); + let client = pane.client().clone(); + cx.spawn( + |_, _| async move { client.terminate_threads(Some(vec![thread_id; 1])).await }, + ) + .detach_and_log_err(cx); + }); + }; + } + fn handle_start_debugging_request( this: &mut Self, client: Arc, diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index b506709a80..a204f76a2c 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -169,8 +169,7 @@ pub enum Event { AddItem { item: Box }, ActivateItem { local: bool }, Remove, - RemoveItem { idx: usize }, - RemovedItem { item_id: EntityId }, + RemovedItem { item: Box }, Split(SplitDirection), ChangeItemTitle, Focus, @@ -190,10 +189,9 @@ impl fmt::Debug for Event { .field("local", local) .finish(), Event::Remove => f.write_str("Remove"), - Event::RemoveItem { idx } => f.debug_struct("RemoveItem").field("idx", idx).finish(), - Event::RemovedItem { item_id } => f + Event::RemovedItem { item } => f .debug_struct("RemovedItem") - .field("item_id", item_id) + .field("item", &item.item_id()) .finish(), Event::Split(direction) => f .debug_struct("Split") @@ -1308,13 +1306,9 @@ impl Pane { } } - cx.emit(Event::RemoveItem { idx: item_index }); - let item = self.items.remove(item_index); - cx.emit(Event::RemovedItem { - item_id: item.item_id(), - }); + cx.emit(Event::RemovedItem { item: item.clone() }); if self.items.is_empty() { item.deactivated(cx); if close_pane_if_empty { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 367d3733e1..65c24e816c 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -2904,11 +2904,10 @@ impl Workspace { } self.update_window_edited(cx); } - pane::Event::RemoveItem { .. } => {} - pane::Event::RemovedItem { item_id } => { + pane::Event::RemovedItem { item } => { cx.emit(Event::ActiveItemChanged); self.update_window_edited(cx); - if let hash_map::Entry::Occupied(entry) = self.panes_by_item.entry(*item_id) { + if let hash_map::Entry::Occupied(entry) = self.panes_by_item.entry(item.item_id()) { if entry.get().entity_id() == pane.entity_id() { entry.remove(); }