-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Workaround for egui run_native ! never return type #427
Comments
You don't need Realistically you will only need an Most of the existing backends that I am aware of target pure Rust apps and graphics stacks. There are a few for |
Thanks for that overview. I'm exploring these options in this repo visual_studio_cpp_egui_demo where I'm trying to statically link a c++ console project to an egui popup. I'm really looking to have the In checking out a The |
Maybe you can spawn As for alternative backends: you can also check out https://crates.io/crates/egui-macroquad, though the downsides with (all?) other backends is that they do not support reactive mode (only repainting when there is input). |
@emilk thanks for the tips. I gave putting it in a thread a shot with the following #[no_mangle]
pub extern fn start_egui_demo() {
let child = std::thread::spawn( move || {
let app = egui_demo_lib::WrapApp::default();
let options = eframe::NativeOptions {
// Let's show off that we support transparent windows
transparent: true,
decorated: true,
..Default::default()
};
eframe::run_native(Box::new(app), options);
});
child.join();
} Which compiles and links fine, but gives a run time error
winit does not like it being a background thread apparently. I followed the calls to run on the event_loop all the way down to the source so |
Please forgive the long-winded response, but this should contain all the info you need for this. TL;DR: You probably don't need to go to the trouble of patching Using egui/egui_glium/src/backend.rs Line 175 in e320ef6
The simplest possible patch is: let event_loop = if cfg!(target_os = "windows") {
glutin::platform::windows::EventLoopExtWindows::new_any_thread()
} else {
glutin::event_loop::EventLoop::with_user_event()
}; It depends on the implementation of That will at least unblock you on the main thread check if you just want to use You may also want to change the code you are using to spawn the thread. Using That's enough to get a window running in a new thread. The only thing left to discuss is the
The question is when do you need However, there is another caveat to beware of; You can still handle complex window lifecycle events even with ... And this gets back to what I originally suggested about using the lower layers. For instance, this |
Thank you for all of the quality information. It's greatly appreciated. I've usually focused on app development on frameworks, vs the nitty-gritty of the frameworks themselves. The target use case is having a single egui modal popup in a Windows C++ application. With data passed back and forth on modal open and close. Once I can get that working I'll see about multiple windows and asynchronous handling. I think the cleanest solution then is going manging the event loop myself. It should make the example I'm trying to develop be much more reusable. I hadn't realized that it was so easy to just the run_return() was so easy to do. So I modified the example as you suggested here. It's essentially the same except for use glium::glutin::platform::run_return::EventLoopExtRunReturn;
...
event_loop.run_return(move |event, _, control_flow| {} It's able to return but the window does not close after returning from the function. It does close after a 2nd GUI window does pop up or the C++ program terminates. You can see it at my example repo I'm trying to explicitly drop the window here but that doesn't kill it either. Based on the discussion in winit/issues/434 it just dropping it seems to be the right approach for killing the window. ...
glutin::event::Event::WindowEvent { event, .. } => {
egui.on_event(event, control_flow);
match control_flow {
glutin::event_loop::ControlFlow::Exit => {
println!("exiting");
std::mem::drop(display.gl_window().window());
println!("Dropped Winit Window");
std::mem::drop(display.gl_window());
println!("Dropped Gl Window")
//std::mem::drop(display);
}
_ => {
display.gl_window().window().request_redraw(); // TODO: ask egui if the events warrants a repaint instead
}
}
}
... I'm seeing this was a past bug that was supposed to be fixed /rust-windowing/winit/issues/7, winit/pull/416. Does Egui change the behavior of winit / glutin or is this an issue I should take to glutin? |
Well, I'm chasing that issue down with this issue in the glium repo, in summary, it seems to be an error on glium's part but I've found a workaround by calling I'm going to close this as it seems like the original question of how to find the workaround for the ! never return type has been answered. |
meant to close |
Since #631 |
@emilk It looks like the window will not be closed after On windows, I use this method to destroy window, however on linux, I don't know how to destroy the window. |
@emilk Thanks for the update on this, I'll update my minimal examples and test it out later this week. Appreciate all the work on the Egui framework! |
I was hoping to try and use egui for a pop dialog in a c++ program. I was able to link the demo library statically to a test c++ Hello World style program, but when it runs, when I quit the program due to the eframe::run_native() function returning never, it causes exceptions
lib.rs
c_wrapper.h
main.cpp
I understand that the never return type is useful when working with web processes to indicate a process should keep running, but on Native, windows in my case, where I want to close a process is there a way I can gracefully exit, and resume another c++ process?
The text was updated successfully, but these errors were encountered: