debugger: Add close button and coloring to debug panel session's menu (#28310)

This PR adds colors to debug panel's session menu that indicate the
state of each respective session. It also adds a close button to each
entry.

green - running
yellow - stopped
red - terminated/ended 


Release Notes:

- N/A
This commit is contained in:
Anthony Eid 2025-04-08 12:35:33 -04:00 committed by GitHub
parent ee7b1ec7f2
commit 1774cad933
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 173 additions and 44 deletions

View file

@ -12,8 +12,8 @@ use dap::{
};
use futures::{SinkExt as _, channel::mpsc};
use gpui::{
Action, App, AsyncWindowContext, Context, Entity, EventEmitter, FocusHandle, Focusable,
Subscription, Task, WeakEntity, actions,
Action, App, AsyncWindowContext, Context, Entity, EntityId, EventEmitter, FocusHandle,
Focusable, Subscription, Task, WeakEntity, actions,
};
use project::{
Project,
@ -336,6 +336,95 @@ impl DebugPanel {
})
}
fn close_session(&mut self, entity_id: EntityId, cx: &mut Context<Self>) {
let Some(session) = self
.sessions
.iter()
.find(|other| entity_id == other.entity_id())
else {
return;
};
session.update(cx, |session, cx| session.shutdown(cx));
self.sessions.retain(|other| entity_id != other.entity_id());
if let Some(active_session_id) = self
.active_session
.as_ref()
.map(|session| session.entity_id())
{
if active_session_id == entity_id {
self.active_session = self.sessions.first().cloned();
}
}
}
fn sessions_drop_down_menu(
&self,
active_session: &Entity<DebugSession>,
window: &mut Window,
cx: &mut Context<Self>,
) -> DropdownMenu {
let sessions = self.sessions.clone();
let weak = cx.weak_entity();
let label = active_session.read(cx).label_element(cx);
DropdownMenu::new_with_element(
"debugger-session-list",
label,
ContextMenu::build(window, cx, move |mut this, _, _| {
for session in sessions.into_iter() {
let weak_session = session.downgrade();
let weak_id = weak_session.entity_id();
this = this.custom_entry(
{
let weak = weak.clone();
move |_, cx| {
weak_session
.read_with(cx, |session, cx| {
h_flex()
.w_full()
.justify_between()
.child(session.label_element(cx))
.child(
IconButton::new(
"close-debug-session",
IconName::Close,
)
.icon_size(IconSize::Small)
.on_click({
let weak = weak.clone();
move |_, _, cx| {
weak.update(cx, |panel, cx| {
panel.close_session(weak_id, cx);
})
.ok();
}
}),
)
.into_any_element()
})
.unwrap_or_else(|_| div().into_any_element())
}
},
{
let weak = weak.clone();
move |window, cx| {
weak.update(cx, |panel, cx| {
panel.activate_session(session.clone(), window, cx);
})
.ok();
}
},
);
}
this
}),
)
}
fn top_controls_strip(&self, window: &mut Window, cx: &mut Context<Self>) -> Option<Div> {
let active_session = self.active_session.clone();
@ -529,34 +618,8 @@ impl DebugPanel {
},
)
.when_some(active_session.as_ref(), |this, session| {
let sessions = self.sessions.clone();
let weak = cx.weak_entity();
let label = session.read(cx).label(cx);
this.child(DropdownMenu::new(
"debugger-session-list",
label,
ContextMenu::build(window, cx, move |mut this, _, cx| {
for item in sessions {
let weak = weak.clone();
this = this.entry(
session.read(cx).label(cx),
None,
move |window, cx| {
weak.update(cx, |panel, cx| {
panel.activate_session(
item.clone(),
window,
cx,
);
})
.ok();
},
);
}
this
}),
))
.child(Divider::vertical())
let context_menu = self.sessions_drop_down_menu(session, window, cx);
this.child(context_menu).child(Divider::vertical())
})
.child(
IconButton::new("debug-new-session", IconName::Plus)