@@ -9,6 +9,7 @@ use crate::{new_session_modal::NewSessionModal, session::DebugSession};
use anyhow::Result;
use command_palette_hooks::CommandPaletteFilter;
use dap::adapters::DebugAdapterName;
+use dap::debugger_settings::DebugPanelDockPosition;
use dap::{
ContinuedEvent, LoadedSourceEvent, ModuleEvent, OutputEvent, StoppedEvent, ThreadEvent,
client::SessionId, debugger_settings::DebuggerSettings,
@@ -21,11 +22,13 @@ use gpui::{
};
use language::Buffer;
+use project::Fs;
use project::debugger::session::{Session, SessionStateEvent};
use project::{Project, debugger::session::ThreadStatus};
use rpc::proto::{self};
use settings::Settings;
use std::any::TypeId;
+use std::sync::Arc;
use task::{DebugScenario, TaskContext};
use ui::{ContextMenu, Divider, DropdownMenu, Tooltip, prelude::*};
use workspace::SplitDirection;
@@ -62,6 +65,7 @@ pub struct DebugPanel {
workspace: WeakEntity<Workspace>,
focus_handle: FocusHandle,
context_menu: Option<(Entity<ContextMenu>, Point<Pixels>, Subscription)>,
+ fs: Arc<dyn Fs>,
}
impl DebugPanel {
@@ -82,6 +86,7 @@ impl DebugPanel {
project,
workspace: workspace.weak_handle(),
context_menu: None,
+ fs: workspace.app_state().fs.clone(),
};
debug_panel
@@ -284,7 +289,7 @@ impl DebugPanel {
})
.ok();
- let serialized_layout = persistence::get_serialized_pane_layout(adapter_name).await;
+ let serialized_layout = persistence::get_serialized_layout(adapter_name).await;
let (debug_session, workspace) = this.update_in(cx, |this, window, cx| {
this.sessions.retain(|session| {
@@ -303,6 +308,7 @@ impl DebugPanel {
session,
cx.weak_entity(),
serialized_layout,
+ this.position(window, cx).axis(),
window,
cx,
);
@@ -599,43 +605,143 @@ impl DebugPanel {
fn top_controls_strip(&self, window: &mut Window, cx: &mut Context<Self>) -> Option<Div> {
let active_session = self.active_session.clone();
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.update(cx, |this, cx| {
+ let workspace = cx.weak_entity();
+ this.toggle_modal(window, cx, |window, cx| {
+ NewSessionModal::new(
+ past_debug_definition,
+ weak_panel,
+ workspace,
+ None,
+ window,
+ cx,
+ )
+ });
+ });
+ }
+ })
+ .tooltip({
+ let focus_handle = focus_handle.clone();
+ move |window, cx| {
+ Tooltip::for_action_in(
+ "New Debug Session",
+ &CreateDebuggingSession,
+ &focus_handle,
+ window,
+ cx,
+ )
+ }
+ })
+ };
Some(
- h_flex()
- .border_b_1()
+ div.border_b_1()
.border_color(cx.theme().colors().border)
.p_1()
.justify_between()
.w_full()
+ .when(is_side, |this| this.gap_1())
.child(
- h_flex().gap_2().w_full().when_some(
- active_session
- .as_ref()
- .map(|session| session.read(cx).running_state()),
- |this, running_session| {
- let thread_status = running_session
- .read(cx)
- .thread_status(cx)
- .unwrap_or(project::debugger::session::ThreadStatus::Exited);
- let capabilities = running_session.read(cx).capabilities(cx);
- this.map(|this| {
- if thread_status == ThreadStatus::Running {
- this.child(
- IconButton::new("debug-pause", IconName::DebugPause)
+ h_flex()
+ .child(
+ h_flex().gap_2().w_full().when_some(
+ active_session
+ .as_ref()
+ .map(|session| session.read(cx).running_state()),
+ |this, running_session| {
+ let thread_status =
+ running_session.read(cx).thread_status(cx).unwrap_or(
+ project::debugger::session::ThreadStatus::Exited,
+ );
+ let capabilities = running_session.read(cx).capabilities(cx);
+ this.map(|this| {
+ if thread_status == ThreadStatus::Running {
+ this.child(
+ IconButton::new(
+ "debug-pause",
+ IconName::DebugPause,
+ )
+ .icon_size(IconSize::XSmall)
+ .shape(ui::IconButtonShape::Square)
+ .on_click(window.listener_for(
+ &running_session,
+ |this, _, _window, cx| {
+ this.pause_thread(cx);
+ },
+ ))
+ .tooltip({
+ let focus_handle = focus_handle.clone();
+ move |window, cx| {
+ Tooltip::for_action_in(
+ "Pause program",
+ &Pause,
+ &focus_handle,
+ window,
+ cx,
+ )
+ }
+ }),
+ )
+ } else {
+ this.child(
+ IconButton::new(
+ "debug-continue",
+ IconName::DebugContinue,
+ )
+ .icon_size(IconSize::XSmall)
+ .shape(ui::IconButtonShape::Square)
+ .on_click(window.listener_for(
+ &running_session,
+ |this, _, _window, cx| this.continue_thread(cx),
+ ))
+ .disabled(thread_status != ThreadStatus::Stopped)
+ .tooltip({
+ let focus_handle = focus_handle.clone();
+ move |window, cx| {
+ Tooltip::for_action_in(
+ "Continue program",
+ &Continue,
+ &focus_handle,
+ window,
+ cx,
+ )
+ }
+ }),
+ )
+ }
+ })
+ .child(
+ IconButton::new("debug-step-over", IconName::ArrowRight)
.icon_size(IconSize::XSmall)
.shape(ui::IconButtonShape::Square)
.on_click(window.listener_for(
&running_session,
|this, _, _window, cx| {
- this.pause_thread(cx);
+ this.step_over(cx);
},
))
+ .disabled(thread_status != ThreadStatus::Stopped)
.tooltip({
let focus_handle = focus_handle.clone();
move |window, cx| {
Tooltip::for_action_in(
- "Pause program",
- &Pause,
+ "Step over",
+ &StepOver,
&focus_handle,
window,
cx,
@@ -643,22 +749,23 @@ impl DebugPanel {
}
}),
)
- } else {
- this.child(
- IconButton::new("debug-continue", IconName::DebugContinue)
+ .child(
+ IconButton::new("debug-step-out", IconName::ArrowUpRight)
.icon_size(IconSize::XSmall)
.shape(ui::IconButtonShape::Square)
.on_click(window.listener_for(
&running_session,
- |this, _, _window, cx| this.continue_thread(cx),
+ |this, _, _window, cx| {
+ this.step_out(cx);
+ },
))
.disabled(thread_status != ThreadStatus::Stopped)
.tooltip({
let focus_handle = focus_handle.clone();
move |window, cx| {
Tooltip::for_action_in(
- "Continue program",
- &Continue,
+ "Step out",
+ &StepOut,
&focus_handle,
window,
cx,
@@ -666,240 +773,173 @@ impl DebugPanel {
}
}),
)
- }
- })
- .child(
- IconButton::new("debug-step-over", IconName::ArrowRight)
- .icon_size(IconSize::XSmall)
- .shape(ui::IconButtonShape::Square)
- .on_click(window.listener_for(
- &running_session,
- |this, _, _window, cx| {
- this.step_over(cx);
- },
- ))
- .disabled(thread_status != ThreadStatus::Stopped)
- .tooltip({
- let focus_handle = focus_handle.clone();
- move |window, cx| {
- Tooltip::for_action_in(
- "Step over",
- &StepOver,
- &focus_handle,
- window,
- cx,
- )
- }
- }),
- )
- .child(
- IconButton::new("debug-step-out", IconName::ArrowUpRight)
- .icon_size(IconSize::XSmall)
- .shape(ui::IconButtonShape::Square)
- .on_click(window.listener_for(
- &running_session,
- |this, _, _window, cx| {
- this.step_out(cx);
- },
- ))
- .disabled(thread_status != ThreadStatus::Stopped)
- .tooltip({
- let focus_handle = focus_handle.clone();
- move |window, cx| {
- Tooltip::for_action_in(
- "Step out",
- &StepOut,
- &focus_handle,
- window,
- cx,
- )
- }
- }),
- )
- .child(
- IconButton::new("debug-step-into", IconName::ArrowDownRight)
- .icon_size(IconSize::XSmall)
- .shape(ui::IconButtonShape::Square)
- .on_click(window.listener_for(
- &running_session,
- |this, _, _window, cx| {
- this.step_in(cx);
- },
- ))
- .disabled(thread_status != ThreadStatus::Stopped)
- .tooltip({
- let focus_handle = focus_handle.clone();
- move |window, cx| {
- Tooltip::for_action_in(
- "Step in",
- &StepInto,
- &focus_handle,
- window,
- cx,
- )
- }
- }),
- )
- .child(Divider::vertical())
- .child(
- IconButton::new(
- "debug-enable-breakpoint",
- IconName::DebugDisabledBreakpoint,
- )
- .icon_size(IconSize::XSmall)
- .shape(ui::IconButtonShape::Square)
- .disabled(thread_status != ThreadStatus::Stopped),
- )
- .child(
- IconButton::new("debug-disable-breakpoint", IconName::CircleOff)
- .icon_size(IconSize::XSmall)
- .shape(ui::IconButtonShape::Square)
- .disabled(thread_status != ThreadStatus::Stopped),
- )
- .child(
- IconButton::new("debug-disable-all-breakpoints", IconName::BugOff)
- .icon_size(IconSize::XSmall)
- .shape(ui::IconButtonShape::Square)
- .disabled(
- thread_status == ThreadStatus::Exited
- || thread_status == ThreadStatus::Ended,
+ .child(
+ IconButton::new(
+ "debug-step-into",
+ IconName::ArrowDownRight,
+ )
+ .icon_size(IconSize::XSmall)
+ .shape(ui::IconButtonShape::Square)
+ .on_click(window.listener_for(
+ &running_session,
+ |this, _, _window, cx| {
+ this.step_in(cx);
+ },
+ ))
+ .disabled(thread_status != ThreadStatus::Stopped)
+ .tooltip({
+ let focus_handle = focus_handle.clone();
+ move |window, cx| {
+ Tooltip::for_action_in(
+ "Step in",
+ &StepInto,
+ &focus_handle,
+ window,
+ cx,
+ )
+ }
+ }),
)
- .on_click(window.listener_for(
- &running_session,
- |this, _, _window, cx| {
- this.toggle_ignore_breakpoints(cx);
- },
- ))
- .tooltip({
- let focus_handle = focus_handle.clone();
- move |window, cx| {
- Tooltip::for_action_in(
- "Disable all breakpoints",
- &ToggleIgnoreBreakpoints,
- &focus_handle,
- window,
- cx,
- )
- }
- }),
- )
- .child(Divider::vertical())
- .child(
- IconButton::new("debug-restart", IconName::DebugRestart)
- .icon_size(IconSize::XSmall)
- .on_click(window.listener_for(
- &running_session,
- |this, _, _window, cx| {
- this.restart_session(cx);
- },
- ))
- .tooltip({
- let focus_handle = focus_handle.clone();
- move |window, cx| {
- Tooltip::for_action_in(
- "Restart",
- &Restart,
- &focus_handle,
- window,
- cx,
- )
- }
- }),
- )
- .child(
- IconButton::new("debug-stop", IconName::Power)
- .icon_size(IconSize::XSmall)
- .on_click(window.listener_for(
- &running_session,
- |this, _, _window, cx| {
- this.stop_thread(cx);
- },
- ))
- .disabled(
- thread_status != ThreadStatus::Stopped
- && thread_status != ThreadStatus::Running,
+ .child(Divider::vertical())
+ .child(
+ IconButton::new(
+ "debug-enable-breakpoint",
+ IconName::DebugDisabledBreakpoint,
+ )
+ .icon_size(IconSize::XSmall)
+ .shape(ui::IconButtonShape::Square)
+ .disabled(thread_status != ThreadStatus::Stopped),
)
- .tooltip({
- let focus_handle = focus_handle.clone();
- let label = if capabilities
- .supports_terminate_threads_request
- .unwrap_or_default()
- {
- "Terminate Thread"
- } else {
- "Terminate All Threads"
- };
- move |window, cx| {
- Tooltip::for_action_in(
- label,
- &Stop,
- &focus_handle,
- window,
- cx,
+ .child(
+ IconButton::new(
+ "debug-disable-breakpoint",
+ IconName::CircleOff,
+ )
+ .icon_size(IconSize::XSmall)
+ .shape(ui::IconButtonShape::Square)
+ .disabled(thread_status != ThreadStatus::Stopped),
+ )
+ .child(
+ IconButton::new(
+ "debug-disable-all-breakpoints",
+ IconName::BugOff,
+ )
+ .icon_size(IconSize::XSmall)
+ .shape(ui::IconButtonShape::Square)
+ .disabled(
+ thread_status == ThreadStatus::Exited
+ || thread_status == ThreadStatus::Ended,
+ )
+ .on_click(window.listener_for(
+ &running_session,
+ |this, _, _window, cx| {
+ this.toggle_ignore_breakpoints(cx);
+ },
+ ))
+ .tooltip({
+ let focus_handle = focus_handle.clone();
+ move |window, cx| {
+ Tooltip::for_action_in(
+ "Disable all breakpoints",
+ &ToggleIgnoreBreakpoints,
+ &focus_handle,
+ window,
+ cx,
+ )
+ }
+ }),
+ )
+ .child(Divider::vertical())
+ .child(
+ IconButton::new("debug-restart", IconName::DebugRestart)
+ .icon_size(IconSize::XSmall)
+ .on_click(window.listener_for(
+ &running_session,
+ |this, _, _window, cx| {
+ this.restart_session(cx);
+ },
+ ))
+ .tooltip({
+ let focus_handle = focus_handle.clone();
+ move |window, cx| {
+ Tooltip::for_action_in(
+ "Restart",
+ &Restart,
+ &focus_handle,
+ window,
+ cx,
+ )
+ }
+ }),
+ )
+ .child(
+ IconButton::new("debug-stop", IconName::Power)
+ .icon_size(IconSize::XSmall)
+ .on_click(window.listener_for(
+ &running_session,
+ |this, _, _window, cx| {
+ this.stop_thread(cx);
+ },
+ ))
+ .disabled(
+ thread_status != ThreadStatus::Stopped
+ && thread_status != ThreadStatus::Running,
)
- }
- }),
- )
- },
- ),
+ .tooltip({
+ let focus_handle = focus_handle.clone();
+ let label = if capabilities
+ .supports_terminate_threads_request
+ .unwrap_or_default()
+ {
+ "Terminate Thread"
+ } else {
+ "Terminate All Threads"
+ };
+ move |window, cx| {
+ Tooltip::for_action_in(
+ label,
+ &Stop,
+ &focus_handle,
+ window,
+ cx,
+ )
+ }
+ }),
+ )
+ },
+ ),
+ )
+ .justify_around()
+ .when(is_side, |this| this.child(new_session_button())),
)
.child(
h_flex()
.gap_2()
- .when_some(
- active_session
- .as_ref()
- .map(|session| session.read(cx).running_state())
- .cloned(),
- |this, session| {
- this.child(
- session.update(cx, |this, cx| this.thread_dropdown(window, cx)),
- )
- .child(Divider::vertical())
- },
+ .when(is_side, |this| this.justify_between())
+ .child(
+ h_flex().when_some(
+ active_session
+ .as_ref()
+ .map(|session| session.read(cx).running_state())
+ .cloned(),
+ |this, session| {
+ this.child(
+ session.update(cx, |this, cx| {
+ this.thread_dropdown(window, cx)
+ }),
+ )
+ .when(!is_side, |this| this.gap_2().child(Divider::vertical()))
+ },
+ ),
)
- .when_some(active_session.as_ref(), |this, session| {
- 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)
- .icon_size(IconSize::Small)
- .on_click({
- let workspace = self.workspace.clone();
- let weak_panel = cx.weak_entity();
- 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.update(cx, |this, cx| {
- let workspace = cx.weak_entity();
- this.toggle_modal(window, cx, |window, cx| {
- NewSessionModal::new(
- past_debug_definition,
- weak_panel,
- workspace,
- None,
- window,
- cx,
- )
- });
- });
- }
+ h_flex()
+ .when_some(active_session.as_ref(), |this, session| {
+ let context_menu =
+ self.sessions_drop_down_menu(session, window, cx);
+ this.child(context_menu).gap_2().child(Divider::vertical())
})
- .tooltip({
- let focus_handle = focus_handle.clone();
- move |window, cx| {
- Tooltip::for_action_in(
- "New Debug Session",
- &CreateDebuggingSession,
- &focus_handle,
- window,
- cx,
- )
- }
- }),
+ .when(!is_side, |this| this.child(new_session_button())),
),
),
)
@@ -967,20 +1007,45 @@ impl Panel for DebugPanel {
"DebugPanel"
}
- fn position(&self, _window: &Window, _cx: &App) -> DockPosition {
- DockPosition::Bottom
+ fn position(&self, _window: &Window, cx: &App) -> DockPosition {
+ match DebuggerSettings::get_global(cx).dock {
+ DebugPanelDockPosition::Left => DockPosition::Left,
+ DebugPanelDockPosition::Bottom => DockPosition::Bottom,
+ DebugPanelDockPosition::Right => DockPosition::Right,
+ }
}
- fn position_is_valid(&self, position: DockPosition) -> bool {
- position == DockPosition::Bottom
+ fn position_is_valid(&self, _: DockPosition) -> bool {
+ true
}
fn set_position(
&mut self,
- _position: DockPosition,
- _window: &mut Window,
- _cx: &mut Context<Self>,
+ position: DockPosition,
+ window: &mut Window,
+ cx: &mut Context<Self>,
) {
+ if position.axis() != self.position(window, cx).axis() {
+ self.sessions.iter().for_each(|session_item| {
+ session_item.update(cx, |item, cx| {
+ item.running_state()
+ .update(cx, |state, _| state.invert_axies())
+ })
+ });
+ }
+
+ settings::update_settings_file::<DebuggerSettings>(
+ self.fs.clone(),
+ cx,
+ move |settings, _| {
+ let dock = match position {
+ DockPosition::Left => DebugPanelDockPosition::Left,
+ DockPosition::Bottom => DebugPanelDockPosition::Bottom,
+ DockPosition::Right => DebugPanelDockPosition::Right,
+ };
+ settings.dock = dock;
+ },
+ );
}
fn size(&self, _window: &Window, _: &App) -> Pixels {
@@ -69,19 +69,22 @@ impl From<DebuggerPaneItem> for SharedString {
}
#[derive(Debug, Serialize, Deserialize)]
-pub(crate) struct SerializedAxis(pub Axis);
+pub(crate) struct SerializedLayout {
+ pub(crate) panes: SerializedPaneLayout,
+ pub(crate) dock_axis: Axis,
+}
-#[derive(Debug, Serialize, Deserialize)]
+#[derive(Debug, Serialize, Deserialize, Clone)]
pub(crate) enum SerializedPaneLayout {
Pane(SerializedPane),
Group {
- axis: SerializedAxis,
+ axis: Axis,
flexes: Option<Vec<f32>>,
children: Vec<SerializedPaneLayout>,
},
}
-#[derive(Debug, Serialize, Deserialize)]
+#[derive(Debug, Serialize, Deserialize, Clone)]
pub(crate) struct SerializedPane {
pub children: Vec<DebuggerPaneItem>,
pub active_item: Option<DebuggerPaneItem>,
@@ -91,7 +94,7 @@ const DEBUGGER_PANEL_PREFIX: &str = "debugger_panel_";
pub(crate) async fn serialize_pane_layout(
adapter_name: DebugAdapterName,
- pane_group: SerializedPaneLayout,
+ pane_group: SerializedLayout,
) -> anyhow::Result<()> {
if let Ok(serialized_pane_group) = serde_json::to_string(&pane_group) {
KEY_VALUE_STORE
@@ -107,10 +110,18 @@ pub(crate) async fn serialize_pane_layout(
}
}
-pub(crate) fn build_serialized_pane_layout(
+pub(crate) fn build_serialized_layout(
pane_group: &Member,
- cx: &mut App,
-) -> SerializedPaneLayout {
+ dock_axis: Axis,
+ cx: &App,
+) -> SerializedLayout {
+ SerializedLayout {
+ dock_axis,
+ panes: build_serialized_pane_layout(pane_group, cx),
+ }
+}
+
+pub(crate) fn build_serialized_pane_layout(pane_group: &Member, cx: &App) -> SerializedPaneLayout {
match pane_group {
Member::Axis(PaneAxis {
axis,
@@ -118,7 +129,7 @@ pub(crate) fn build_serialized_pane_layout(
flexes,
bounding_boxes: _,
}) => SerializedPaneLayout::Group {
- axis: SerializedAxis(*axis),
+ axis: *axis,
children: members
.iter()
.map(|member| build_serialized_pane_layout(member, cx))
@@ -129,7 +140,7 @@ pub(crate) fn build_serialized_pane_layout(
}
}
-fn serialize_pane(pane: &Entity<Pane>, cx: &mut App) -> SerializedPane {
+fn serialize_pane(pane: &Entity<Pane>, cx: &App) -> SerializedPane {
let pane = pane.read(cx);
let children = pane
.items()
@@ -150,20 +161,21 @@ fn serialize_pane(pane: &Entity<Pane>, cx: &mut App) -> SerializedPane {
}
}
-pub(crate) async fn get_serialized_pane_layout(
+pub(crate) async fn get_serialized_layout(
adapter_name: impl AsRef<str>,
-) -> Option<SerializedPaneLayout> {
+) -> Option<SerializedLayout> {
let key = format!("{DEBUGGER_PANEL_PREFIX}-{}", adapter_name.as_ref());
KEY_VALUE_STORE
.read_kvp(&key)
.log_err()
.flatten()
- .and_then(|value| serde_json::from_str::<SerializedPaneLayout>(&value).ok())
+ .and_then(|value| serde_json::from_str::<SerializedLayout>(&value).ok())
}
pub(crate) fn deserialize_pane_layout(
serialized: SerializedPaneLayout,
+ should_invert: bool,
workspace: &WeakEntity<Workspace>,
project: &Entity<Project>,
stack_frame_list: &Entity<StackFrameList>,
@@ -187,6 +199,7 @@ pub(crate) fn deserialize_pane_layout(
for child in children {
if let Some(new_member) = deserialize_pane_layout(
child,
+ should_invert,
workspace,
project,
stack_frame_list,
@@ -213,7 +226,7 @@ pub(crate) fn deserialize_pane_layout(
}
Some(Member::Axis(PaneAxis::load(
- axis.0,
+ if should_invert { axis.invert() } else { axis },
members,
flexes.clone(),
)))
@@ -307,3 +320,28 @@ pub(crate) fn deserialize_pane_layout(
}
}
}
+
+#[cfg(test)]
+impl SerializedPaneLayout {
+ pub(crate) fn in_order(&self) -> Vec<SerializedPaneLayout> {
+ let mut panes = vec![];
+
+ Self::inner_in_order(&self, &mut panes);
+ panes
+ }
+
+ fn inner_in_order(&self, panes: &mut Vec<SerializedPaneLayout>) {
+ match self {
+ SerializedPaneLayout::Pane(_) => panes.push((*self).clone()),
+ SerializedPaneLayout::Group {
+ axis: _,
+ flexes: _,
+ children,
+ } => {
+ for child in children {
+ child.inner_in_order(panes);
+ }
+ }
+ }
+ }
+}
@@ -7,7 +7,7 @@ pub mod variable_list;
use std::{any::Any, ops::ControlFlow, path::PathBuf, sync::Arc, time::Duration};
-use crate::persistence::{self, DebuggerPaneItem, SerializedPaneLayout};
+use crate::persistence::{self, DebuggerPaneItem, SerializedLayout};
use super::DebugPanelItemEvent;
use anyhow::{Result, anyhow};
@@ -22,7 +22,7 @@ use dap::{
};
use futures::{SinkExt, channel::mpsc};
use gpui::{
- Action as _, AnyView, AppContext, Entity, EntityId, EventEmitter, FocusHandle, Focusable,
+ Action as _, AnyView, AppContext, Axis, Entity, EntityId, EventEmitter, FocusHandle, Focusable,
NoAction, Pixels, Point, Subscription, Task, WeakEntity,
};
use language::Buffer;
@@ -73,6 +73,7 @@ pub struct RunningState {
panes: PaneGroup,
active_pane: Option<Entity<Pane>>,
pane_close_subscriptions: HashMap<EntityId, Subscription>,
+ dock_axis: Axis,
_schedule_serialize: Option<Task<()>>,
}
@@ -510,7 +511,8 @@ impl RunningState {
session: Entity<Session>,
project: Entity<Project>,
workspace: WeakEntity<Workspace>,
- serialized_pane_layout: Option<SerializedPaneLayout>,
+ serialized_pane_layout: Option<SerializedLayout>,
+ dock_axis: Axis,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
@@ -589,7 +591,8 @@ impl RunningState {
let mut pane_close_subscriptions = HashMap::default();
let panes = if let Some(root) = serialized_pane_layout.and_then(|serialized_layout| {
persistence::deserialize_pane_layout(
- serialized_layout,
+ serialized_layout.panes,
+ dock_axis != serialized_layout.dock_axis,
&workspace,
&project,
&stack_frame_list,
@@ -617,6 +620,7 @@ impl RunningState {
&loaded_source_list,
&console,
&breakpoint_list,
+ dock_axis,
&mut pane_close_subscriptions,
window,
cx,
@@ -643,6 +647,7 @@ impl RunningState {
loaded_sources_list: loaded_source_list,
pane_close_subscriptions,
debug_terminal,
+ dock_axis,
_schedule_serialize: None,
}
}
@@ -1056,12 +1061,16 @@ impl RunningState {
.timer(Duration::from_millis(100))
.await;
- let Some((adapter_name, pane_group)) = this
- .update(cx, |this, cx| {
+ let Some((adapter_name, pane_layout)) = this
+ .read_with(cx, |this, cx| {
let adapter_name = this.session.read(cx).adapter();
(
adapter_name,
- persistence::build_serialized_pane_layout(&this.panes.root, cx),
+ persistence::build_serialized_layout(
+ &this.panes.root,
+ this.dock_axis,
+ cx,
+ ),
)
})
.ok()
@@ -1069,7 +1078,7 @@ impl RunningState {
return;
};
- persistence::serialize_pane_layout(adapter_name, pane_group)
+ persistence::serialize_pane_layout(adapter_name, pane_layout)
.await
.log_err();
@@ -1195,6 +1204,11 @@ impl RunningState {
&self.variable_list
}
+ #[cfg(test)]
+ pub(crate) fn serialized_layout(&self, cx: &App) -> SerializedLayout {
+ persistence::build_serialized_layout(&self.panes.root, self.dock_axis, cx)
+ }
+
pub fn capabilities(&self, cx: &App) -> Capabilities {
self.session().read(cx).capabilities().clone()
}
@@ -1408,6 +1422,7 @@ impl RunningState {
loaded_source_list: &Entity<LoadedSourceList>,
console: &Entity<Console>,
breakpoints: &Entity<BreakpointList>,
+ dock_axis: Axis,
subscriptions: &mut HashMap<EntityId, Subscription>,
window: &mut Window,
cx: &mut Context<'_, RunningState>,
@@ -1528,7 +1543,7 @@ impl RunningState {
);
let group_root = workspace::PaneAxis::new(
- gpui::Axis::Horizontal,
+ dock_axis.invert(),
[leftmost_pane, center_pane, rightmost_pane]
.into_iter()
.map(workspace::Member::Pane)
@@ -1537,6 +1552,11 @@ impl RunningState {
Member::Axis(group_root)
}
+
+ pub(crate) fn invert_axies(&mut self) {
+ self.dock_axis = self.dock_axis.invert();
+ self.panes.invert_axies();
+ }
}
impl EventEmitter<DebugPanelItemEvent> for RunningState {}