diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 8d4dc371e6..74712feb28 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -39,7 +39,10 @@ use std::{ sync::{atomic::Ordering::SeqCst, Arc}, time::Duration, }; -use util::http::{self, HttpClient}; +use util::{ + http::{self, HttpClient}, + ResultExt, +}; /// Temporary(?) wrapper around RefCell to help us debug any double borrows. /// Strongly consider removing after stabilization. @@ -1055,6 +1058,62 @@ impl AppContext { self.global_action_listeners .contains_key(&action.as_any().type_id()) } + + pub fn dispatch_action(&mut self, action: &dyn Action) { + 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 + .global_action_listeners + .remove(&action.as_any().type_id()) + { + for listener in global_listeners.iter().rev() { + listener(action, 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); + } + } + } } impl Context for AppContext { diff --git a/crates/gpui2/src/platform.rs b/crates/gpui2/src/platform.rs index 5d3a92f052..96be670af7 100644 --- a/crates/gpui2/src/platform.rs +++ b/crates/gpui2/src/platform.rs @@ -92,9 +92,9 @@ pub trait Platform: 'static { fn on_reopen(&self, callback: Box); fn on_event(&self, callback: Box bool>); - fn on_menu_command(&self, callback: Box); - fn on_will_open_menu(&self, callback: Box); - fn on_validate_menu_command(&self, callback: Box bool>); + fn on_app_menu_action(&self, callback: Box); + fn on_will_open_app_menu(&self, callback: Box); + fn on_validate_app_menu_command(&self, callback: Box bool>); fn os_name(&self) -> &'static str; fn os_version(&self) -> Result; diff --git a/crates/gpui2/src/platform/app_menu.rs b/crates/gpui2/src/platform/app_menu.rs index 0f784f6585..bfac1366b2 100644 --- a/crates/gpui2/src/platform/app_menu.rs +++ b/crates/gpui2/src/platform/app_menu.rs @@ -53,14 +53,14 @@ pub enum OsAction { } pub(crate) fn init(platform: &dyn Platform, cx: &mut AppContext) { - platform.on_will_open_menu(Box::new({ + platform.on_will_open_app_menu(Box::new({ let cx = cx.to_async(); move || { cx.update(|cx| cx.clear_pending_keystrokes()).ok(); } })); - platform.on_validate_menu_command(Box::new({ + platform.on_validate_app_menu_command(Box::new({ let cx = cx.to_async(); move |action| { cx.update(|cx| cx.is_action_available(action)) @@ -68,29 +68,10 @@ pub(crate) fn init(platform: &dyn Platform, cx: &mut AppContext) { } })); - platform.on_menu_command(Box::new({ + platform.on_app_menu_action(Box::new({ let cx = cx.to_async(); move |action| { - cx.update(|cx| { - // if let Some(main_window) = cx.active_window() { - // let dispatched = main_window - // .update(&mut *cx, |cx| { - // if let Some(view_id) = cx.focused_view_id() { - // cx.dispatch_action(Some(view_id), action); - // true - // } else { - // false - // } - // }) - // .unwrap_or(false); - - // if dispatched { - // return; - // } - // } - // cx.dispatch_global_action_any(action); - }) - .log_err(); + cx.update(|cx| cx.dispatch_action(action)).log_err(); } })); } diff --git a/crates/gpui2/src/platform/mac/platform.rs b/crates/gpui2/src/platform/mac/platform.rs index 6dae0afc0e..d7fc37f0de 100644 --- a/crates/gpui2/src/platform/mac/platform.rs +++ b/crates/gpui2/src/platform/mac/platform.rs @@ -683,15 +683,15 @@ impl Platform for MacPlatform { } } - fn on_menu_command(&self, callback: Box) { + fn on_app_menu_action(&self, callback: Box) { self.0.lock().menu_command = Some(callback); } - fn on_will_open_menu(&self, callback: Box) { + fn on_will_open_app_menu(&self, callback: Box) { self.0.lock().will_open_menu = Some(callback); } - fn on_validate_menu_command(&self, callback: Box bool>) { + fn on_validate_app_menu_command(&self, callback: Box bool>) { self.0.lock().validate_menu_command = Some(callback); } diff --git a/crates/gpui2/src/platform/test/platform.rs b/crates/gpui2/src/platform/test/platform.rs index 2642737305..952a9a96ca 100644 --- a/crates/gpui2/src/platform/test/platform.rs +++ b/crates/gpui2/src/platform/test/platform.rs @@ -205,15 +205,15 @@ impl Platform for TestPlatform { unimplemented!() } - fn on_menu_command(&self, _callback: Box) { + fn on_app_menu_action(&self, _callback: Box) { unimplemented!() } - fn on_will_open_menu(&self, _callback: Box) { + fn on_will_open_app_menu(&self, _callback: Box) { unimplemented!() } - fn on_validate_menu_command(&self, _callback: Box bool>) { + fn on_validate_app_menu_command(&self, _callback: Box bool>) { unimplemented!() }