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

[macOS] EventLoop::run_return with multiple windows does not return #2284

Closed
kcking opened this issue May 8, 2022 · 2 comments · Fixed by #2292
Closed

[macOS] EventLoop::run_return with multiple windows does not return #2284

kcking opened this issue May 8, 2022 · 2 comments · Fixed by #2292
Labels
B - bug Dang, that shouldn't have happened C - needs investigation Issue must be confirmed and researched DS - macos

Comments

@kcking
Copy link
Contributor

kcking commented May 8, 2022

Modifying the window_run_return example to spawn multiple windows (but keep a single event loop) results in the event_loop never returning control to the caller. This happens when focusing the non-first window. I have only been testing this on macOS.

// Limit this example to only compatible platforms.
#[cfg(any(
    target_os = "windows",
    target_os = "macos",
    target_os = "linux",
    target_os = "dragonfly",
    target_os = "freebsd",
    target_os = "netbsd",
    target_os = "openbsd"
))]
fn main() {
    use std::{thread::sleep, time::Duration};

    use simple_logger::SimpleLogger;
    use winit::{
        event::{Event, WindowEvent},
        event_loop::EventLoop,
        platform::run_return::EventLoopExtRunReturn,
        window::{Window, WindowBuilder},
    };
    let mut event_loop = EventLoop::new();

    SimpleLogger::new().init().unwrap();
    let _window = WindowBuilder::new()
        .with_title("A fantastic window!")
        .build(&event_loop)
        .unwrap();

    let mut quit = false;

    let mut frame = 0u128;

    let mut windows = vec![];

    while !quit {
        frame += 1;
        event_loop.run_return(|event, _, control_flow| {
            control_flow.set_wait();

            if let Event::WindowEvent { event, .. } = &event {
                // Print only Window events to reduce noise
                println!("{:?}", event);
            }

            match event {
                Event::WindowEvent {
                    event: WindowEvent::CloseRequested,
                    ..
                } => {
                    quit = true;
                }
                Event::MainEventsCleared => {
                    control_flow.set_exit();
                }
                _ => (),
            }
        });

        if frame % 300 == 0 {
            windows.push(Window::new(&event_loop));
        }

        // Sleep for 1/60 second to simulate rendering
        println!("rendering");
        sleep(Duration::from_millis(16));
    }
}

#[cfg(any(target_os = "ios", target_os = "android", target_arch = "wasm32"))]
fn main() {
    println!("This platform doesn't support run_return.");
}
@kcking
Copy link
Contributor Author

kcking commented May 9, 2022

With some debugging I found that the cause appears to be the is_dialog logic in

let is_visible: BOOL = msg_send![dialog, isVisible];

hard-coding this to false fixes the issue for me, but I'm first going to look further into what this logic is for and if there is a general fix.

@maroider maroider added B - bug Dang, that shouldn't have happened DS - macos C - needs investigation Issue must be confirmed and researched labels May 9, 2022
@madsmtm
Copy link
Member

madsmtm commented Jun 8, 2022

Thanks for the detailed instructions, makes it very easy to reproduce the issue!

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 C - needs investigation Issue must be confirmed and researched DS - macos
Development

Successfully merging a pull request may close this issue.

3 participants