Detailed changes
@@ -467,14 +467,14 @@ impl MutableAppContext {
pub fn dispatch_action(
&mut self,
window_id: usize,
- responder_chain: &[usize],
+ path: &[usize],
name: &str,
arg: &dyn Any,
) -> bool {
self.pending_flushes += 1;
let mut halted_dispatch = false;
- for view_id in responder_chain.iter().rev() {
+ for view_id in path.iter().rev() {
if let Some(mut view) = self
.ctx
.windows
@@ -635,6 +635,29 @@ impl MutableAppContext {
self,
)));
+ {
+ let mut app = self.upgrade();
+ let presenter = presenter.clone();
+ window.on_event(Box::new(move |event, window| {
+ log::info!("event {:?}", event);
+ app.update(|ctx| {
+ ctx.pending_flushes += 1;
+ let actions = presenter
+ .borrow_mut()
+ .dispatch_event(event, ctx.downgrade());
+ for action in actions {
+ ctx.dispatch_action(
+ window_id,
+ &action.path,
+ action.name,
+ action.arg.as_ref(),
+ );
+ }
+ ctx.flush_effects();
+ })
+ }));
+ }
+
{
let mut app = self.upgrade();
let presenter = presenter.clone();
@@ -17,6 +17,7 @@ pub enum Foreground {
Test(smol::LocalExecutor<'static>),
}
+#[must_use]
#[pin_project(project = ForegroundTaskProject)]
pub enum ForegroundTask<T> {
Platform(#[pin] async_task::Task<T>),
@@ -31,8 +31,8 @@ use std::{
cell::RefCell,
ffi::c_void,
mem, ptr,
- rc::Rc,
- time::{Duration, Instant},
+ rc::{Rc, Weak},
+ time::Duration,
};
use super::{geometry::RectFExt, renderer::Renderer};
@@ -330,24 +330,33 @@ extern "C" fn dealloc_view(this: &Object, _: Sel) {
extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
let window_state = unsafe { get_window_state(this) };
- let mut window_state_borrow = window_state.as_ref().borrow_mut();
+ let weak_window_state = Rc::downgrade(&window_state);
+ let mut window_state = window_state.as_ref().borrow_mut();
- let event = unsafe { Event::from_native(native_event, Some(window_state_borrow.size().y())) };
+ let event = unsafe { Event::from_native(native_event, Some(window_state.size().y())) };
if let Some(event) = event {
match event {
Event::LeftMouseDragged { position } => {
- schedule_synthetic_drag(&&window_state, position)
+ window_state.synthetic_drag_counter += 1;
+ window_state
+ .executor
+ .spawn(synthetic_drag(
+ weak_window_state,
+ window_state.synthetic_drag_counter,
+ position,
+ ))
+ .detach();
}
Event::LeftMouseUp { .. } => {
- post_inc(&mut window_state_borrow.synthetic_drag_counter);
+ window_state.synthetic_drag_counter += 1;
}
_ => {}
}
- if let Some(mut callback) = window_state_borrow.event_callback.take() {
- callback(event, &mut *window_state_borrow);
- window_state_borrow.event_callback = Some(callback);
+ if let Some(mut callback) = window_state.event_callback.take() {
+ callback(event, &mut *window_state);
+ window_state.event_callback = Some(callback);
}
}
}
@@ -450,30 +459,23 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
}
}
-fn schedule_synthetic_drag(window_state: &Rc<RefCell<WindowState>>, position: Vector2F) {
- let weak_window_state = Rc::downgrade(window_state);
- let mut window_state = window_state.as_ref().borrow_mut();
-
- let drag_id = post_inc(&mut window_state.synthetic_drag_counter);
- let instant = Instant::now() + Duration::from_millis(16);
-
- window_state
- .executor
- .spawn(async move {
- Timer::at(instant).await;
- if let Some(window_state) = weak_window_state.upgrade() {
- let mut window_state_borrow = window_state.as_ref().borrow_mut();
- if window_state_borrow.synthetic_drag_counter == drag_id {
- if let Some(mut callback) = window_state_borrow.event_callback.take() {
- schedule_synthetic_drag(&window_state, position);
- callback(
- Event::LeftMouseDragged { position },
- &mut *window_state_borrow,
- );
- window_state_borrow.event_callback = Some(callback);
- }
+async fn synthetic_drag(
+ window_state: Weak<RefCell<WindowState>>,
+ drag_id: usize,
+ position: Vector2F,
+) {
+ loop {
+ Timer::after(Duration::from_millis(16)).await;
+ if let Some(window_state) = window_state.upgrade() {
+ let mut window_state = window_state.borrow_mut();
+ if window_state.synthetic_drag_counter == drag_id {
+ if let Some(mut callback) = window_state.event_callback.take() {
+ callback(Event::LeftMouseDragged { position }, &mut *window_state);
+ window_state.event_callback = Some(callback);
}
+ } else {
+ break;
}
- })
- .detach();
+ }
+ }
}
@@ -109,11 +109,7 @@ impl Presenter {
})
}
- pub fn dispatch_event(
- &self,
- event: Event,
- app: &AppContext,
- ) -> Vec<(usize, &'static str, Box<dyn Any>)> {
+ pub fn dispatch_event(&self, event: Event, app: &AppContext) -> Vec<ActionToDispatch> {
let mut event_ctx = EventContext {
rendered_views: &self.rendered_views,
actions: Vec::new(),
@@ -128,6 +124,12 @@ impl Presenter {
}
}
+pub struct ActionToDispatch {
+ pub path: Vec<usize>,
+ pub name: &'static str,
+ pub arg: Box<dyn Any>,
+}
+
pub struct LayoutContext<'a> {
rendered_views: &'a mut HashMap<usize, Box<dyn Element>>,
parents: &'a mut HashMap<usize, usize>,
@@ -184,7 +186,7 @@ impl<'a> PaintContext<'a> {
pub struct EventContext<'a> {
rendered_views: &'a HashMap<usize, Box<dyn Element>>,
- actions: Vec<(usize, &'static str, Box<dyn Any>)>,
+ actions: Vec<ActionToDispatch>,
pub font_cache: &'a FontCache,
pub text_layout_cache: &'a TextLayoutCache,
view_stack: Vec<usize>,
@@ -208,8 +210,11 @@ impl<'a> EventContext<'a> {
}
pub fn dispatch_action<A: 'static + Any>(&mut self, name: &'static str, arg: A) {
- self.actions
- .push((*self.view_stack.last().unwrap(), name, Box::new(arg)));
+ self.actions.push(ActionToDispatch {
+ path: self.view_stack.clone(),
+ name,
+ arg: Box::new(arg),
+ });
}
}