Let WindowContext::dispatch_action handle global actions

Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
Piotr Osiewicz 2023-12-06 16:52:52 +01:00
parent e9002ab10a
commit 6549a9a091
3 changed files with 60 additions and 58 deletions

View file

@ -1040,20 +1040,10 @@ impl AppContext {
pub fn is_action_available(&mut self, action: &dyn Action) -> bool {
if let Some(window) = self.active_window() {
let window_action_available = window
.update(self, |_, cx| {
if let Some(focus_id) = cx.window.focus {
cx.window
.current_frame
.dispatch_tree
.is_action_available(action, focus_id)
} else {
false
}
})
.unwrap_or(false);
if window_action_available {
return true;
if let Ok(window_action_available) =
window.update(self, |_, cx| cx.is_action_available(action))
{
return window_action_available;
}
}
@ -1075,6 +1065,11 @@ impl AppContext {
}
pub fn dispatch_action(&mut self, action: &dyn Action) {
if let Some(active_window) = self.active_window() {
active_window
.update(self, |_, cx| cx.dispatch_action(action.boxed_clone()))
.log_err();
} else {
self.propagate_event = true;
if let Some(mut global_listeners) = self
@ -1082,7 +1077,7 @@ impl AppContext {
.remove(&action.as_any().type_id())
{
for listener in &global_listeners {
listener(action, DispatchPhase::Capture, self);
listener(action.as_any(), DispatchPhase::Capture, self);
if !self.propagate_event {
break;
}
@ -1098,21 +1093,13 @@ impl AppContext {
.insert(action.as_any().type_id(), global_listeners);
}
if self.propagate_event {
if let Some(active_window) = self.active_window() {
active_window
.update(self, |_, cx| cx.dispatch_action(action.boxed_clone()))
.log_err();
}
}
if self.propagate_event {
if let Some(mut global_listeners) = self
.global_action_listeners
.remove(&action.as_any().type_id())
{
for listener in global_listeners.iter().rev() {
listener(action, DispatchPhase::Bubble, self);
listener(action.as_any(), DispatchPhase::Bubble, self);
if !self.propagate_event {
break;
}
@ -1129,6 +1116,7 @@ impl AppContext {
}
}
}
}
}
impl Context for AppContext {

View file

@ -161,9 +161,8 @@ impl DispatchTree {
actions
}
pub fn is_action_available(&self, action: &dyn Action, target: FocusId) -> bool {
if let Some(node) = self.focusable_node_ids.get(&target) {
for node_id in self.dispatch_path(*node) {
pub fn is_action_available(&self, action: &dyn Action, target: DispatchNodeId) -> bool {
for node_id in self.dispatch_path(target) {
let node = &self.nodes[node_id.0];
if node
.action_listeners
@ -173,7 +172,6 @@ impl DispatchTree {
return true;
}
}
}
false
}

View file

@ -804,6 +804,22 @@ impl<'a> WindowContext<'a> {
);
}
pub fn is_action_available(&self, action: &dyn Action) -> bool {
let target = self
.focused()
.and_then(|focused_handle| {
self.window
.current_frame
.dispatch_tree
.focusable_node_id(focused_handle.id)
})
.unwrap_or_else(|| self.window.current_frame.dispatch_tree.root_node_id());
self.window
.current_frame
.dispatch_tree
.is_action_available(action, target)
}
/// The position of the mouse relative to the window.
pub fn mouse_position(&self) -> Point<Pixels> {
self.window.mouse_position