@@ -82,11 +82,13 @@ where
8282#[ derive( Default ) ]
8383struct Handler {
8484 ready : AtomicBool ,
85+ in_callback : AtomicBool ,
8586 control_flow : Mutex < ControlFlow > ,
8687 control_flow_prev : Mutex < ControlFlow > ,
8788 start_time : Mutex < Option < Instant > > ,
8889 callback : Mutex < Option < Box < dyn EventHandler > > > ,
8990 pending_events : Mutex < VecDeque < Event < Never > > > ,
91+ deferred_events : Mutex < VecDeque < Event < Never > > > ,
9092 pending_redraw : Mutex < Vec < WindowId > > ,
9193 waker : Mutex < EventLoopWaker > ,
9294}
@@ -99,6 +101,10 @@ impl Handler {
99101 self . pending_events . lock ( ) . unwrap ( )
100102 }
101103
104+ fn deferred < ' a > ( & ' a self ) -> MutexGuard < ' a , VecDeque < Event < Never > > > {
105+ self . deferred_events . lock ( ) . unwrap ( )
106+ }
107+
102108 fn redraw < ' a > ( & ' a self ) -> MutexGuard < ' a , Vec < WindowId > > {
103109 self . pending_redraw . lock ( ) . unwrap ( )
104110 }
@@ -143,10 +149,22 @@ impl Handler {
143149 mem:: replace ( & mut * self . events ( ) , Default :: default ( ) )
144150 }
145151
152+ fn take_deferred ( & self ) -> VecDeque < Event < Never > > {
153+ mem:: replace ( & mut * self . deferred ( ) , Default :: default ( ) )
154+ }
155+
146156 fn should_redraw ( & self ) -> Vec < WindowId > {
147157 mem:: replace ( & mut * self . redraw ( ) , Default :: default ( ) )
148158 }
149159
160+ fn get_in_callback ( & self ) -> bool {
161+ self . in_callback . load ( Ordering :: Acquire )
162+ }
163+
164+ fn set_in_callback ( & self , in_callback : bool ) {
165+ self . in_callback . store ( in_callback, Ordering :: Release ) ;
166+ }
167+
150168 fn handle_nonuser_event ( & self , event : Event < Never > ) {
151169 if let Some ( ref mut callback) = * self . callback . lock ( ) . unwrap ( ) {
152170 callback. handle_nonuser_event (
@@ -181,13 +199,17 @@ impl AppState {
181199 }
182200
183201 pub fn exit ( ) {
202+ HANDLER . set_in_callback ( true ) ;
184203 HANDLER . handle_nonuser_event ( Event :: LoopDestroyed ) ;
204+ HANDLER . set_in_callback ( false ) ;
185205 }
186206
187207 pub fn launched ( ) {
188208 HANDLER . set_ready ( ) ;
189209 HANDLER . waker ( ) . start ( ) ;
210+ HANDLER . set_in_callback ( true ) ;
190211 HANDLER . handle_nonuser_event ( Event :: NewEvents ( StartCause :: Init ) ) ;
212+ HANDLER . set_in_callback ( false ) ;
191213 }
192214
193215 pub fn wakeup ( ) {
@@ -214,7 +236,9 @@ impl AppState {
214236 } ,
215237 ControlFlow :: Exit => StartCause :: Poll , //panic!("unexpected `ControlFlow::Exit`"),
216238 } ;
239+ HANDLER . set_in_callback ( true ) ;
217240 HANDLER . handle_nonuser_event ( Event :: NewEvents ( cause) ) ;
241+ HANDLER . set_in_callback ( false ) ;
218242 }
219243
220244 // This is called from multiple threads at present
@@ -227,38 +251,49 @@ impl AppState {
227251
228252 pub fn queue_event ( event : Event < Never > ) {
229253 if !unsafe { msg_send ! [ class!( NSThread ) , isMainThread] } {
230- panic ! ( "uh-oh" ) ;
254+ panic ! ( "Event queued from different thread: {:#?}" , event ) ;
231255 }
232256 HANDLER . events ( ) . push_back ( event) ;
233257 }
234258
235259 pub fn queue_events ( mut events : VecDeque < Event < Never > > ) {
236260 if !unsafe { msg_send ! [ class!( NSThread ) , isMainThread] } {
237- panic ! ( "uh-ohs" ) ;
261+ panic ! ( "Events queued from different thread: {:#?}" , events ) ;
238262 }
239263 HANDLER . events ( ) . append ( & mut events) ;
240264 }
241265
242266 pub fn send_event_immediately ( event : Event < Never > ) {
243267 if !unsafe { msg_send ! [ class!( NSThread ) , isMainThread] } {
244- panic ! ( "uh-oh" ) ;
268+ panic ! ( "Event sent from different thread: {:#?}" , event) ;
269+ }
270+ HANDLER . deferred ( ) . push_back ( event) ;
271+ if !HANDLER . get_in_callback ( ) {
272+ HANDLER . set_in_callback ( true ) ;
273+ for event in HANDLER . take_deferred ( ) {
274+ HANDLER . handle_nonuser_event ( event) ;
275+ }
276+ HANDLER . set_in_callback ( false ) ;
245277 }
246- HANDLER . handle_nonuser_event ( event) ;
247278 }
248279
249280 pub fn cleared ( ) {
250281 if !HANDLER . is_ready ( ) { return }
251- HANDLER . handle_user_events ( ) ;
252- for event in HANDLER . take_events ( ) {
253- HANDLER . handle_nonuser_event ( event) ;
254- }
255- for window_id in HANDLER . should_redraw ( ) {
256- HANDLER . handle_nonuser_event ( Event :: WindowEvent {
257- window_id,
258- event : WindowEvent :: RedrawRequested ,
259- } ) ;
282+ if !HANDLER . get_in_callback ( ) {
283+ HANDLER . set_in_callback ( true ) ;
284+ HANDLER . handle_user_events ( ) ;
285+ for event in HANDLER . take_events ( ) {
286+ HANDLER . handle_nonuser_event ( event) ;
287+ }
288+ for window_id in HANDLER . should_redraw ( ) {
289+ HANDLER . handle_nonuser_event ( Event :: WindowEvent {
290+ window_id,
291+ event : WindowEvent :: RedrawRequested ,
292+ } ) ;
293+ }
294+ HANDLER . handle_nonuser_event ( Event :: EventsCleared ) ;
295+ HANDLER . set_in_callback ( false ) ;
260296 }
261- HANDLER . handle_nonuser_event ( Event :: EventsCleared ) ;
262297 if HANDLER . should_exit ( ) {
263298 let _: ( ) = unsafe { msg_send ! [ NSApp ( ) , stop: nil] } ;
264299 return
0 commit comments