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