Let WindowContext::dispatch_action handle global actions
Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
parent
e9002ab10a
commit
6549a9a091
3 changed files with 60 additions and 58 deletions
|
@ -1040,20 +1040,10 @@ impl AppContext {
|
||||||
|
|
||||||
pub fn is_action_available(&mut self, action: &dyn Action) -> bool {
|
pub fn is_action_available(&mut self, action: &dyn Action) -> bool {
|
||||||
if let Some(window) = self.active_window() {
|
if let Some(window) = self.active_window() {
|
||||||
let window_action_available = window
|
if let Ok(window_action_available) =
|
||||||
.update(self, |_, cx| {
|
window.update(self, |_, cx| cx.is_action_available(action))
|
||||||
if let Some(focus_id) = cx.window.focus {
|
{
|
||||||
cx.window
|
return window_action_available;
|
||||||
.current_frame
|
|
||||||
.dispatch_tree
|
|
||||||
.is_action_available(action, focus_id)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap_or(false);
|
|
||||||
if window_action_available {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1075,44 +1065,19 @@ impl AppContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch_action(&mut self, action: &dyn Action) {
|
pub fn dispatch_action(&mut self, action: &dyn Action) {
|
||||||
self.propagate_event = true;
|
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
|
|
||||||
.global_action_listeners
|
|
||||||
.remove(&action.as_any().type_id())
|
|
||||||
{
|
|
||||||
for listener in &global_listeners {
|
|
||||||
listener(action, 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 {
|
|
||||||
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
|
if let Some(mut global_listeners) = self
|
||||||
.global_action_listeners
|
.global_action_listeners
|
||||||
.remove(&action.as_any().type_id())
|
.remove(&action.as_any().type_id())
|
||||||
{
|
{
|
||||||
for listener in global_listeners.iter().rev() {
|
for listener in &global_listeners {
|
||||||
listener(action, DispatchPhase::Bubble, self);
|
listener(action.as_any(), DispatchPhase::Capture, self);
|
||||||
if !self.propagate_event {
|
if !self.propagate_event {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1127,6 +1092,29 @@ impl AppContext {
|
||||||
self.global_action_listeners
|
self.global_action_listeners
|
||||||
.insert(action.as_any().type_id(), global_listeners);
|
.insert(action.as_any().type_id(), global_listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,17 +161,15 @@ impl DispatchTree {
|
||||||
actions
|
actions
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_action_available(&self, action: &dyn Action, target: FocusId) -> bool {
|
pub fn is_action_available(&self, action: &dyn Action, target: DispatchNodeId) -> bool {
|
||||||
if let Some(node) = self.focusable_node_ids.get(&target) {
|
for node_id in self.dispatch_path(target) {
|
||||||
for node_id in self.dispatch_path(*node) {
|
let node = &self.nodes[node_id.0];
|
||||||
let node = &self.nodes[node_id.0];
|
if node
|
||||||
if node
|
.action_listeners
|
||||||
.action_listeners
|
.iter()
|
||||||
.iter()
|
.any(|listener| listener.action_type == action.as_any().type_id())
|
||||||
.any(|listener| listener.action_type == action.as_any().type_id())
|
{
|
||||||
{
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
|
|
@ -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.
|
/// The position of the mouse relative to the window.
|
||||||
pub fn mouse_position(&self) -> Point<Pixels> {
|
pub fn mouse_position(&self) -> Point<Pixels> {
|
||||||
self.window.mouse_position
|
self.window.mouse_position
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue