From 6f97da3435763619a6c377201f567f39a9928102 Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Mon, 2 Jun 2025 20:59:36 -0400 Subject: [PATCH] debugger: Align zoom behavior with other panels (#31901) Release Notes: - Debugger Beta: `shift-escape` (`workspace::ToggleZoom`) now zooms the entire debug panel; `alt-shift-escape` (`debugger::ToggleExpandItem`) triggers the old behavior of zooming a specific item. --- assets/keymaps/default-linux.json | 3 +- assets/keymaps/default-macos.json | 3 +- crates/debugger_ui/src/debugger_panel.rs | 48 ++++++++++++++++++++++- crates/debugger_ui/src/debugger_ui.rs | 1 + crates/debugger_ui/src/session/running.rs | 24 ++++-------- crates/workspace/src/pane.rs | 11 +++++- 6 files changed, 69 insertions(+), 21 deletions(-) diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index b652f8f488..0b463266f5 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -884,7 +884,8 @@ "context": "DebugPanel", "bindings": { "ctrl-t": "debugger::ToggleThreadPicker", - "ctrl-i": "debugger::ToggleSessionPicker" + "ctrl-i": "debugger::ToggleSessionPicker", + "shift-alt-escape": "debugger::ToggleExpandItem" } }, { diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index 18c4d88d22..75d35f3ed3 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -949,7 +949,8 @@ "context": "DebugPanel", "bindings": { "cmd-t": "debugger::ToggleThreadPicker", - "cmd-i": "debugger::ToggleSessionPicker" + "cmd-i": "debugger::ToggleSessionPicker", + "shift-alt-escape": "debugger::ToggleExpandItem" } }, { diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index ea98b44148..73858c4a38 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -5,8 +5,8 @@ use crate::{ ClearAllBreakpoints, Continue, Detach, FocusBreakpointList, FocusConsole, FocusFrames, FocusLoadedSources, FocusModules, FocusTerminal, FocusVariables, NewProcessModal, NewProcessMode, Pause, Restart, ShowStackTrace, StepBack, StepInto, StepOut, StepOver, Stop, - ToggleIgnoreBreakpoints, ToggleSessionPicker, ToggleThreadPicker, persistence, - spawn_task_or_modal, + ToggleExpandItem, ToggleIgnoreBreakpoints, ToggleSessionPicker, ToggleThreadPicker, + persistence, spawn_task_or_modal, }; use anyhow::Result; use command_palette_hooks::CommandPaletteFilter; @@ -70,6 +70,7 @@ pub struct DebugPanel { pub(crate) thread_picker_menu_handle: PopoverMenuHandle, pub(crate) session_picker_menu_handle: PopoverMenuHandle, fs: Arc, + is_zoomed: bool, _subscriptions: [Subscription; 1], } @@ -104,6 +105,7 @@ impl DebugPanel { fs: workspace.app_state().fs.clone(), thread_picker_menu_handle, session_picker_menu_handle, + is_zoomed: false, _subscriptions: [focus_subscription], debug_scenario_scheduled_last: true, } @@ -1021,6 +1023,22 @@ impl DebugPanel { pub(crate) fn toggle_session_picker(&mut self, window: &mut Window, cx: &mut Context) { self.session_picker_menu_handle.toggle(window, cx); } + + fn toggle_zoom( + &mut self, + _: &workspace::ToggleZoom, + window: &mut Window, + cx: &mut Context, + ) { + if self.is_zoomed { + cx.emit(PanelEvent::ZoomOut); + } else { + if !self.focus_handle(cx).contains_focused(window, cx) { + cx.focus_self(window); + } + cx.emit(PanelEvent::ZoomIn); + } + } } async fn register_session_inner( @@ -1176,6 +1194,15 @@ impl Panel for DebugPanel { } fn set_active(&mut self, _: bool, _: &mut Window, _: &mut Context) {} + + fn is_zoomed(&self, _window: &Window, _cx: &App) -> bool { + self.is_zoomed + } + + fn set_zoomed(&mut self, zoomed: bool, _window: &mut Window, cx: &mut Context) { + self.is_zoomed = zoomed; + cx.notify(); + } } impl Render for DebugPanel { @@ -1316,6 +1343,23 @@ impl Render for DebugPanel { .ok(); } }) + .on_action(cx.listener(Self::toggle_zoom)) + .on_action(cx.listener(|panel, _: &ToggleExpandItem, _, cx| { + let Some(session) = panel.active_session() else { + return; + }; + let active_pane = session + .read(cx) + .running_state() + .read(cx) + .active_pane() + .clone(); + active_pane.update(cx, |pane, cx| { + let is_zoomed = pane.is_zoomed(); + pane.set_zoomed(!is_zoomed, cx); + }); + cx.notify(); + })) .when(self.active_session.is_some(), |this| { this.on_mouse_down( MouseButton::Right, diff --git a/crates/debugger_ui/src/debugger_ui.rs b/crates/debugger_ui/src/debugger_ui.rs index 106c66ebae..996a86fb6b 100644 --- a/crates/debugger_ui/src/debugger_ui.rs +++ b/crates/debugger_ui/src/debugger_ui.rs @@ -49,6 +49,7 @@ actions!( ToggleThreadPicker, ToggleSessionPicker, RerunLastSession, + ToggleExpandItem, ] ); diff --git a/crates/debugger_ui/src/session/running.rs b/crates/debugger_ui/src/session/running.rs index 5b85b51faa..456f6d3d43 100644 --- a/crates/debugger_ui/src/session/running.rs +++ b/crates/debugger_ui/src/session/running.rs @@ -8,6 +8,7 @@ pub mod variable_list; use std::{any::Any, ops::ControlFlow, path::PathBuf, sync::Arc, time::Duration}; use crate::{ + ToggleExpandItem, new_process_modal::resolve_path, persistence::{self, DebuggerPaneItem, SerializedLayout}, }; @@ -347,6 +348,7 @@ pub(crate) fn new_debugger_pane( false } }))); + pane.set_can_toggle_zoom(false, cx); pane.display_nav_history_buttons(None); pane.set_custom_drop_handle(cx, custom_drop_handle); pane.set_should_display_tab_bar(|_, _| true); @@ -472,17 +474,19 @@ pub(crate) fn new_debugger_pane( }, ) .icon_size(IconSize::XSmall) - .on_click(cx.listener(move |pane, _, window, cx| { - pane.toggle_zoom(&workspace::ToggleZoom, window, cx); + .on_click(cx.listener(move |pane, _, _, cx| { + let is_zoomed = pane.is_zoomed(); + pane.set_zoomed(!is_zoomed, cx); + cx.notify(); })) .tooltip({ let focus_handle = focus_handle.clone(); move |window, cx| { let zoomed_text = - if zoomed { "Zoom Out" } else { "Zoom In" }; + if zoomed { "Minimize" } else { "Expand" }; Tooltip::for_action_in( zoomed_text, - &workspace::ToggleZoom, + &ToggleExpandItem, &focus_handle, window, cx, @@ -1260,18 +1264,6 @@ impl RunningState { Event::Focus => { this.active_pane = source_pane.clone(); } - Event::ZoomIn => { - source_pane.update(cx, |pane, cx| { - pane.set_zoomed(true, cx); - }); - cx.notify(); - } - Event::ZoomOut => { - source_pane.update(cx, |pane, cx| { - pane.set_zoomed(false, cx); - }); - cx.notify(); - } _ => {} } } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 58627fda97..6031109abd 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -311,6 +311,7 @@ pub struct Pane { >, can_split_predicate: Option) -> bool>>, + can_toggle_zoom: bool, should_display_tab_bar: Rc) -> bool>, render_tab_bar_buttons: Rc< dyn Fn( @@ -450,6 +451,7 @@ impl Pane { can_drop_predicate, custom_drop_handle: None, can_split_predicate: None, + can_toggle_zoom: true, should_display_tab_bar: Rc::new(|_, cx| TabBarSettings::get_global(cx).show), render_tab_bar_buttons: Rc::new(default_render_tab_bar_buttons), render_tab_bar: Rc::new(Self::render_tab_bar), @@ -650,6 +652,11 @@ impl Pane { self.can_split_predicate = can_split_predicate; } + pub fn set_can_toggle_zoom(&mut self, can_toggle_zoom: bool, cx: &mut Context) { + self.can_toggle_zoom = can_toggle_zoom; + cx.notify(); + } + pub fn set_close_pane_if_empty(&mut self, close_pane_if_empty: bool, cx: &mut Context) { self.close_pane_if_empty = close_pane_if_empty; cx.notify(); @@ -1104,7 +1111,9 @@ impl Pane { } pub fn toggle_zoom(&mut self, _: &ToggleZoom, window: &mut Window, cx: &mut Context) { - if self.zoomed { + if !self.can_toggle_zoom { + cx.propagate(); + } else if self.zoomed { cx.emit(Event::ZoomOut); } else if !self.items.is_empty() { if !self.focus_handle.contains_focused(window, cx) {