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

Multiwindow example is broken on OS X #56

Closed
tomaka opened this issue Nov 3, 2016 · 15 comments · Fixed by #132
Closed

Multiwindow example is broken on OS X #56

tomaka opened this issue Nov 3, 2016 · 15 comments · Fixed by #132

Comments

@tomaka
Copy link
Contributor

tomaka commented Nov 3, 2016

Original: rust-windowing/glutin#618

@paulrouget
Copy link
Contributor

Afaict, it crashes on nextEventMatchingMask_untilDate_inMode_dequeue_.

cargo run --example multiwindow
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/examples/multiwindow`
thread 'thread '<unnamed><unnamed>' panicked at '' panicked at 'called `Option::unwrap()` on a `None` valuecalled `Option::unwrap()` on a `None` value', ', ../src/libcore/option.rs../src/libcore/option.rs::323323

stack backtrace:
   1:        0x10dd582f8 - std::sys::backtrace::tracing::imp::write::h22f199c1dbb72ba2
   2:        0x10dd5a5bf - std::panicking::default_hook::{{closure}}::h9a389c462b6a22dd
   3:        0x10dd59895 - std::panicking::default_hook::h852b4223c1c00c59
   4:        0x10dd59ea6 - std::panicking::rust_panic_with_hook::hcd9d05f53fa0dafc
   5:        0x10dd59d44 - std::panicking::begin_panic::hf6c488cee66e7f17
   6:        0x10dd59c62 - std::panicking::begin_panic_fmt::hb0a7126ee57cdd27
   7:        0x10dd59bc7 - rust_begin_unwind
   8:        0x10dd7f750 - core::panicking::panic_fmt::h9af671b78898cdba
   9:        0x10dd7f654 - core::panicking::panic::h1a2d1a6b50eaa468
  10:        0x10dd5abbb - __rust_maybe_catch_panic
  11:        0x10dd2666e - std::panicking::try::h3dfd7266c7742781
  12:        0x10dd24131 - std::panic::catch_unwind::he95d7ae2a73e9890
  13:        0x10dd2c676 - std::thread::Builder::spawn::{{closure}}::hab139d69c2939105
  14:        0x10dd29cbb - <F as alloc::boxed::FnBox<A>>::call_box::h1fe7796ba8cabf77
  15:        0x10dd59114 - std::sys::thread::Thread::new::thread_start::h50b05608a499d2b2
  16:     0x7fffb06ceaaa - _pthread_body
  17:     0x7fffb06ce9f6 - _pthread_start
stack backtrace:
   1:  fatal runtime error:  failed to initiate panic, error  5
   0x10dd582f8 - std::sys::backtrace::tracing::imp::write::error: process didn't exit successfully: `target/debug/examples/multiwindow` (signal: 6, SIGABRT: process abort signal)

@mitchmindtree
Copy link
Contributor

mitchmindtree commented Nov 8, 2016

@paulrouget what version of OS X are you on?

Just tested this on OS X 10.10.5 and it seems work fine. It does use about 300% CPU though due to the hot loop for each of the 3 window threads, however it doesn't crash at any point.

Edit: actually, not exactly sure why it uses up so much CPU as the loops are wait_events loops, which should just wait for events no?

@mitchmindtree
Copy link
Contributor

Printing the events from each of the window loops seems to show that they are just returning the Awakened event again and again (and no other events) as fast as possible in a hot loop.

@mitchmindtree
Copy link
Contributor

When switching the event loop from wait_events to poll_events and nesting it in a loop, the PollEvents iterator is empty and never yields any events for any of the windows.

@mitchmindtree
Copy link
Contributor

I tried removing the windows 2 and 3 to see if there was some conflict between windows or something, but the behaviour was the same.

Then I tried moving the run function call for the first window out of the spawned t1 thread so that it looped on the main thread instead and it started working perfectly again. It seems that the windows don't like polling or waiting for events on any thread other than main 😕

@paulrouget
Copy link
Contributor

Just tested this on OS X 10.10.5 and it seems work fine

10.12.1

@paulrouget
Copy link
Contributor

It seems that the windows don't like polling or waiting for events on any thread other than main

I remember testing multi glutin windows a while back. It looked like it worked. Not sure sure if events were properly received though. And I'm not sure about CPU.

I will check if this ever worked on my osx 10.11.

@mitchmindtree
Copy link
Contributor

When changing the example to run all windows on the main thread like this:

fn main() {
    let window1 = winit::WindowBuilder::new().build().unwrap();
    let window2 = winit::WindowBuilder::new().build().unwrap();
    let window3 = winit::WindowBuilder::new().build().unwrap();

    loop {
        poll_events(1, &window1);
        poll_events(2, &window2);
        poll_events(3, &window3);
        std::thread::sleep(std::time::Duration::from_millis(100));
    }
}

fn poll_events(i: i32, window: &winit::Window) {
    for event in window.poll_events() {
        println!("{:?} {:?}", i, &event);
        match event {
            winit::Event::Closed => break,
            _ => ()
        }
    }
}

it seems to behave fine, however, only window1 seems to receive most mouse or keyboard events.

It almost seems like input events are just being received by the first window that happens to poll for them, rather than only going to the currently focused window. For example, mouse coordinates are always relative to the currently focused window, however they are not necessarily received by that window (window1 normally receives them all regardless of focus as it is the first to poll in the loop above).

@mitchmindtree
Copy link
Contributor

@paulrouget i'm also interested in getting this working for a personal project, however I won't get time to do much digging this week. Feel free to ping me if you want me to run any tests though 👍

@paulrouget
Copy link
Contributor

do you get window2 key events when polling window1 key events?

@mitchmindtree
Copy link
Contributor

Yep, no matter what window is focused, window1 receives all key events when running the code I posted in my previous comment.

@paulrouget
Copy link
Contributor

alright - I think the way cocoa events are pulled is wrong. I'll look into it if I ever manage to fix that crash.

@paulrouget
Copy link
Contributor

paulrouget commented Nov 18, 2016

So first thing first: nextEventMatchingMask_untilDate_inMode_dequeue_ (used by wait_events) has to run in the main thread. It is now enforced in osx 10.12. This explains the crash.

Then, I'm not sure (and I can't test until crash is fixed), but afaict, we use NSApplication::nextEventMatchingMask instead of NSWindow::nextEventMatchingMask for each window, that might explain why we only get the events of all the events in the first window. Maybe we are supposed to sort out the event origin from a unique NSApplication::nextEventMatchingMask.

@paulrouget
Copy link
Contributor

/cc @pcwalton can you help figuring out what's the best approach here? How do we keep nextEventMatchingMask in the main thread, and do we need one global nextEventMatchingMask or one per window?

@tomaka
Copy link
Contributor Author

tomaka commented Nov 18, 2016

#20 is how I think this should be solved. I haven't had a lot of feedback though.

jrmuizel pushed a commit to jrmuizel/winit that referenced this issue Mar 29, 2017
Merge from upstream

CC rust-windowing#56

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/glutin/57)
<!-- Reviewable:end -->
tmfink pushed a commit to tmfink/winit that referenced this issue Jan 5, 2022
madsmtm pushed a commit to madsmtm/winit that referenced this issue Jun 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

3 participants