Halt keystroke dispatch immediately when we call a global action handler

Someday, we may want to define a global action context that allows us to propagate the action, but this isn't currently supported. Previous to this commit, we were invoking the same global action handler multiple times, once for each view in the responder chain.
This commit is contained in:
Nathan Sobo 2021-12-18 08:12:08 -07:00
parent bd6e972d0f
commit cd65031cda

View file

@ -667,7 +667,7 @@ pub struct MutableAppContext {
assets: Arc<AssetCache>, assets: Arc<AssetCache>,
cx: AppContext, cx: AppContext,
actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>, actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
global_actions: HashMap<TypeId, Vec<Box<GlobalActionCallback>>>, global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
keystroke_matcher: keymap::Matcher, keystroke_matcher: keymap::Matcher,
next_entity_id: usize, next_entity_id: usize,
next_window_id: usize, next_window_id: usize,
@ -838,10 +838,13 @@ impl MutableAppContext {
handler(action, cx); handler(action, cx);
}); });
self.global_actions if self
.entry(TypeId::of::<A>()) .global_actions
.or_default() .insert(TypeId::of::<A>(), handler)
.push(handler); .is_some()
{
panic!("registered multiple global handlers for the same action type");
}
} }
pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ { pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
@ -1125,7 +1128,7 @@ impl MutableAppContext {
} }
if !halted_dispatch { if !halted_dispatch {
this.dispatch_global_action_any(action); halted_dispatch = this.dispatch_global_action_any(action);
} }
halted_dispatch halted_dispatch
}) })
@ -1135,13 +1138,14 @@ impl MutableAppContext {
self.dispatch_global_action_any(&action); self.dispatch_global_action_any(&action);
} }
fn dispatch_global_action_any(&mut self, action: &dyn AnyAction) { fn dispatch_global_action_any(&mut self, action: &dyn AnyAction) -> bool {
self.update(|this| { self.update(|this| {
if let Some((name, mut handlers)) = this.global_actions.remove_entry(&action.id()) { if let Some((name, mut handler)) = this.global_actions.remove_entry(&action.id()) {
for handler in handlers.iter_mut().rev() {
handler(action, this); handler(action, this);
} this.global_actions.insert(name, handler);
this.global_actions.insert(name, handlers); true
} else {
false
} }
}) })
} }