11use std:: cell:: { Cell , RefCell } ;
2+ use std:: collections:: VecDeque ;
23use std:: ffi:: c_void;
34use std:: ptr;
45use std:: rc:: Rc ;
@@ -267,6 +268,7 @@ impl<'a> Window<'a> {
267268 keyboard_state : KeyboardState :: new ( ) ,
268269 frame_timer : Cell :: new ( None ) ,
269270 window_info : Cell :: new ( window_info) ,
271+ deferred_events : RefCell :: default ( ) ,
270272 } ) ;
271273
272274 let window_state_ptr = Rc :: into_raw ( Rc :: clone ( & window_state) ) ;
@@ -360,6 +362,9 @@ pub(super) struct WindowState {
360362 frame_timer : Cell < Option < CFRunLoopTimer > > ,
361363 /// The last known window info for this window.
362364 pub window_info : Cell < WindowInfo > ,
365+
366+ /// Events that will be triggered at the end of `window_handler`'s borrow.
367+ deferred_events : RefCell < VecDeque < Event > > ,
363368}
364369
365370impl WindowState {
@@ -378,14 +383,34 @@ impl WindowState {
378383 state
379384 }
380385
386+ /// Trigger the event immediately and return the event status.
387+ /// Will panic if `window_handler` is already borrowed (see `trigger_deferrable_event`).
381388 pub ( super ) fn trigger_event ( & self , event : Event ) -> EventStatus {
382389 let mut window = crate :: Window :: new ( Window { inner : & self . window_inner } ) ;
383- self . window_handler . borrow_mut ( ) . on_event ( & mut window, event)
390+ let mut window_handler = self . window_handler . borrow_mut ( ) ;
391+ let status = window_handler. on_event ( & mut window, event) ;
392+ self . send_deferred_events ( window_handler. as_mut ( ) ) ;
393+ status
394+ }
395+
396+ /// Trigger the event immediately if `window_handler` can be borrowed mutably,
397+ /// otherwise add the event to a queue that will be cleared once `window_handler`'s mutable borrow ends.
398+ /// As this method might result in the event triggering asynchronously, it can't reliably return the event status.
399+ pub ( super ) fn trigger_deferrable_event ( & self , event : Event ) {
400+ if let Ok ( mut window_handler) = self . window_handler . try_borrow_mut ( ) {
401+ let mut window = crate :: Window :: new ( Window { inner : & self . window_inner } ) ;
402+ window_handler. on_event ( & mut window, event) ;
403+ self . send_deferred_events ( window_handler. as_mut ( ) ) ;
404+ } else {
405+ self . deferred_events . borrow_mut ( ) . push_back ( event) ;
406+ }
384407 }
385408
386409 pub ( super ) fn trigger_frame ( & self ) {
387410 let mut window = crate :: Window :: new ( Window { inner : & self . window_inner } ) ;
388- self . window_handler . borrow_mut ( ) . on_frame ( & mut window) ;
411+ let mut window_handler = self . window_handler . borrow_mut ( ) ;
412+ window_handler. on_frame ( & mut window) ;
413+ self . send_deferred_events ( window_handler. as_mut ( ) ) ;
389414 }
390415
391416 pub ( super ) fn keyboard_state ( & self ) -> & KeyboardState {
@@ -419,6 +444,18 @@ impl WindowState {
419444
420445 ( * window_state_ptr) . frame_timer . set ( Some ( timer) ) ;
421446 }
447+
448+ fn send_deferred_events ( & self , window_handler : & mut dyn WindowHandler ) {
449+ let mut window = crate :: Window :: new ( Window { inner : & self . window_inner } ) ;
450+ loop {
451+ let next_event = self . deferred_events . borrow_mut ( ) . pop_front ( ) ;
452+ if let Some ( event) = next_event {
453+ window_handler. on_event ( & mut window, event) ;
454+ } else {
455+ break ;
456+ }
457+ }
458+ }
422459}
423460
424461unsafe impl < ' a > HasRawWindowHandle for Window < ' a > {
0 commit comments