Fix dispatching global actions from a window (#9502)

Fixes https://github.com/zed-industries/zed/issues/9313

Release Notes:

- Fixed a regression that caused global actions to stop working when
invoked from a window (preview-only)
([#9313](https://github.com/zed-industries/zed/issues/9313)).

Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
Antonio Scandurra 2024-03-18 18:31:47 +01:00 committed by GitHub
parent 4e17ce3b37
commit 3d08e20c72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 7 deletions

View File

@ -1155,7 +1155,7 @@ impl AppContext {
}
}
pub(crate) fn dispatch_global_action(&mut self, action: &dyn Action) {
fn dispatch_global_action(&mut self, action: &dyn Action) {
self.propagate_event = true;
if let Some(mut global_listeners) = self

View File

@ -705,7 +705,6 @@ impl<'a> WindowContext<'a> {
let window = self.window.handle;
self.app.defer(move |cx| {
cx.propagate_event = true;
window
.update(cx, |_, cx| {
let node_id = focus_handle
@ -720,9 +719,6 @@ impl<'a> WindowContext<'a> {
cx.dispatch_action_on_node(node_id, action.as_ref());
})
.log_err();
if cx.propagate_event {
cx.dispatch_global_action(action.as_ref());
}
})
}
@ -1467,7 +1463,34 @@ impl<'a> WindowContext<'a> {
.dispatch_tree
.dispatch_path(node_id);
// Capture phase
// Capture phase for global actions.
self.propagate_event = true;
if let Some(mut global_listeners) = self
.global_action_listeners
.remove(&action.as_any().type_id())
{
for listener in &global_listeners {
listener(action.as_any(), DispatchPhase::Capture, self);
if !self.propagate_event {
break;
}
}
global_listeners.extend(
self.global_action_listeners
.remove(&action.as_any().type_id())
.unwrap_or_default(),
);
self.global_action_listeners
.insert(action.as_any().type_id(), global_listeners);
}
if !self.propagate_event {
return;
}
// Capture phase for window actions.
for node_id in &dispatch_path {
let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
for DispatchActionListener {
@ -1487,7 +1510,8 @@ impl<'a> WindowContext<'a> {
}
}
}
// Bubble phase
// Bubble phase for window actions.
for node_id in dispatch_path.iter().rev() {
let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
for DispatchActionListener {
@ -1509,6 +1533,30 @@ impl<'a> WindowContext<'a> {
}
}
}
// Bubble phase for global actions.
if let Some(mut global_listeners) = self
.global_action_listeners
.remove(&action.as_any().type_id())
{
for listener in global_listeners.iter().rev() {
self.propagate_event = false; // Actions stop propagation by default during the bubble phase
listener(action.as_any(), DispatchPhase::Bubble, self);
if !self.propagate_event {
break;
}
}
global_listeners.extend(
self.global_action_listeners
.remove(&action.as_any().type_id())
.unwrap_or_default(),
);
self.global_action_listeners
.insert(action.as_any().type_id(), global_listeners);
}
}
/// Register the given handler to be invoked whenever the global of the given type