From bbffe1ec2cc40b5cbcfd66b0f83a117eaed0b0a6 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 7 May 2025 00:27:50 +0200 Subject: [PATCH] debugger: Unify landing state for new session modal (#30046) Closes #ISSUE Release Notes: - N/A --- ...{debug_disconnect.svg => debug_detach.svg} | 0 crates/debugger_ui/src/debugger_panel.rs | 77 ++++++++----------- crates/debugger_ui/src/debugger_ui.rs | 35 +-------- crates/debugger_ui/src/new_session_modal.rs | 14 +++- crates/debugger_ui/src/session.rs | 16 ++-- crates/debugger_ui/src/session/running.rs | 15 ++-- crates/icons/src/icons.rs | 2 +- 7 files changed, 58 insertions(+), 101 deletions(-) rename assets/icons/{debug_disconnect.svg => debug_detach.svg} (100%) diff --git a/assets/icons/debug_disconnect.svg b/assets/icons/debug_detach.svg similarity index 100% rename from assets/icons/debug_disconnect.svg rename to assets/icons/debug_detach.svg diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 50ac46d01a..6691a9ee69 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -1,11 +1,10 @@ use crate::persistence::DebuggerPaneItem; +use crate::session::DebugSession; use crate::{ - ClearAllBreakpoints, Continue, CreateDebuggingSession, Disconnect, FocusBreakpointList, - FocusConsole, FocusFrames, FocusLoadedSources, FocusModules, FocusTerminal, FocusVariables, - Pause, Restart, StepBack, StepInto, StepOut, StepOver, Stop, ToggleIgnoreBreakpoints, - persistence, + ClearAllBreakpoints, Continue, Detach, FocusBreakpointList, FocusConsole, FocusFrames, + FocusLoadedSources, FocusModules, FocusTerminal, FocusVariables, Pause, Restart, StepBack, + StepInto, StepOut, StepOver, Stop, ToggleIgnoreBreakpoints, persistence, }; -use crate::{new_session_modal::NewSessionModal, session::DebugSession}; use anyhow::Result; use command_palette_hooks::CommandPaletteFilter; use dap::adapters::DebugAdapterName; @@ -110,7 +109,7 @@ impl DebugPanel { let filter = CommandPaletteFilter::global_mut(cx); let debugger_action_types = [ - TypeId::of::(), + TypeId::of::(), TypeId::of::(), TypeId::of::(), ]; @@ -609,52 +608,19 @@ impl DebugPanel { let focus_handle = self.focus_handle.clone(); let is_side = self.position(window, cx).axis() == gpui::Axis::Horizontal; let div = if is_side { v_flex() } else { h_flex() }; - let weak_panel = cx.weak_entity(); let new_session_button = || { IconButton::new("debug-new-session", IconName::Plus) .icon_size(IconSize::Small) .on_click({ - let workspace = self.workspace.clone(); - let weak_panel = weak_panel.clone(); - let past_debug_definition = self.past_debug_definition.clone(); - move |_, window, cx| { - let weak_panel = weak_panel.clone(); - let past_debug_definition = past_debug_definition.clone(); - let workspace = workspace.clone(); - window - .spawn(cx, async move |cx| { - let task_contexts = workspace - .update_in(cx, |workspace, window, cx| { - tasks_ui::task_contexts(workspace, window, cx) - })? - .await; - - workspace.update_in(cx, |this, window, cx| { - this.toggle_modal(window, cx, |window, cx| { - NewSessionModal::new( - past_debug_definition, - weak_panel, - workspace.clone(), - None, - task_contexts, - window, - cx, - ) - }); - })?; - - Result::<_, anyhow::Error>::Ok(()) - }) - .detach(); - } + move |_, window, cx| window.dispatch_action(crate::Start.boxed_clone(), cx) }) .tooltip({ let focus_handle = focus_handle.clone(); move |window, cx| { Tooltip::for_action_in( - "New Debug Session", - &CreateDebuggingSession, + "Start Debug Session", + &crate::Start, &focus_handle, window, cx, @@ -920,6 +886,28 @@ impl DebugPanel { } }), ) + .child( + IconButton::new("debug-disconnect", IconName::DebugDetach) + .icon_size(IconSize::XSmall) + .on_click(window.listener_for( + &running_session, + |this, _, _, cx| { + this.detach_client(cx); + }, + )) + .tooltip({ + let focus_handle = focus_handle.clone(); + move |window, cx| { + Tooltip::for_action_in( + "Detach", + &Detach, + &focus_handle, + window, + cx, + ) + } + }), + ) }, ), ) @@ -1270,10 +1258,7 @@ impl Render for DebugPanel { Button::new("spawn-new-session-empty-state", "New Session") .size(ButtonSize::Large) .on_click(|_, window, cx| { - window.dispatch_action( - CreateDebuggingSession.boxed_clone(), - cx, - ); + window.dispatch_action(crate::Start.boxed_clone(), cx); }), ), ), diff --git a/crates/debugger_ui/src/debugger_ui.rs b/crates/debugger_ui/src/debugger_ui.rs index b8ef6e1217..747c6d72a4 100644 --- a/crates/debugger_ui/src/debugger_ui.rs +++ b/crates/debugger_ui/src/debugger_ui.rs @@ -24,7 +24,7 @@ actions!( [ Start, Continue, - Disconnect, + Detach, Pause, Restart, StepInto, @@ -34,7 +34,6 @@ actions!( Stop, ToggleIgnoreBreakpoints, ClearAllBreakpoints, - CreateDebuggingSession, FocusConsole, FocusVariables, FocusBreakpointList, @@ -147,38 +146,6 @@ pub fn init(cx: &mut App) { }) }, ) - .register_action( - |workspace: &mut Workspace, _: &CreateDebuggingSession, window, cx| { - if let Some(debug_panel) = workspace.panel::(cx) { - let weak_panel = debug_panel.downgrade(); - let weak_workspace = cx.weak_entity(); - - cx.spawn_in(window, async move |this, cx| { - let task_contexts = this - .update_in(cx, |workspace, window, cx| { - tasks_ui::task_contexts(workspace, window, cx) - })? - .await; - this.update_in(cx, |workspace, window, cx| { - workspace.toggle_modal(window, cx, |window, cx| { - NewSessionModal::new( - debug_panel.read(cx).past_debug_definition.clone(), - weak_panel, - weak_workspace, - None, - task_contexts, - window, - cx, - ) - }); - })?; - - Result::<_, anyhow::Error>::Ok(()) - }) - .detach(); - } - }, - ) .register_action(|workspace: &mut Workspace, _: &Start, window, cx| { if let Some(debug_panel) = workspace.panel::(cx) { let weak_panel = debug_panel.downgrade(); diff --git a/crates/debugger_ui/src/new_session_modal.rs b/crates/debugger_ui/src/new_session_modal.rs index d82982e453..ecb1c7f893 100644 --- a/crates/debugger_ui/src/new_session_modal.rs +++ b/crates/debugger_ui/src/new_session_modal.rs @@ -629,9 +629,7 @@ impl Render for NewSessionModal { ), ) .justify_between() - .when(!matches!(self.mode, NewSessionMode::Scenario(_)), |this| { - this.children(self.adapter_drop_down_menu(window, cx)) - }) + .children(self.adapter_drop_down_menu(window, cx)) .border_color(cx.theme().colors().border_variant) .border_b_1(), ) @@ -644,7 +642,15 @@ impl Render for NewSessionModal { .border_color(cx.theme().colors().border_variant) .border_t_1() .w_full() - .child(self.debug_config_drop_down_menu(window, cx)) + .child( + matches!(self.mode, NewSessionMode::Scenario(_)) + .not() + .then(|| { + self.debug_config_drop_down_menu(window, cx) + .into_any_element() + }) + .unwrap_or_else(|| v_flex().w_full().into_any_element()), + ) .child( h_flex() .justify_end() diff --git a/crates/debugger_ui/src/session.rs b/crates/debugger_ui/src/session.rs index b70b8cdedf..bc1cb75cdd 100644 --- a/crates/debugger_ui/src/session.rs +++ b/crates/debugger_ui/src/session.rs @@ -103,14 +103,14 @@ impl DebugSession { pub(crate) fn label_element(&self, cx: &App) -> AnyElement { let label = self.label(cx); + let is_terminated = self + .running_state + .read(cx) + .session() + .read(cx) + .is_terminated(); let icon = { - if self - .running_state - .read(cx) - .session() - .read(cx) - .is_terminated() - { + if is_terminated { Some(Indicator::dot().color(Color::Error)) } else { match self @@ -131,7 +131,7 @@ impl DebugSession { .gap_2() .when_some(icon, |this, indicator| this.child(indicator)) .justify_between() - .child(Label::new(label)) + .child(Label::new(label).when(is_terminated, |this| this.strikethrough())) .into_any_element() } } diff --git a/crates/debugger_ui/src/session/running.rs b/crates/debugger_ui/src/session/running.rs index 5c2a769116..eda8a88577 100644 --- a/crates/debugger_ui/src/session/running.rs +++ b/crates/debugger_ui/src/session/running.rs @@ -44,9 +44,10 @@ use task::{ use terminal_view::TerminalView; use ui::{ ActiveTheme, AnyElement, App, ButtonCommon as _, Clickable as _, Context, ContextMenu, - DropdownMenu, FluentBuilder, IconButton, IconName, IconSize, InteractiveElement, IntoElement, - Label, LabelCommon as _, ParentElement, Render, SharedString, StatefulInteractiveElement, - Styled, Tab, Tooltip, VisibleOnHover, VisualContext, Window, div, h_flex, v_flex, + Disableable, DropdownMenu, FluentBuilder, IconButton, IconName, IconSize, InteractiveElement, + IntoElement, Label, LabelCommon as _, ParentElement, Render, SharedString, + StatefulInteractiveElement, Styled, Tab, Tooltip, VisibleOnHover, VisualContext, Window, div, + h_flex, v_flex, }; use util::ResultExt; use variable_list::VariableList; @@ -1420,11 +1421,7 @@ impl RunningState { }); } - #[expect( - unused, - reason = "Support for disconnecting a client is not wired through yet" - )] - pub fn disconnect_client(&self, cx: &mut Context) { + pub fn detach_client(&self, cx: &mut Context) { self.session().update(cx, |state, cx| { state.disconnect_client(cx); }); @@ -1442,6 +1439,7 @@ impl RunningState { cx: &mut Context<'_, RunningState>, ) -> DropdownMenu { let state = cx.entity(); + let session_terminated = self.session.read(cx).is_terminated(); let threads = self.session.update(cx, |this, cx| this.threads(cx)); let selected_thread_name = threads .iter() @@ -1464,6 +1462,7 @@ impl RunningState { this }), ) + .disabled(session_terminated) } fn default_pane_layout( diff --git a/crates/icons/src/icons.rs b/crates/icons/src/icons.rs index bdb371b0b2..3ee48e0e1b 100644 --- a/crates/icons/src/icons.rs +++ b/crates/icons/src/icons.rs @@ -81,7 +81,7 @@ pub enum IconName { DebugContinue, DebugDisabledBreakpoint, DebugDisabledLogBreakpoint, - DebugDisconnect, + DebugDetach, DebugIgnoreBreakpoints, DebugLogBreakpoint, DebugPause,