Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not receiving RedrawRequested events for all windows that .request_redraw() #3648

Open
ickk opened this issue Apr 23, 2024 · 2 comments
Open
Labels
B - bug Dang, that shouldn't have happened DS - windows

Comments

@ickk
Copy link

ickk commented Apr 23, 2024

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

@ickk ickk added B - bug Dang, that shouldn't have happened DS - windows labels Apr 23, 2024
@ickk
Copy link
Author

ickk commented Apr 23, 2024

I skimmed the source, and I think this might be because of the way winit tries to get RedrawWindow/WM_PAINT to throttle redraws?

@kchibisov
Copy link
Member

Yes, redraws are throttled by the compositor usually, though, WM_PAINT looks so broken that winit should likely use something else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B - bug Dang, that shouldn't have happened DS - windows
Development

No branches or pull requests

2 participants