Skip to content

Commit 0558e9d

Browse files
committed
Implement new redraw API
1 parent 24a8410 commit 0558e9d

File tree

7 files changed

+84
-154
lines changed

7 files changed

+84
-154
lines changed

examples/request_redraw.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn main() {
2222
event: WindowEvent::CloseRequested,
2323
..
2424
} => *control_flow = ControlFlow::Exit,
25-
Event::EventsCleared => {
25+
Event::MainEventsCleared => {
2626
window.request_redraw();
2727
*control_flow = ControlFlow::WaitUntil(Instant::now() + Duration::new(1, 0))
2828
}

examples/window.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ fn main() {
2020
event: WindowEvent::CloseRequested,
2121
window_id,
2222
} if window_id == window.id() => *control_flow = ControlFlow::Exit,
23-
_ => *control_flow = ControlFlow::Wait,
23+
Event::MainEventsCleared => {
24+
window.request_redraw();
25+
}
26+
_ => *control_flow = ControlFlow::Poll,
2427
}
2528
});
2629
}

src/event.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,16 @@ pub enum Event<T> {
2929
UserEvent(T),
3030
/// Emitted when new events arrive from the OS to be processed.
3131
NewEvents(StartCause),
32-
/// Emitted when all of the event loop's events have been processed and control flow is about
33-
/// to be taken away from the program.
34-
EventsCleared,
32+
/// Emitted when all of the event loop's standard events have been processed and redraw event
33+
/// processing is about to begin.
34+
MainEventsCleared,
35+
36+
/// The OS or application has requested that the window be redrawn. This gets emitted after
37+
/// `MainEventsCleared`.
38+
RedrawRequested(WindowId),
39+
/// Emitted when all the redraw events have been processed. Also signals that control flow is
40+
/// about to be taken away from the program.
41+
RedrawEventsCleared,
3542

3643
/// Emitted when the event loop is being shut down. This is irreversable - if this event is
3744
/// emitted, it is guaranteed to be the last event emitted.
@@ -52,7 +59,9 @@ impl<T> Event<T> {
5259
WindowEvent { window_id, event } => Ok(WindowEvent { window_id, event }),
5360
DeviceEvent { device_id, event } => Ok(DeviceEvent { device_id, event }),
5461
NewEvents(cause) => Ok(NewEvents(cause)),
55-
EventsCleared => Ok(EventsCleared),
62+
MainEventsCleared => Ok(MainEventsCleared),
63+
RedrawRequested(window_id) => Ok(RedrawRequested(window_id)),
64+
RedrawEventsCleared => Ok(RedrawEventsCleared),
5665
LoopDestroyed => Ok(LoopDestroyed),
5766
Suspended => Ok(Suspended),
5867
Resumed => Ok(Resumed),
@@ -184,9 +193,6 @@ pub enum WindowEvent {
184193
value: f64,
185194
},
186195

187-
/// The OS or application has requested that the window be redrawn.
188-
RedrawRequested,
189-
190196
/// Touch event has been received
191197
Touch(Touch),
192198

src/lib.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,13 @@
4848
//!
4949
//! event_loop.run(move |event, _, control_flow| {
5050
//! match event {
51-
//! Event::EventsCleared => {
51+
//! Event::MainEventsCleared => {
5252
//! // Application update code.
53-
//!
53+
//!
5454
//! // Queue a RedrawRequested event.
5555
//! window.request_redraw();
5656
//! },
57-
//! Event::WindowEvent {
58-
//! event: WindowEvent::RedrawRequested,
59-
//! ..
60-
//! } => {
57+
//! Event::RedrawRequested(_window_id) => {
6158
//! // Redraw the application.
6259
//! //
6360
//! // It's preferrable to render in this event rather than in EventsCleared, since

src/platform_impl/windows/event_loop.rs

+1-49
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use std::{
2020
mem, panic, ptr,
2121
rc::Rc,
2222
sync::{
23-
atomic::{AtomicBool, Ordering},
2423
mpsc::{self, Receiver, Sender},
2524
Arc,
2625
},
@@ -92,7 +91,6 @@ pub struct EventLoop<T: 'static> {
9291

9392
pub struct EventLoopWindowTarget<T> {
9493
thread_id: DWORD,
95-
trigger_newevents_on_redraw: Arc<AtomicBool>,
9694
thread_msg_target: HWND,
9795
pub(crate) runner_shared: EventLoopRunnerShared<T>,
9896
}
@@ -119,7 +117,6 @@ impl<T: 'static> EventLoop<T> {
119117
window_target: RootELW {
120118
p: EventLoopWindowTarget {
121119
thread_id,
122-
trigger_newevents_on_redraw: Arc::new(AtomicBool::new(true)),
123120
thread_msg_target,
124121
runner_shared,
125122
},
@@ -218,7 +215,6 @@ impl<T> EventLoopWindowTarget<T> {
218215
pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor {
219216
EventLoopThreadExecutor {
220217
thread_id: self.thread_id,
221-
trigger_newevents_on_redraw: self.trigger_newevents_on_redraw.clone(),
222218
target_window: self.thread_msg_target,
223219
}
224220
}
@@ -289,7 +285,6 @@ impl<T> Drop for EventLoop<T> {
289285

290286
pub(crate) struct EventLoopThreadExecutor {
291287
thread_id: DWORD,
292-
trigger_newevents_on_redraw: Arc<AtomicBool>,
293288
target_window: HWND,
294289
}
295290

@@ -303,10 +298,6 @@ impl EventLoopThreadExecutor {
303298
self.thread_id == cur_thread_id
304299
}
305300

306-
pub(super) fn trigger_newevents_on_redraw(&self) -> bool {
307-
!self.in_event_loop_thread() || self.trigger_newevents_on_redraw.load(Ordering::Relaxed)
308-
}
309-
310301
/// Executes a function in the event loop thread. If we're already in the event loop thread,
311302
/// we just call the function directly.
312303
///
@@ -398,12 +389,6 @@ lazy_static! {
398389
winuser::RegisterWindowMessageA("Winit::InitialDpiMsg\0".as_ptr() as LPCSTR)
399390
}
400391
};
401-
// Message sent by a `Window` if it's requesting a redraw without sending a NewEvents.
402-
pub static ref REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID: u32 = {
403-
unsafe {
404-
winuser::RegisterWindowMessageA("Winit::RequestRedrawNoNewevents\0".as_ptr() as LPCSTR)
405-
}
406-
};
407392
// WPARAM is a bool specifying the `WindowFlags::MARKER_RETAIN_STATE_ON_SIZE` flag. See the
408393
// documentation in the `window_state` module for more information.
409394
pub static ref SET_RETAIN_STATE_ON_SIZE_MSG_ID: u32 = unsafe {
@@ -581,41 +566,8 @@ unsafe extern "system" fn public_window_callback<T>(
581566
0
582567
}
583568

584-
_ if msg == *REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID => {
585-
use crate::event::WindowEvent::RedrawRequested;
586-
subclass_input.window_state.lock().queued_out_of_band_redraw = false;
587-
588-
// This check makes sure that requesting a redraw during `EventsCleared`
589-
// handling dispatch `RedrawRequested` immediately after `EventsCleared`, without
590-
// spinning up a new event loop iteration. We do this because that's what the API
591-
// says to do.
592-
match subclass_input.event_loop_runner.handling_events() {
593-
true => {
594-
winuser::RedrawWindow(
595-
window,
596-
ptr::null(),
597-
ptr::null_mut(),
598-
winuser::RDW_INTERNALPAINT,
599-
);
600-
}
601-
false => {
602-
subclass_input
603-
.event_loop_runner
604-
.call_event_handler(Event::WindowEvent {
605-
window_id: RootWindowId(WindowId(window)),
606-
event: RedrawRequested,
607-
});
608-
}
609-
}
610-
611-
0
612-
}
613569
winuser::WM_PAINT => {
614-
use crate::event::WindowEvent::RedrawRequested;
615-
subclass_input.send_event(Event::WindowEvent {
616-
window_id: RootWindowId(WindowId(window)),
617-
event: RedrawRequested,
618-
});
570+
subclass_input.send_event(Event::RedrawRequested(RootWindowId(WindowId(window))));
619571
commctrl::DefSubclassProc(window, msg, wparam, lparam)
620572
}
621573

0 commit comments

Comments
 (0)