debugger: Always focus the active session whenever it is stopped (#31182)
Closes #ISSUE Release Notes: - debugger: Fixed child debug sessions taking precedence over the parents when spawned.
This commit is contained in:
parent
ee4e43f1b6
commit
fa1abd8201
3 changed files with 131 additions and 64 deletions
|
@ -273,7 +273,7 @@ impl DebugPanel {
|
|||
let session = session.clone();
|
||||
async move |this, cx| {
|
||||
let debug_session =
|
||||
Self::register_session(this.clone(), session.clone(), cx).await?;
|
||||
Self::register_session(this.clone(), session.clone(), true, cx).await?;
|
||||
let definition = debug_session
|
||||
.update_in(cx, |debug_session, window, cx| {
|
||||
debug_session.running_state().update(cx, |running, cx| {
|
||||
|
@ -318,69 +318,21 @@ impl DebugPanel {
|
|||
pub(crate) async fn register_session(
|
||||
this: WeakEntity<Self>,
|
||||
session: Entity<Session>,
|
||||
focus: bool,
|
||||
cx: &mut AsyncWindowContext,
|
||||
) -> Result<Entity<DebugSession>> {
|
||||
let adapter_name = session.update(cx, |session, _| session.adapter())?;
|
||||
this.update_in(cx, |_, window, cx| {
|
||||
cx.subscribe_in(
|
||||
&session,
|
||||
window,
|
||||
move |this, session, event: &SessionStateEvent, window, cx| match event {
|
||||
SessionStateEvent::Restart => {
|
||||
this.handle_restart_request(session.clone(), window, cx);
|
||||
}
|
||||
SessionStateEvent::SpawnChildSession { request } => {
|
||||
this.handle_start_debugging_request(request, session.clone(), window, cx);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
})
|
||||
.ok();
|
||||
let debug_session = register_session_inner(&this, session, cx).await?;
|
||||
|
||||
let serialized_layout = persistence::get_serialized_layout(adapter_name).await;
|
||||
let workspace = this.update_in(cx, |this, window, cx| {
|
||||
if focus {
|
||||
this.activate_session(debug_session.clone(), window, cx);
|
||||
}
|
||||
|
||||
let (debug_session, workspace) = this.update_in(cx, |this, window, cx| {
|
||||
this.sessions.retain(|session| {
|
||||
!session
|
||||
.read(cx)
|
||||
.running_state()
|
||||
.read(cx)
|
||||
.session()
|
||||
.read(cx)
|
||||
.is_terminated()
|
||||
});
|
||||
|
||||
let debug_session = DebugSession::running(
|
||||
this.project.clone(),
|
||||
this.workspace.clone(),
|
||||
session,
|
||||
cx.weak_entity(),
|
||||
serialized_layout,
|
||||
this.position(window, cx).axis(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
||||
// We might want to make this an event subscription and only notify when a new thread is selected
|
||||
// This is used to filter the command menu correctly
|
||||
cx.observe(
|
||||
&debug_session.read(cx).running_state().clone(),
|
||||
|_, _, cx| cx.notify(),
|
||||
)
|
||||
.detach();
|
||||
|
||||
this.sessions.push(debug_session.clone());
|
||||
this.activate_session(debug_session.clone(), window, cx);
|
||||
|
||||
(debug_session, this.workspace.clone())
|
||||
this.workspace.clone()
|
||||
})?;
|
||||
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
workspace.focus_panel::<Self>(window, cx);
|
||||
})?;
|
||||
|
||||
Ok(debug_session)
|
||||
}
|
||||
|
||||
|
@ -418,7 +370,7 @@ impl DebugPanel {
|
|||
});
|
||||
(session, task)
|
||||
})?;
|
||||
Self::register_session(this, session, cx).await?;
|
||||
Self::register_session(this.clone(), session, true, cx).await?;
|
||||
task.await
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
|
@ -441,7 +393,6 @@ impl DebugPanel {
|
|||
let adapter = parent_session.read(cx).adapter().clone();
|
||||
let mut binary = parent_session.read(cx).binary().clone();
|
||||
binary.request_args = request.clone();
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let (session, task) = dap_store_handle.update(cx, |dap_store, cx| {
|
||||
let session =
|
||||
|
@ -452,7 +403,7 @@ impl DebugPanel {
|
|||
});
|
||||
(session, task)
|
||||
})?;
|
||||
Self::register_session(this, session, cx).await?;
|
||||
Self::register_session(this, session, false, cx).await?;
|
||||
task.await
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
|
@ -910,6 +861,21 @@ impl DebugPanel {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn activate_session_by_id(
|
||||
&mut self,
|
||||
session_id: SessionId,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some(session) = self
|
||||
.sessions
|
||||
.iter()
|
||||
.find(|session| session.read(cx).session_id(cx) == session_id)
|
||||
{
|
||||
self.activate_session(session.clone(), window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn activate_session(
|
||||
&mut self,
|
||||
session_item: Entity<DebugSession>,
|
||||
|
@ -923,7 +889,7 @@ impl DebugPanel {
|
|||
this.go_to_selected_stack_frame(window, cx);
|
||||
});
|
||||
});
|
||||
self.active_session = Some(session_item.clone());
|
||||
self.active_session = Some(session_item);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
@ -999,6 +965,67 @@ impl DebugPanel {
|
|||
}
|
||||
}
|
||||
|
||||
async fn register_session_inner(
|
||||
this: &WeakEntity<DebugPanel>,
|
||||
session: Entity<Session>,
|
||||
cx: &mut AsyncWindowContext,
|
||||
) -> Result<Entity<DebugSession>> {
|
||||
let adapter_name = session.update(cx, |session, _| session.adapter())?;
|
||||
this.update_in(cx, |_, window, cx| {
|
||||
cx.subscribe_in(
|
||||
&session,
|
||||
window,
|
||||
move |this, session, event: &SessionStateEvent, window, cx| match event {
|
||||
SessionStateEvent::Restart => {
|
||||
this.handle_restart_request(session.clone(), window, cx);
|
||||
}
|
||||
SessionStateEvent::SpawnChildSession { request } => {
|
||||
this.handle_start_debugging_request(request, session.clone(), window, cx);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
})
|
||||
.ok();
|
||||
let serialized_layout = persistence::get_serialized_layout(adapter_name).await;
|
||||
let debug_session = this.update_in(cx, |this, window, cx| {
|
||||
this.sessions.retain(|session| {
|
||||
!session
|
||||
.read(cx)
|
||||
.running_state()
|
||||
.read(cx)
|
||||
.session()
|
||||
.read(cx)
|
||||
.is_terminated()
|
||||
});
|
||||
|
||||
let debug_session = DebugSession::running(
|
||||
this.project.clone(),
|
||||
this.workspace.clone(),
|
||||
session,
|
||||
cx.weak_entity(),
|
||||
serialized_layout,
|
||||
this.position(window, cx).axis(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
||||
// We might want to make this an event subscription and only notify when a new thread is selected
|
||||
// This is used to filter the command menu correctly
|
||||
cx.observe(
|
||||
&debug_session.read(cx).running_state().clone(),
|
||||
|_, _, cx| cx.notify(),
|
||||
)
|
||||
.detach();
|
||||
|
||||
this.sessions.push(debug_session.clone());
|
||||
|
||||
debug_session
|
||||
})?;
|
||||
Ok(debug_session)
|
||||
}
|
||||
|
||||
impl EventEmitter<PanelEvent> for DebugPanel {}
|
||||
impl EventEmitter<DebugPanelEvent> for DebugPanel {}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue