@@ -16,6 +16,7 @@ use winapi::shared::basetsd::DWORD_PTR;
16
16
use winapi:: shared:: basetsd:: UINT_PTR ;
17
17
use std:: { mem, ptr} ;
18
18
use std:: sync:: Arc ;
19
+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
19
20
use std:: time:: { Duration , Instant } ;
20
21
use std:: rc:: Rc ;
21
22
use std:: cell:: RefCell ;
@@ -129,11 +130,10 @@ pub(crate) struct SubclassInput<T> {
129
130
130
131
impl < T > SubclassInput < T > {
131
132
unsafe fn send_event ( & self , event : Event < T > ) {
132
- let runner = self . event_loop_runner . borrow_mut ( ) ;
133
- if let Some ( runner) = * runner {
134
- ( * runner) . process_event ( event) ;
135
- } else {
136
- panic ! ( "Attempted to send event without active runner" ) ;
133
+ let mut runner = self . event_loop_runner . borrow_mut ( ) ;
134
+ match * runner {
135
+ ELRSharedOption :: Runner ( runner) => ( * runner) . process_event ( event) ,
136
+ ELRSharedOption :: Buffer ( ref mut buffer) => buffer. push ( event)
137
137
}
138
138
}
139
139
}
@@ -145,11 +145,10 @@ struct ThreadMsgTargetSubclassInput<T> {
145
145
146
146
impl < T > ThreadMsgTargetSubclassInput < T > {
147
147
unsafe fn send_event ( & self , event : Event < T > ) {
148
- let runner = self . event_loop_runner . borrow_mut ( ) ;
149
- if let Some ( runner) = * runner {
150
- ( * runner) . process_event ( event) ;
151
- } else {
152
- panic ! ( "Attempted to send event without active runner" ) ;
148
+ let mut runner = self . event_loop_runner . borrow_mut ( ) ;
149
+ match * runner {
150
+ ELRSharedOption :: Runner ( runner) => ( * runner) . process_event ( event) ,
151
+ ELRSharedOption :: Buffer ( ref mut buffer) => buffer. push ( event)
153
152
}
154
153
}
155
154
}
@@ -159,6 +158,7 @@ pub struct EventLoop<T> {
159
158
thread_id : DWORD ,
160
159
thread_msg_target : HWND ,
161
160
thread_msg_sender : Sender < T > ,
161
+ trigger_newevents_on_redraw : Arc < AtomicBool > ,
162
162
pub ( crate ) runner_shared : EventLoopRunnerShared < T > ,
163
163
}
164
164
@@ -171,12 +171,13 @@ impl<T> EventLoop<T> {
171
171
become_dpi_aware ( dpi_aware) ;
172
172
173
173
let thread_id = unsafe { processthreadsapi:: GetCurrentThreadId ( ) } ;
174
- let runner_shared = Rc :: new ( RefCell :: new ( None ) ) ;
174
+ let runner_shared = Rc :: new ( RefCell :: new ( ELRSharedOption :: Buffer ( vec ! [ ] ) ) ) ;
175
175
let ( thread_msg_target, thread_msg_sender) = thread_event_target_window ( runner_shared. clone ( ) ) ;
176
176
177
177
EventLoop {
178
178
thread_id,
179
179
thread_msg_target, thread_msg_sender,
180
+ trigger_newevents_on_redraw : Arc :: new ( AtomicBool :: new ( true ) ) ,
180
181
runner_shared
181
182
}
182
183
}
@@ -197,7 +198,19 @@ impl<T> EventLoop<T> {
197
198
modal_loop_data : None ,
198
199
event_handler : & mut event_handler
199
200
} ;
200
- * runner. event_loop . events_loop . runner_shared . borrow_mut ( ) = Some ( & mut runner) ;
201
+ {
202
+ let runner_shared = runner. event_loop . events_loop . runner_shared . clone ( ) ;
203
+ let mut runner_shared = runner_shared. borrow_mut ( ) ;
204
+ let mut event_buffer = vec ! [ ] ;
205
+ if let ELRSharedOption :: Buffer ( ref mut buffer) = * runner_shared {
206
+ mem:: swap ( buffer, & mut event_buffer) ;
207
+ }
208
+ for event in event_buffer. drain ( ..) {
209
+ runner. process_event ( event) ;
210
+ }
211
+ * runner_shared = ELRSharedOption :: Runner ( & mut runner) ;
212
+ }
213
+
201
214
let timer_handle = winuser:: SetTimer ( ptr:: null_mut ( ) , 0 , 0x7FFFFFFF , None ) ;
202
215
203
216
let mut msg = mem:: uninitialized ( ) ;
@@ -242,7 +255,7 @@ impl<T> EventLoop<T> {
242
255
}
243
256
244
257
runner. call_event_handler ( Event :: LoopDestroyed ) ;
245
- * runner. event_loop . events_loop . runner_shared . borrow_mut ( ) = None ;
258
+ * runner. event_loop . events_loop . runner_shared . borrow_mut ( ) = ELRSharedOption :: Buffer ( vec ! [ ] ) ;
246
259
}
247
260
248
261
drop ( event_handler) ;
@@ -259,12 +272,17 @@ impl<T> EventLoop<T> {
259
272
#[ inline( always) ]
260
273
pub ( crate ) fn create_thread_executor ( & self ) -> EventLoopThreadExecutor {
261
274
EventLoopThreadExecutor {
262
- thread_id : self . thread_id
275
+ thread_id : self . thread_id ,
276
+ trigger_newevents_on_redraw : self . trigger_newevents_on_redraw . clone ( )
263
277
}
264
278
}
265
279
}
266
280
267
- pub ( crate ) type EventLoopRunnerShared < T > = Rc < RefCell < Option < * mut EventLoopRunner < T > > > > ;
281
+ pub ( crate ) type EventLoopRunnerShared < T > = Rc < RefCell < ELRSharedOption < T > > > ;
282
+ pub ( crate ) enum ELRSharedOption < T > {
283
+ Runner ( * mut EventLoopRunner < T > ) ,
284
+ Buffer ( Vec < Event < T > > )
285
+ }
268
286
pub ( crate ) struct EventLoopRunner < T > {
269
287
event_loop : :: EventLoop < T > ,
270
288
control_flow : ControlFlow ,
@@ -346,8 +364,10 @@ impl<T> EventLoopRunner<T> {
346
364
}
347
365
348
366
unsafe fn process_event ( & mut self , event : Event < T > ) {
367
+ // If we're in the middle of a modal loop, only set the timer for zero if it hasn't been
368
+ // reset in a prior call to `process_event`.
349
369
if let Some ( ModalLoopData { hwnd, timer_handle} ) = self . modal_loop_data {
350
- if ! self . event_processing_active ( ) {
370
+ if self . runner_state != RunnerState :: HandlingEvents {
351
371
winuser:: SetTimer ( hwnd, timer_handle, 0 , None ) ;
352
372
}
353
373
}
@@ -385,10 +405,9 @@ impl<T> EventLoopRunner<T> {
385
405
ControlFlow :: Poll |
386
406
ControlFlow :: Exit => unreachable ! ( )
387
407
}
388
-
389
- self . runner_state = RunnerState :: HandlingEvents ;
390
408
}
391
409
410
+ self . runner_state = RunnerState :: HandlingEvents ;
392
411
self . call_event_handler ( event) ;
393
412
}
394
413
@@ -437,6 +456,12 @@ impl<T> EventLoopRunner<T> {
437
456
438
457
unsafe fn call_event_handler ( & mut self , event : Event < T > ) {
439
458
if self . event_handler != mem:: zeroed ( ) {
459
+ match event {
460
+ Event :: NewEvents ( _) => self . event_loop . events_loop . trigger_newevents_on_redraw . store ( true , Ordering :: Relaxed ) ,
461
+ Event :: EventsCleared => self . event_loop . events_loop . trigger_newevents_on_redraw . store ( false , Ordering :: Relaxed ) ,
462
+ _ => ( )
463
+ }
464
+
440
465
if self . control_flow != ControlFlow :: Exit {
441
466
( * self . event_handler ) ( event, & self . event_loop , & mut self . control_flow ) ;
442
467
} else {
@@ -446,15 +471,6 @@ impl<T> EventLoopRunner<T> {
446
471
panic ! ( "Tried to call event handler with null handler" ) ;
447
472
}
448
473
}
449
-
450
- fn event_processing_active ( & self ) -> bool {
451
- match self . runner_state {
452
- RunnerState :: HandlingEvents => true ,
453
- RunnerState :: DeferredNewEvents ( ..) |
454
- RunnerState :: New |
455
- RunnerState :: Idle ( ..) => false
456
- }
457
- }
458
474
}
459
475
460
476
// Implementation taken from https://github.com/rust-lang/rust/blob/db5476571d9b27c862b95c1e64764b0ac8980e23/src/libstd/sys/windows/mod.rs
@@ -490,7 +506,8 @@ impl<T> Drop for EventLoop<T> {
490
506
}
491
507
492
508
pub ( crate ) struct EventLoopThreadExecutor {
493
- thread_id : DWORD
509
+ thread_id : DWORD ,
510
+ trigger_newevents_on_redraw : Arc < AtomicBool >
494
511
}
495
512
496
513
impl EventLoopThreadExecutor {
@@ -500,6 +517,10 @@ impl EventLoopThreadExecutor {
500
517
self . thread_id == cur_thread_id
501
518
}
502
519
520
+ pub ( super ) fn trigger_newevents_on_redraw ( & self ) -> bool {
521
+ !self . in_event_loop_thread ( ) || self . trigger_newevents_on_redraw . load ( Ordering :: Relaxed )
522
+ }
523
+
503
524
/// Executes a function in the event loop thread. If we're already in the event loop thread,
504
525
/// we just call the function directly.
505
526
///
@@ -586,6 +607,12 @@ lazy_static! {
586
607
winuser:: RegisterWindowMessageA ( "Winit::InitialDpiMsg\0 " . as_ptr( ) as LPCSTR )
587
608
}
588
609
} ;
610
+ // Message sent by a `Window` if it's requesting a redraw without sending a NewEvents.
611
+ pub static ref REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID : u32 = {
612
+ unsafe {
613
+ winuser:: RegisterWindowMessageA ( "Winit::RequestRedrawNoNewevents\0 " . as_ptr( ) as LPCSTR )
614
+ }
615
+ } ;
589
616
static ref THREAD_EVENT_TARGET_WINDOW_CLASS : Vec <u16 > = unsafe {
590
617
use std:: ffi:: OsStr ;
591
618
use std:: os:: windows:: ffi:: OsStrExt ;
@@ -708,7 +735,7 @@ unsafe extern "system" fn public_window_callback<T>(
708
735
}
709
736
winuser:: WM_ENTERSIZEMOVE => {
710
737
let modal_timer_handle = subclass_input. window_state . lock ( ) . modal_timer_handle ;
711
- if let Some ( runner) = * subclass_input. event_loop_runner . borrow_mut ( ) {
738
+ if let ELRSharedOption :: Runner ( runner) = * subclass_input. event_loop_runner . borrow_mut ( ) {
712
739
( * runner) . modal_loop_data = Some ( ModalLoopData {
713
740
hwnd : window,
714
741
timer_handle : modal_timer_handle
@@ -719,7 +746,7 @@ unsafe extern "system" fn public_window_callback<T>(
719
746
} ,
720
747
winuser:: WM_EXITSIZEMOVE => {
721
748
let modal_timer_handle = subclass_input. window_state . lock ( ) . modal_timer_handle ;
722
- if let Some ( runner) = * subclass_input. event_loop_runner . borrow_mut ( ) {
749
+ if let ELRSharedOption :: Runner ( runner) = * subclass_input. event_loop_runner . borrow_mut ( ) {
723
750
( * runner) . modal_loop_data = None ;
724
751
}
725
752
winuser:: SetTimer ( window, modal_timer_handle, 0x7FFFFFFF , None ) ;
@@ -729,7 +756,7 @@ unsafe extern "system" fn public_window_callback<T>(
729
756
let modal_timer_handle = subclass_input. window_state . lock ( ) . modal_timer_handle ;
730
757
if wparam == modal_timer_handle {
731
758
let runner = subclass_input. event_loop_runner . borrow_mut ( ) ;
732
- if let Some ( runner) = * runner {
759
+ if let ELRSharedOption :: Runner ( runner) = * runner {
733
760
let runner = & mut * runner;
734
761
if runner. modal_loop_data . is_some ( ) {
735
762
runner. events_cleared ( ) ;
@@ -791,12 +818,44 @@ unsafe extern "system" fn public_window_callback<T>(
791
818
0
792
819
} ,
793
820
821
+ _ if msg == * REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID => {
822
+ use events:: WindowEvent :: RedrawRequested ;
823
+ let runner = subclass_input. event_loop_runner . borrow_mut ( ) ;
824
+ if let ELRSharedOption :: Runner ( runner) = * runner {
825
+ let runner = & mut * runner;
826
+ match runner. runner_state {
827
+ RunnerState :: Idle ( ..) |
828
+ RunnerState :: DeferredNewEvents ( ..) => runner. call_event_handler ( Event :: WindowEvent {
829
+ window_id : SuperWindowId ( WindowId ( window) ) ,
830
+ event : RedrawRequested ,
831
+ } ) ,
832
+ _ => ( )
833
+ }
834
+ }
835
+ 0
836
+ } ,
794
837
winuser:: WM_PAINT => {
795
- use events:: WindowEvent :: Redraw ;
796
- subclass_input . send_event ( Event :: WindowEvent {
838
+ use events:: WindowEvent :: RedrawRequested ;
839
+ let event = || Event :: WindowEvent {
797
840
window_id : SuperWindowId ( WindowId ( window) ) ,
798
- event : Redraw ,
799
- } ) ;
841
+ event : RedrawRequested ,
842
+ } ;
843
+
844
+ let mut send_event = false ;
845
+ {
846
+ let runner = subclass_input. event_loop_runner . borrow_mut ( ) ;
847
+ if let ELRSharedOption :: Runner ( runner) = * runner {
848
+ let runner = & mut * runner;
849
+ match runner. runner_state {
850
+ RunnerState :: Idle ( ..) |
851
+ RunnerState :: DeferredNewEvents ( ..) => runner. call_event_handler ( event ( ) ) ,
852
+ _ => send_event = true
853
+ }
854
+ }
855
+ }
856
+ if send_event {
857
+ subclass_input. send_event ( event ( ) ) ;
858
+ }
800
859
commctrl:: DefSubclassProc ( window, msg, wparam, lparam)
801
860
} ,
802
861
0 commit comments