diff --git a/crates/gpui/src/key_dispatch.rs b/crates/gpui/src/key_dispatch.rs index eb6eceeac0..8e2af9422b 100644 --- a/crates/gpui/src/key_dispatch.rs +++ b/crates/gpui/src/key_dispatch.rs @@ -63,6 +63,8 @@ use std::{ rc::Rc, }; +/// ID of a node within `DispatchTree`. Note that these are **not** stable between frames, and so a +/// `DispatchNodeId` should only be used with the `DispatchTree` that provided it. #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub(crate) struct DispatchNodeId(usize); diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index c87a65573f..f0f4579b29 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -1318,21 +1318,13 @@ impl Window { /// Dispatch the given action on the currently focused element. pub fn dispatch_action(&mut self, action: Box, cx: &mut App) { - let focus_handle = self.focused(cx); + let focus_id = self.focused(cx).map(|handle| handle.id); let window = self.handle; cx.defer(move |cx| { window .update(cx, |_, window, cx| { - let node_id = focus_handle - .and_then(|handle| { - window - .rendered_frame - .dispatch_tree - .focusable_node_id(handle.id) - }) - .unwrap_or_else(|| window.rendered_frame.dispatch_tree.root_node_id()); - + let node_id = window.focus_node_id_in_rendered_frame(focus_id); window.dispatch_action_on_node(node_id, action.as_ref(), cx); }) .log_err(); @@ -1709,17 +1701,11 @@ impl Window { /// Determine whether the given action is available along the dispatch path to the currently focused element. pub fn is_action_available(&self, action: &dyn Action, cx: &mut App) -> bool { - let target = self - .focused(cx) - .and_then(|focused_handle| { - self.rendered_frame - .dispatch_tree - .focusable_node_id(focused_handle.id) - }) - .unwrap_or_else(|| self.rendered_frame.dispatch_tree.root_node_id()); + let node_id = + self.focus_node_id_in_rendered_frame(self.focused(cx).map(|handle| handle.id)); self.rendered_frame .dispatch_tree - .is_action_available(action, target) + .is_action_available(action, node_id) } /// The position of the mouse relative to the window. @@ -3484,15 +3470,7 @@ impl Window { self.draw(cx); } - let node_id = self - .focus - .and_then(|focus_id| { - self.rendered_frame - .dispatch_tree - .focusable_node_id(focus_id) - }) - .unwrap_or_else(|| self.rendered_frame.dispatch_tree.root_node_id()); - + let node_id = self.focus_node_id_in_rendered_frame(self.focus); let dispatch_path = self.rendered_frame.dispatch_tree.dispatch_path(node_id); let mut keystroke: Option = None; @@ -3564,6 +3542,7 @@ impl Window { return; }; + let node_id = window.focus_node_id_in_rendered_frame(window.focus); let dispatch_path = window.rendered_frame.dispatch_tree.dispatch_path(node_id); let to_replay = window @@ -3695,15 +3674,7 @@ impl Window { } fn replay_pending_input(&mut self, replays: SmallVec<[Replay; 1]>, cx: &mut App) { - let node_id = self - .focus - .and_then(|focus_id| { - self.rendered_frame - .dispatch_tree - .focusable_node_id(focus_id) - }) - .unwrap_or_else(|| self.rendered_frame.dispatch_tree.root_node_id()); - + let node_id = self.focus_node_id_in_rendered_frame(self.focus); let dispatch_path = self.rendered_frame.dispatch_tree.dispatch_path(node_id); 'replay: for replay in replays { @@ -3739,6 +3710,16 @@ impl Window { } } + fn focus_node_id_in_rendered_frame(&self, focus_id: Option) -> DispatchNodeId { + focus_id + .and_then(|focus_id| { + self.rendered_frame + .dispatch_tree + .focusable_node_id(focus_id) + }) + .unwrap_or_else(|| self.rendered_frame.dispatch_tree.root_node_id()) + } + fn dispatch_action_on_node( &mut self, node_id: DispatchNodeId, @@ -3946,12 +3927,8 @@ impl Window { /// Returns the current context stack. pub fn context_stack(&self) -> Vec { + let node_id = self.focus_node_id_in_rendered_frame(self.focus); let dispatch_tree = &self.rendered_frame.dispatch_tree; - let node_id = self - .focus - .and_then(|focus_id| dispatch_tree.focusable_node_id(focus_id)) - .unwrap_or_else(|| dispatch_tree.root_node_id()); - dispatch_tree .dispatch_path(node_id) .iter() @@ -3961,15 +3938,7 @@ impl Window { /// Returns all available actions for the focused element. pub fn available_actions(&self, cx: &App) -> Vec> { - let node_id = self - .focus - .and_then(|focus_id| { - self.rendered_frame - .dispatch_tree - .focusable_node_id(focus_id) - }) - .unwrap_or_else(|| self.rendered_frame.dispatch_tree.root_node_id()); - + let node_id = self.focus_node_id_in_rendered_frame(self.focus); let mut actions = self.rendered_frame.dispatch_tree.available_actions(node_id); for action_type in cx.global_action_listeners.keys() { if let Err(ix) = actions.binary_search_by_key(action_type, |a| a.as_any().type_id()) {