@@ -1774,11 +1774,13 @@ impl MutableAppContext {
presenter.borrow().dispatch_path(cx.as_ref()),
keystroke,
) {
- return;
+ return true;
}
}
- presenter.borrow_mut().dispatch_event(event, cx);
+ presenter.borrow_mut().dispatch_event(event, cx)
+ } else {
+ false
}
})
}));
@@ -90,7 +90,7 @@ pub trait Dispatcher: Send + Sync {
pub trait Window: WindowContext {
fn as_any_mut(&mut self) -> &mut dyn Any;
- fn on_event(&mut self, callback: Box<dyn FnMut(Event)>);
+ fn on_event(&mut self, callback: Box<dyn FnMut(Event) -> bool>);
fn on_active_status_change(&mut self, callback: Box<dyn FnMut(bool)>);
fn on_resize(&mut self, callback: Box<dyn FnMut()>);
fn on_close(&mut self, callback: Box<dyn FnOnce()>);
@@ -92,8 +92,8 @@ unsafe fn build_classes() {
decl.add_method(sel!(dealloc), dealloc_view as extern "C" fn(&Object, Sel));
decl.add_method(
- sel!(keyDown:),
- handle_view_event as extern "C" fn(&Object, Sel, id),
+ sel!(performKeyEquivalent:),
+ handle_key_equivalent as extern "C" fn(&Object, Sel, id) -> BOOL,
);
decl.add_method(
sel!(mouseDown:),
@@ -164,7 +164,7 @@ pub struct Window(Rc<RefCell<WindowState>>);
struct WindowState {
id: usize,
native_window: id,
- event_callback: Option<Box<dyn FnMut(Event)>>,
+ event_callback: Option<Box<dyn FnMut(Event) -> bool>>,
activate_callback: Option<Box<dyn FnMut(bool)>>,
resize_callback: Option<Box<dyn FnMut()>>,
close_callback: Option<Box<dyn FnOnce()>>,
@@ -331,7 +331,7 @@ impl platform::Window for Window {
self
}
- fn on_event(&mut self, callback: Box<dyn FnMut(Event)>) {
+ fn on_event(&mut self, callback: Box<dyn FnMut(Event) -> bool>) {
self.0.as_ref().borrow_mut().event_callback = Some(callback);
}
@@ -528,6 +528,45 @@ extern "C" fn dealloc_view(this: &Object, _: Sel) {
}
}
+extern "C" fn handle_key_equivalent(this: &Object, _: Sel, native_event: id) -> BOOL {
+ let window_state = unsafe { get_window_state(this) };
+ let mut window_state_borrow = window_state.as_ref().borrow_mut();
+
+ let event = unsafe { Event::from_native(native_event, Some(window_state_borrow.size().y())) };
+ if let Some(event) = event {
+ match &event {
+ Event::KeyDown {
+ keystroke,
+ input,
+ is_held,
+ } => {
+ let keydown = (keystroke.clone(), input.clone());
+ // Ignore events from held-down keys after some of the initially-pressed keys
+ // were released.
+ if *is_held {
+ if window_state_borrow.last_fresh_keydown.as_ref() != Some(&keydown) {
+ return YES;
+ }
+ } else {
+ window_state_borrow.last_fresh_keydown = Some(keydown);
+ }
+ }
+ _ => return NO,
+ }
+
+ if let Some(mut callback) = window_state_borrow.event_callback.take() {
+ drop(window_state_borrow);
+ let handled = callback(event);
+ window_state.borrow_mut().event_callback = Some(callback);
+ handled as BOOL
+ } else {
+ NO
+ }
+ } else {
+ NO
+ }
+}
+
extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
let window_state = unsafe { get_window_state(this) };
let weak_window_state = Rc::downgrade(&window_state);
@@ -551,24 +590,6 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
Event::LeftMouseUp { .. } => {
window_state_borrow.synthetic_drag_counter += 1;
}
-
- // Ignore events from held-down keys after some of the initially-pressed keys
- // were released.
- Event::KeyDown {
- input,
- keystroke,
- is_held,
- } => {
- let keydown = (keystroke.clone(), input.clone());
- if *is_held {
- if window_state_borrow.last_fresh_keydown.as_ref() != Some(&keydown) {
- return;
- }
- } else {
- window_state_borrow.last_fresh_keydown = Some(keydown);
- }
- }
-
_ => {}
}
@@ -34,7 +34,7 @@ pub struct Window {
size: Vector2F,
scale_factor: f32,
current_scene: Option<crate::Scene>,
- event_handlers: Vec<Box<dyn FnMut(super::Event)>>,
+ event_handlers: Vec<Box<dyn FnMut(super::Event) -> bool>>,
resize_handlers: Vec<Box<dyn FnMut()>>,
close_handlers: Vec<Box<dyn FnOnce()>>,
pub(crate) title: Option<String>,
@@ -233,7 +233,7 @@ impl super::Window for Window {
self
}
- fn on_event(&mut self, callback: Box<dyn FnMut(crate::Event)>) {
+ fn on_event(&mut self, callback: Box<dyn FnMut(crate::Event) -> bool>) {
self.event_handlers.push(callback);
}
@@ -224,7 +224,7 @@ impl Presenter {
}
}
- pub fn dispatch_event(&mut self, event: Event, cx: &mut MutableAppContext) {
+ pub fn dispatch_event(&mut self, event: Event, cx: &mut MutableAppContext) -> bool {
if let Some(root_view_id) = cx.root_view_id(self.window_id) {
let mut invalidated_views = Vec::new();
let mut mouse_down_out_handlers = Vec::new();
@@ -366,7 +366,7 @@ impl Presenter {
}
if !handled {
- event_cx.dispatch_event(root_view_id, &event);
+ handled = event_cx.dispatch_event(root_view_id, &event);
}
invalidated_views.extend(event_cx.invalidated_views);
@@ -384,6 +384,10 @@ impl Presenter {
}
cx.dispatch_action_any(self.window_id, &dispatch_path, directive.action.as_ref());
}
+
+ handled
+ } else {
+ false
}
}