Not receiving `RedrawRequested` events for all windows that `.request_redraw()`
ickk opened this issue · comments
Description
When I create multiple windows with winit, and for each window call window.request_redraw()
in the AboutToWait
handler, I do not receive the corresponding WindowEvent::RedrawRequested
for all of the windows that requested.
minimal reproduction:
use winit::{
event::{Event, WindowEvent},
event_loop::EventLoop,
window::WindowBuilder,
};
const WINDOW_COUNT: usize = 5;
fn main() {
let event_loop = EventLoop::new().unwrap();
let windows = Vec::from_iter(
std::iter::repeat_with(|| WindowBuilder::new().build(&event_loop).unwrap()).take(WINDOW_COUNT),
);
let mut ticks = 500;
event_loop
.run(|event, elwt| match event {
Event::AboutToWait => {
for (i, window) in windows.iter().enumerate() {
eprintln!("request_redraw for window {i}",);
window.request_redraw();
}
ticks -= 1;
if ticks <= 0 {
elwt.exit()
}
}
Event::WindowEvent {
window_id,
event: WindowEvent::RedrawRequested,
} => {
let i = windows.iter().position(|w| w.id() == window_id).unwrap();
eprintln!("received RedrawRequested for window {i}");
}
_ => (),
})
.unwrap();
}
output observed:
..
request_redraw for window 0
request_redraw for window 1
request_redraw for window 2
request_redraw for window 3
request_redraw for window 4
received RedrawRequested for window 4
received RedrawRequested for window 3
request_redraw for window 0
request_redraw for window 1
request_redraw for window 2
request_redraw for window 3
request_redraw for window 4
received RedrawRequested for window 4
received RedrawRequested for window 3
..
that is, I only receive the RedrawRequested
event for the last 2 windows.
If I also call request_redraw()
inside the RedrawRequested
handler for the given window, as follows:
Event::WindowEvent {
window_id,
event: WindowEvent::RedrawRequested,
} => {
let i = windows.iter().position(|w| w.id() == window_id).unwrap();
eprintln!("received RedrawRequested for window {i}, requesting redraw for window {i}");
windows[i].request_redraw();
}
_ => (),
then I observe the following:
..
request_redraw for window 0
request_redraw for window 1
request_redraw for window 2
request_redraw for window 3
request_redraw for window 4
received RedrawRequested for window 4, requesting redraw for window 4
received RedrawRequested for window 4, requesting redraw for window 4
request_redraw for window 0
request_redraw for window 1
request_redraw for window 2
request_redraw for window 3
request_redraw for window 4
received RedrawRequested for window 4, requesting redraw for window 4
received RedrawRequested for window 4, requesting redraw for window 4
..
that is, I receive two consecutive RedrawRequested
events (sometimes just 1), but only ever for the last window.
Neither approach behaves as I would expect. I would expect to reliably receive a single RedrawRequested
event for each window
Windows version
Microsoft Windows [Version 10.0.19045.4291]
Winit version
v0.29.15
I skimmed the source, and I think this might be because of the way winit tries to get RedrawWindow
/WM_PAINT
to throttle redraws?
Yes, redraws are throttled by the compositor usually, though, WM_PAINT
looks so broken that winit should likely use something else.