@@ -68,7 +68,7 @@ pub(crate) struct DispatchNodeId(usize);
pub(crate) struct DispatchTree {
node_stack: Vec<DispatchNodeId>,
- pub(crate) context_stack: Vec<KeyContext>,
+ context_stack: Vec<KeyContext>,
view_stack: Vec<EntityId>,
nodes: Vec<DispatchNode>,
focusable_node_ids: FxHashMap<FocusId, DispatchNodeId>,
@@ -396,13 +396,13 @@ impl DispatchTree {
pub fn bindings_for_action(
&self,
action: &dyn Action,
- context_stack: &[KeyContext],
+ context_path: &[KeyContext],
) -> Vec<KeyBinding> {
let keymap = self.keymap.borrow();
keymap
.bindings_for_action(action)
.filter(|binding| {
- let (bindings, _) = keymap.bindings_for_input(&binding.keystrokes, context_stack);
+ let (bindings, _) = keymap.bindings_for_input(&binding.keystrokes, context_path);
bindings
.iter()
.next()
@@ -519,6 +519,13 @@ impl DispatchTree {
dispatch_path
}
+ pub fn context_path(&self, node_id: DispatchNodeId) -> SmallVec<[KeyContext; 32]> {
+ self.dispatch_path(node_id)
+ .into_iter()
+ .filter_map(|node_id| self.node(node_id).context.clone())
+ .collect()
+ }
+
pub fn focus_path(&self, focus_id: FocusId) -> SmallVec<[FocusId; 8]> {
let mut focus_path: SmallVec<[FocusId; 8]> = SmallVec::new();
let mut current_node_id = self.focusable_node_ids.get(&focus_id).copied();
@@ -106,7 +106,7 @@ impl Keymap {
pub fn bindings_for_input(
&self,
input: &[Keystroke],
- context_stack: &[KeyContext],
+ context_path: &[KeyContext],
) -> (SmallVec<[KeyBinding; 1]>, bool) {
let possibilities = self.bindings().rev().filter_map(|binding| {
binding
@@ -118,8 +118,8 @@ impl Keymap {
let mut is_pending = None;
'outer: for (binding, pending) in possibilities {
- for depth in (0..=context_stack.len()).rev() {
- if self.binding_enabled(binding, &context_stack[0..depth]) {
+ for depth in (0..=context_path.len()).rev() {
+ if self.binding_enabled(binding, &context_path[0..depth]) {
if is_pending.is_none() {
is_pending = Some(pending);
}
@@ -3683,22 +3683,11 @@ impl<'a> WindowContext<'a> {
/// Returns all available actions for the focused element.
pub fn available_actions(&self) -> Vec<Box<dyn Action>> {
- let node_id = self
- .window
- .focus
- .and_then(|focus_id| {
- self.window
- .rendered_frame
- .dispatch_tree
- .focusable_node_id(focus_id)
- })
- .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
-
let mut actions = self
.window
.rendered_frame
.dispatch_tree
- .available_actions(node_id);
+ .available_actions(self.focused_node_id());
for action_type in self.global_action_listeners.keys() {
if let Err(ix) = actions.binary_search_by_key(action_type, |a| a.as_any().type_id()) {
let action = self.actions.build_action_type(action_type).ok();
@@ -3712,13 +3701,9 @@ impl<'a> WindowContext<'a> {
/// Returns key bindings that invoke the given action on the currently focused element.
pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
- self.window
- .rendered_frame
- .dispatch_tree
- .bindings_for_action(
- action,
- &self.window.rendered_frame.dispatch_tree.context_stack,
- )
+ let dispatch_tree = &self.window.rendered_frame.dispatch_tree;
+ dispatch_tree
+ .bindings_for_action(action, &dispatch_tree.context_path(self.focused_node_id()))
}
/// Returns key bindings that invoke the given action on the currently focused element.
@@ -3734,15 +3719,23 @@ impl<'a> WindowContext<'a> {
) -> Vec<KeyBinding> {
let dispatch_tree = &self.window.rendered_frame.dispatch_tree;
- let Some(node_id) = dispatch_tree.focusable_node_id(focus_handle.id) else {
- return vec![];
- };
- let context_stack: Vec<_> = dispatch_tree
- .dispatch_path(node_id)
- .into_iter()
- .filter_map(|node_id| dispatch_tree.node(node_id).context.clone())
- .collect();
- dispatch_tree.bindings_for_action(action, &context_stack)
+ if let Some(node_id) = dispatch_tree.focusable_node_id(focus_handle.id) {
+ dispatch_tree.bindings_for_action(action, &dispatch_tree.context_path(node_id))
+ } else {
+ vec![]
+ }
+ }
+
+ fn focused_node_id(&self) -> DispatchNodeId {
+ self.window
+ .focus
+ .and_then(|focus_id| {
+ self.window
+ .rendered_frame
+ .dispatch_tree
+ .focusable_node_id(focus_id)
+ })
+ .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id())
}
/// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.