Fix double read panic in nav history (#22754)
This one seems to be triggered when the assistant's `View<ContextEditor>` is leased during the call into `NavHistory::for_each_entry`, which then tries to read it again through the `ItemHandle` interface. Fix it by skipping entries that can't be read in the history iteration. Release Notes: - N/A
This commit is contained in:
parent
ef583e6b5a
commit
1d8bd151b7
4 changed files with 25 additions and 4 deletions
|
@ -4272,6 +4272,10 @@ impl Item for ContextEditor {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn include_in_nav_history() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl SearchableItem for ContextEditor {
|
||||
|
|
|
@ -320,6 +320,10 @@ pub trait Item: FocusableView + EventEmitter<Self::Event> {
|
|||
fn preserve_preview(&self, _cx: &AppContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn include_in_nav_history() -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SerializableItem: Item {
|
||||
|
@ -464,6 +468,7 @@ pub trait ItemHandle: 'static + Send {
|
|||
fn downgrade_item(&self) -> Box<dyn WeakItemHandle>;
|
||||
fn workspace_settings<'a>(&self, cx: &'a AppContext) -> &'a WorkspaceSettings;
|
||||
fn preserve_preview(&self, cx: &AppContext) -> bool;
|
||||
fn include_in_nav_history(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait WeakItemHandle: Send + Sync {
|
||||
|
@ -877,6 +882,10 @@ impl<T: Item> ItemHandle for View<T> {
|
|||
fn preserve_preview(&self, cx: &AppContext) -> bool {
|
||||
self.read(cx).preserve_preview(cx)
|
||||
}
|
||||
|
||||
fn include_in_nav_history(&self) -> bool {
|
||||
T::include_in_nav_history()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<dyn ItemHandle>> for AnyView {
|
||||
|
|
|
@ -3095,8 +3095,14 @@ impl Render for Pane {
|
|||
|
||||
impl ItemNavHistory {
|
||||
pub fn push<D: 'static + Send + Any>(&mut self, data: Option<D>, cx: &mut WindowContext) {
|
||||
self.history
|
||||
.push(data, self.item.clone(), self.is_preview, cx);
|
||||
if self
|
||||
.item
|
||||
.upgrade()
|
||||
.is_some_and(|item| item.include_in_nav_history())
|
||||
{
|
||||
self.history
|
||||
.push(data, self.item.clone(), self.is_preview, cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pop_backward(&mut self, cx: &mut WindowContext) -> Option<NavigationEntry> {
|
||||
|
|
|
@ -2975,13 +2975,15 @@ impl Workspace {
|
|||
match target {
|
||||
Some(ActivateInDirectionTarget::Pane(pane)) => cx.focus_view(&pane),
|
||||
Some(ActivateInDirectionTarget::Dock(dock)) => {
|
||||
dock.update(cx, |dock, cx| {
|
||||
// Defer this to avoid a panic when the dock's active panel is already on the stack.
|
||||
cx.defer(move |cx| {
|
||||
let dock = dock.read(cx);
|
||||
if let Some(panel) = dock.active_panel() {
|
||||
panel.focus_handle(cx).focus(cx);
|
||||
} else {
|
||||
log::error!("Could not find a focus target when in switching focus in {direction} direction for a {:?} dock", dock.position());
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue