-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Continue execution after closing native eframe window #1889
Conversation
This will allow us to try out another event loop, one that continues execution after the window closes.
`true` by default. Only implemented for glow so far.
f45cfd7
to
2512aae
Compare
|
Does this allow recreating the window? |
Unfortunately, on my Mac EventLoopExtRunReturn::run_return crashes the second time it is called:
|
Yes: https://github.com/emilk/egui/blob/master/eframe/src/epi.rs#L593-L597 |
Ok, I'm going to merge this and see how it goes. |
I just test it on my Windows 10 PC, looks like there is still a problem. I build a minimized app, it is expected to exit gracefully after clicking close and reopen the window after waiting two seconds. use std::{thread::sleep, time::Duration};
use eframe::egui;
fn main() {
for _ in 0..10 {
eframe::run_native(
"Exit",
eframe::NativeOptions::default(),
Box::new(|_cc| Box::new(MyApp::default())),
);
sleep(Duration::from_secs(2));
}
}
#[derive(Default)]
struct MyApp {}
impl eframe::App for MyApp {
fn update(&mut self, _ctx: &egui::Context, _frame: &mut eframe::Frame) {
}
} I still encountered the same problem before. After clicking close, the window cannot be closed normally, and the task manager shows a timeout. After waiting for two seconds, the window closes and a new window opens. Same as #1223 (comment) 20220805_153041.mp4 |
@zu1k interesting! Could you please open an issue in the winit repo, and perhaps open a PR to add a call to |
It looks like So this maybe works #1877, I will have a try. |
It looks like a |
I found a way, this works on my win10. use instant::Duration;
use simple_logger::SimpleLogger;
use std::thread::sleep;
use winit::{
event::{Event, WindowEvent},
event_loop::EventLoop,
platform::run_return::EventLoopExtRunReturn,
window::Window,
};
fn main() {
SimpleLogger::new().init().unwrap();
let mut event_loop = EventLoop::new();
for _ in 0..5 {
{
let _window = Window::new(&event_loop).unwrap();
event_loop.run_return(move |event, _event_loop, control_flow| {
control_flow.set_wait();
match event {
Event::WindowEvent { event, window_id } => match event {
WindowEvent::CloseRequested => {
println!("Window {:?} has received the signal to close", window_id);
control_flow.set_exit();
}
_ => {}
},
_ => (),
}
});
}
// we need to call `run_return` again
event_loop.run_return(|_, _, cf| cf.set_exit());
sleep(Duration::from_secs(2));
}
} 20220806_105521.mp4 |
trying something similar with glutin and running the event_loop again does not seem to work on Linux, when i close the first window, the second window immediately closes. this is with egui 0.18.1 |
@zu1k thanks for investigating! So we need to reuse the same event_loop – is that true for both winit 0.28 and winit 0.29? |
@emilk I test it on winit master branch. Now I need to call |
I created an issue for this in #1918 |
@emilk I have just noticed that fn main() {
let native_options = eframe::NativeOptions {
// This is false to trigger App::on_exit when we closing the app with Cmd-Q.
run_and_return: false,
..Default::default()
};
eframe::run_native("My App", native_options, Box::new(|cc| Box::new(MyEguiApp::new(cc))));
}
impl eframe::App for MyEguiApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| ui.heading("Hello World!"));
}
fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) {
println!("On exit");
}
} I am using |
Is it also possible with eframe to |
The approach of emilk#1889 may remove the observer of a view twice, which produces the Obj-C Exception: Cannot remove an observer <...> for the key path "nextResponder" from <WinitView ...> because it is not registered as an observer. The above message can only be seen when attaching the application to debugger. Users normally see: [1] *** trace trap cargo run This commit fixes it by only running event_loop twice on Windows. Besides: * We have set ControlFlow::Exit on 'Event::LoopDestoryed', 'EventResult::Exit' and on error; therefore, it is safe to not calling `set_exit()`. * This commit also fix the persistence function in macOS. It can't store the content in Memory due to this exception. Fixed: emilk#2768 (eframe: "App quit unexpectedly" on macOS) Signed-off-by: pan93412 <[email protected]>
The approach of emilk#1889 may remove observers in a view twice, which produces the Obj-C Exception: Cannot remove an observer <...> for the key path "nextResponder" from <WinitView ...> because it is not registered as an observer. The above message can only be seen when attaching the application to debugger. Users normally see: [1] *** trace trap cargo run This commit fixes it by only running `event_loop.run_return()` twice on Windows. Besides: * We have set `ControlFlow::Exit` on `Event::LoopDestroyed`, `EventResult::Exit` and on error; therefore, it is safe to not calling `set_exit()`. * This commit also fix the persistence function in macOS. It can't store the content in Memory due to this exception. Fixed: emilk#2768 (eframe: "App quit unexpectedly" on macOS) Signed-off-by: pan93412 <[email protected]>
The approach of #1889 may remove observers in a view twice, which produces the Obj-C Exception: Cannot remove an observer <...> for the key path "nextResponder" from <WinitView ...> because it is not registered as an observer. The above message can only be seen when attaching the application to debugger. Users normally see: [1] *** trace trap cargo run This commit fixes it by only running `event_loop.run_return()` twice on Windows. Besides: * We have set `ControlFlow::Exit` on `Event::LoopDestroyed`, `EventResult::Exit` and on error; therefore, it is safe to not calling `set_exit()`. * This commit also fix the persistence function in macOS. It can't store the content in Memory due to this exception. Fixed: #2768 (eframe: "App quit unexpectedly" on macOS) Signed-off-by: pan93412 <[email protected]>
Is this a stable feature? because i seem to get an issue where the last frame sticks around and the main window becomes unresponsive. this is still true on windows in 0.27.2. for a mve https://stackoverflow.com/questions/78294791/egui-run-and-return-not-destroying-main-window |
I second this, circumvented this for now by grabbing it's hwnd via a receiver and using win32 DestroyWindow to close it https://github.com/couleur-tweak-tips/smoothie-rs/blob/main/src/main.rs#L124 |
Closes #1223
This adds
NativeOptions::run_and_return
with default valuetrue
.If
true
, execution will continue after the eframe window is closed. This is a new behavior introduced in this PR.If
false
, the app will close once the eframe window is closed. The is the old behavior.This is
true
by default, and thefalse
option is only there so we can revert if we find any bugs.When
true
,winit::platform::run_return::EventLoopExtRunReturn::run_return
is used. The winit docs warns of its usage, recommendingEventLoop::run
, but 🤷When
false
,winit::event_loop::EventLoop::run
is used.This is a really useful feature. You can now use
eframe
to quickly open up a window and show some data or options, and then continue your program after theeframe
window is closedMy previous attempt at this caused some problems, but my new attempt seems to be working much better, at least on my Mac.