11use std:: cell:: { Cell , RefCell } ;
2+ use std:: collections:: VecDeque ;
23use std:: ffi:: c_void;
34use std:: ptr;
45use std:: rc:: Rc ;
@@ -71,7 +72,6 @@ impl WindowInner {
7172 pub ( super ) fn close ( & self ) {
7273 if self . open . get ( ) {
7374 self . open . set ( false ) ;
74-
7575 unsafe {
7676 // Take back ownership of the NSView's Rc<WindowState>
7777 let state_ptr: * const c_void = * ( * self . ns_view ) . get_ivar ( BASEVIEW_STATE_IVAR ) ;
@@ -267,6 +267,7 @@ impl<'a> Window<'a> {
267267 keyboard_state : KeyboardState :: new ( ) ,
268268 frame_timer : Cell :: new ( None ) ,
269269 window_info : Cell :: new ( window_info) ,
270+ deferred_events : RefCell :: default ( ) ,
270271 } ) ;
271272
272273 let window_state_ptr = Rc :: into_raw ( Rc :: clone ( & window_state) ) ;
@@ -360,6 +361,9 @@ pub(super) struct WindowState {
360361 frame_timer : Cell < Option < CFRunLoopTimer > > ,
361362 /// The last known window info for this window.
362363 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 > > ,
363367}
364368
365369impl WindowState {
@@ -378,14 +382,34 @@ impl WindowState {
378382 state
379383 }
380384
385+ /// Trigger the event immediately and return the event status.
386+ /// Will panic if `window_handler` is already borrowed (see `trigger_deferrable_event`).
381387 pub ( super ) fn trigger_event ( & self , event : Event ) -> EventStatus {
382388 let mut window = crate :: Window :: new ( Window { inner : & self . window_inner } ) ;
383- 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+ }
384406 }
385407
386408 pub ( super ) fn trigger_frame ( & self ) {
387409 let mut window = crate :: Window :: new ( Window { inner : & self . window_inner } ) ;
388- 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 ( ) ) ;
389413 }
390414
391415 pub ( super ) fn keyboard_state ( & self ) -> & KeyboardState {
@@ -419,6 +443,18 @@ impl WindowState {
419443
420444 ( * window_state_ptr) . frame_timer . set ( Some ( timer) ) ;
421445 }
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+ }
422458}
423459
424460unsafe impl < ' a > HasRawWindowHandle for Window < ' a > {
0 commit comments