Detailed changes
@@ -862,6 +862,13 @@
"alt-l": "git::GenerateCommitMessage"
}
},
+ {
+ "context": "DebugPanel",
+ "bindings": {
+ "ctrl-t": "debugger::ToggleThreadPicker",
+ "ctrl-i": "debugger::ToggleSessionPicker"
+ }
+ },
{
"context": "CollabPanel && not_editing",
"bindings": {
@@ -929,6 +929,13 @@
"alt-tab": "git::GenerateCommitMessage"
}
},
+ {
+ "context": "DebugPanel",
+ "bindings": {
+ "cmd-t": "debugger::ToggleThreadPicker",
+ "cmd-i": "debugger::ToggleSessionPicker"
+ }
+ },
{
"context": "CollabPanel && not_editing",
"use_key_equivalents": true,
@@ -5,7 +5,7 @@ use crate::{
ClearAllBreakpoints, Continue, Detach, FocusBreakpointList, FocusConsole, FocusFrames,
FocusLoadedSources, FocusModules, FocusTerminal, FocusVariables, Pause, Restart,
ShowStackTrace, StepBack, StepInto, StepOut, StepOver, Stop, ToggleIgnoreBreakpoints,
- persistence,
+ ToggleSessionPicker, ToggleThreadPicker, persistence,
};
use anyhow::{Context as _, Result, anyhow};
use command_palette_hooks::CommandPaletteFilter;
@@ -31,7 +31,7 @@ use settings::Settings;
use std::any::TypeId;
use std::sync::Arc;
use task::{DebugScenario, TaskContext};
-use ui::{ContextMenu, Divider, Tooltip, prelude::*};
+use ui::{ContextMenu, Divider, PopoverMenuHandle, Tooltip, prelude::*};
use workspace::SplitDirection;
use workspace::{
Pane, Workspace,
@@ -65,6 +65,8 @@ pub struct DebugPanel {
workspace: WeakEntity<Workspace>,
focus_handle: FocusHandle,
context_menu: Option<(Entity<ContextMenu>, Point<Pixels>, Subscription)>,
+ pub(crate) thread_picker_menu_handle: PopoverMenuHandle<ContextMenu>,
+ pub(crate) session_picker_menu_handle: PopoverMenuHandle<ContextMenu>,
fs: Arc<dyn Fs>,
}
@@ -77,6 +79,8 @@ impl DebugPanel {
cx.new(|cx| {
let project = workspace.project().clone();
let focus_handle = cx.focus_handle();
+ let thread_picker_menu_handle = PopoverMenuHandle::default();
+ let session_picker_menu_handle = PopoverMenuHandle::default();
let debug_panel = Self {
size: px(300.),
@@ -87,6 +91,8 @@ impl DebugPanel {
workspace: workspace.weak_handle(),
context_menu: None,
fs: workspace.app_state().fs.clone(),
+ thread_picker_menu_handle,
+ session_picker_menu_handle,
};
debug_panel
@@ -1033,6 +1039,14 @@ impl DebugPanel {
})
.unwrap_or_else(|err| Task::ready(Err(err)))
}
+
+ pub(crate) fn toggle_thread_picker(&mut self, window: &mut Window, cx: &mut Context<Self>) {
+ self.thread_picker_menu_handle.toggle(window, cx);
+ }
+
+ pub(crate) fn toggle_session_picker(&mut self, window: &mut Window, cx: &mut Context<Self>) {
+ self.session_picker_menu_handle.toggle(window, cx);
+ }
}
impl EventEmitter<PanelEvent> for DebugPanel {}
@@ -1249,6 +1263,24 @@ impl Render for DebugPanel {
.ok();
}
})
+ .on_action({
+ let this = this.clone();
+ move |_: &ToggleThreadPicker, window, cx| {
+ this.update(cx, |this, cx| {
+ this.toggle_thread_picker(window, cx);
+ })
+ .ok();
+ }
+ })
+ .on_action({
+ let this = this.clone();
+ move |_: &ToggleSessionPicker, window, cx| {
+ this.update(cx, |this, cx| {
+ this.toggle_session_picker(window, cx);
+ })
+ .ok();
+ }
+ })
.when(self.active_session.is_some(), |this| {
this.on_mouse_down(
MouseButton::Right,
@@ -45,6 +45,8 @@ actions!(
FocusLoadedSources,
FocusTerminal,
ShowStackTrace,
+ ToggleThreadPicker,
+ ToggleSessionPicker,
]
);
@@ -132,7 +132,8 @@ impl DebugPanel {
this
}),
)
- .style(DropdownStyle::Ghost),
+ .style(DropdownStyle::Ghost)
+ .handle(self.session_picker_menu_handle.clone()),
)
} else {
None
@@ -163,7 +164,7 @@ impl DebugPanel {
DropdownMenu::new_with_element(
("thread-list", session_id.0),
trigger,
- ContextMenu::build_eager(window, cx, move |mut this, _, _| {
+ ContextMenu::build(window, cx, move |mut this, _, _| {
for (thread, _) in threads {
let running_state = running_state.clone();
let thread_id = thread.id;
@@ -177,7 +178,8 @@ impl DebugPanel {
}),
)
.disabled(session_terminated)
- .style(DropdownStyle::Ghost),
+ .style(DropdownStyle::Ghost)
+ .handle(self.thread_picker_menu_handle.clone()),
)
} else {
None
@@ -96,7 +96,7 @@ impl Render for RunningState {
.find(|pane| pane.read(cx).is_zoomed());
let active = self.panes.panes().into_iter().next();
- let x = if let Some(ref zoomed_pane) = zoomed_pane {
+ let pane = if let Some(ref zoomed_pane) = zoomed_pane {
zoomed_pane.update(cx, |pane, cx| pane.render(window, cx).into_any_element())
} else if let Some(active) = active {
self.panes
@@ -122,7 +122,7 @@ impl Render for RunningState {
.size_full()
.key_context("DebugSessionItem")
.track_focus(&self.focus_handle(cx))
- .child(h_flex().flex_1().child(x))
+ .child(h_flex().flex_1().child(pane))
}
}
@@ -154,7 +154,6 @@ pub struct ContextMenu {
key_context: SharedString,
_on_blur_subscription: Subscription,
keep_open_on_confirm: bool,
- eager: bool,
documentation_aside: Option<(usize, DocumentationAside)>,
fixed_width: Option<DefiniteLength>,
}
@@ -207,7 +206,6 @@ impl ContextMenu {
key_context: "menu".into(),
_on_blur_subscription,
keep_open_on_confirm: false,
- eager: false,
documentation_aside: None,
fixed_width: None,
end_slot_action: None,
@@ -250,43 +248,6 @@ impl ContextMenu {
key_context: "menu".into(),
_on_blur_subscription,
keep_open_on_confirm: true,
- eager: false,
- documentation_aside: None,
- fixed_width: None,
- end_slot_action: None,
- },
- window,
- cx,
- )
- })
- }
-
- pub fn build_eager(
- window: &mut Window,
- cx: &mut App,
- f: impl FnOnce(Self, &mut Window, &mut Context<Self>) -> Self,
- ) -> Entity<Self> {
- cx.new(|cx| {
- let focus_handle = cx.focus_handle();
- let _on_blur_subscription = cx.on_blur(
- &focus_handle,
- window,
- |this: &mut ContextMenu, window, cx| this.cancel(&menu::Cancel, window, cx),
- );
- window.refresh();
- f(
- Self {
- builder: None,
- items: Default::default(),
- focus_handle,
- action_context: None,
- selected_index: None,
- delayed: false,
- clicked: false,
- key_context: "menu".into(),
- _on_blur_subscription,
- keep_open_on_confirm: false,
- eager: true,
documentation_aside: None,
fixed_width: None,
end_slot_action: None,
@@ -327,7 +288,6 @@ impl ContextMenu {
|this: &mut ContextMenu, window, cx| this.cancel(&menu::Cancel, window, cx),
),
keep_open_on_confirm: false,
- eager: false,
documentation_aside: None,
fixed_width: None,
end_slot_action: None,
@@ -634,10 +594,7 @@ impl ContextMenu {
..
})
| ContextMenuItem::CustomEntry { handler, .. },
- ) = self
- .selected_index
- .and_then(|ix| self.items.get(ix))
- .filter(|_| !self.eager)
+ ) = self.selected_index.and_then(|ix| self.items.get(ix))
{
(handler)(context, window, cx)
}
@@ -740,10 +697,9 @@ impl ContextMenu {
fn select_index(
&mut self,
ix: usize,
- window: &mut Window,
- cx: &mut Context<Self>,
+ _window: &mut Window,
+ _cx: &mut Context<Self>,
) -> Option<usize> {
- let context = self.action_context.as_ref();
self.documentation_aside = None;
let item = self.items.get(ix)?;
if item.is_selectable() {
@@ -752,9 +708,6 @@ impl ContextMenu {
if let Some(callback) = &entry.documentation_aside {
self.documentation_aside = Some((ix, callback.clone()));
}
- if self.eager && !entry.disabled {
- (entry.handler)(context, window, cx)
- }
}
}
Some(ix)
@@ -2,6 +2,8 @@ use gpui::{ClickEvent, Corner, CursorStyle, Entity, Hsla, MouseButton};
use crate::{ContextMenu, PopoverMenu, prelude::*};
+use super::PopoverMenuHandle;
+
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DropdownStyle {
#[default]
@@ -22,6 +24,7 @@ pub struct DropdownMenu {
menu: Entity<ContextMenu>,
full_width: bool,
disabled: bool,
+ handle: Option<PopoverMenuHandle<ContextMenu>>,
}
impl DropdownMenu {
@@ -37,6 +40,7 @@ impl DropdownMenu {
menu,
full_width: false,
disabled: false,
+ handle: None,
}
}
@@ -52,6 +56,7 @@ impl DropdownMenu {
menu,
full_width: false,
disabled: false,
+ handle: None,
}
}
@@ -64,6 +69,11 @@ impl DropdownMenu {
self.full_width = full_width;
self
}
+
+ pub fn handle(mut self, handle: PopoverMenuHandle<ContextMenu>) -> Self {
+ self.handle = Some(handle);
+ self
+ }
}
impl Disableable for DropdownMenu {
@@ -85,6 +95,7 @@ impl RenderOnce for DropdownMenu {
.style(self.style),
)
.attach(Corner::BottomLeft)
+ .when_some(self.handle.clone(), |el, handle| el.with_handle(handle))
}
}
@@ -159,17 +170,11 @@ pub struct DropdownTriggerStyle {
impl DropdownTriggerStyle {
pub fn for_style(style: DropdownStyle, cx: &App) -> Self {
let colors = cx.theme().colors();
-
- if style == DropdownStyle::Solid {
- Self {
- // why is this editor_background?
- bg: colors.editor_background,
- }
- } else {
- Self {
- bg: colors.ghost_element_background,
- }
- }
+ let bg = match style {
+ DropdownStyle::Solid => colors.editor_background,
+ DropdownStyle::Ghost => colors.ghost_element_background,
+ };
+ Self { bg }
}
}