eframe: rename quit/exit to "close" (#1943)

Since https://github.com/emilk/egui/pull/1919 we can continue
the application after closing the native window. It therefore makes
more sense to call `frame.close()` to close the native window,
instead of `frame.quit()`.
This commit is contained in:
Emil Ernerfeldt 2022-08-20 16:08:59 +02:00 committed by GitHub
parent 2453756782
commit 127931ba45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 41 deletions

View file

@ -24,6 +24,7 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C
* Fixed mouse cursor change on Linux ([#1747](https://github.com/emilk/egui/pull/1747)). * Fixed mouse cursor change on Linux ([#1747](https://github.com/emilk/egui/pull/1747)).
* Added `Frame::set_visible` ([#1808](https://github.com/emilk/egui/pull/1808)). * Added `Frame::set_visible` ([#1808](https://github.com/emilk/egui/pull/1808)).
* Added fullscreen support ([#1866](https://github.com/emilk/egui/pull/1866)). * Added fullscreen support ([#1866](https://github.com/emilk/egui/pull/1866)).
* `Frame::quit` has been renamed to `Frame::close` and `App::on_exit_event` is now `App::on_close_event` ([#1943](https://github.com/emilk/egui/pull/1943)).
#### Web: #### Web:
* Added ability to stop/re-run web app from JavaScript. ⚠️ You need to update your CSS with `html, body: { height: 100%; width: 100%; }` ([#1803](https://github.com/emilk/egui/pull/1650)). * Added ability to stop/re-run web app from JavaScript. ⚠️ You need to update your CSS with `html, body: { height: 100%; width: 100%; }` ([#1803](https://github.com/emilk/egui/pull/1650)).

View file

@ -67,21 +67,25 @@ pub trait App {
/// where `APPNAME` is what is given to `eframe::run_native`. /// where `APPNAME` is what is given to `eframe::run_native`.
fn save(&mut self, _storage: &mut dyn Storage) {} fn save(&mut self, _storage: &mut dyn Storage) {}
/// Called before an exit that can be aborted. /// Called when the user attempts to close the desktop window and/or quit the application.
/// By returning `false` the exit will be aborted. To continue the exit return `true`. ///
/// By returning `false` the closing will be aborted. To continue the closing return `true`.
/// ///
/// A scenario where this method will be run is after pressing the close button on a native /// A scenario where this method will be run is after pressing the close button on a native
/// window, which allows you to ask the user whether they want to do something before exiting. /// window, which allows you to ask the user whether they want to do something before exiting.
/// See the example at <https://github.com/emilk/egui/blob/master/examples/confirm_exit/> for practical usage. /// See the example at <https://github.com/emilk/egui/blob/master/examples/confirm_exit/> for practical usage.
/// ///
/// It will _not_ be called on the web or when the window is forcefully closed. /// It will _not_ be called on the web or when the window is forcefully closed.
fn on_exit_event(&mut self) -> bool { #[cfg(not(target_arch = "wasm32"))]
#[doc(alias = "exit")]
#[doc(alias = "quit")]
fn on_close_event(&mut self) -> bool {
true true
} }
/// Called once on shutdown, after [`Self::save`]. /// Called once on shutdown, after [`Self::save`].
/// ///
/// If you need to abort an exit use [`Self::on_exit_event`]. /// If you need to abort an exit use [`Self::on_close_event`].
/// ///
/// To get a [`glow`] context you need to compile with the `glow` feature flag, /// To get a [`glow`] context you need to compile with the `glow` feature flag,
/// and run eframe with the glow backend. /// and run eframe with the glow backend.
@ -90,7 +94,7 @@ pub trait App {
/// Called once on shutdown, after [`Self::save`]. /// Called once on shutdown, after [`Self::save`].
/// ///
/// If you need to abort an exit use [`Self::on_exit_event`]. /// If you need to abort an exit use [`Self::on_close_event`].
#[cfg(not(feature = "glow"))] #[cfg(not(feature = "glow"))]
fn on_exit(&mut self) {} fn on_exit(&mut self) {}
@ -571,11 +575,24 @@ impl Frame {
self.wgpu_render_state.as_ref() self.wgpu_render_state.as_ref()
} }
/// Signal the app to stop/exit/quit the app (only works for native apps, not web apps). /// Tell `eframe` to close the desktop window.
/// The framework will not quit immediately, but at the end of the this frame. ///
/// The window will not close immediately, but at the end of the this frame.
///
/// Calling this will likely result in the app quitting, unless
/// you have more code after the call to [`crate::run_native`].
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[doc(alias = "exit")]
#[doc(alias = "quit")]
pub fn close(&mut self) {
self.output.close = true;
}
/// Tell `eframe` to close the desktop window.
#[cfg(not(target_arch = "wasm32"))]
#[deprecated = "Renamed `close`"]
pub fn quit(&mut self) { pub fn quit(&mut self) {
self.output.quit = true; self.close();
} }
/// Set the desired inner size of the window (in egui points). /// Set the desired inner size of the window (in egui points).
@ -797,10 +814,9 @@ pub(crate) mod backend {
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
#[must_use] #[must_use]
pub struct AppOutput { pub struct AppOutput {
/// Set to `true` to stop the app. /// Set to `true` to close the native window (which often quits the app).
/// This does nothing for web apps.
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub quit: bool, pub close: bool,
/// Set to some size to resize the outer window (e.g. glium window) to this size. /// Set to some size to resize the outer window (e.g. glium window) to this size.
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]

View file

@ -115,7 +115,7 @@ pub fn handle_app_output(
app_output: epi::backend::AppOutput, app_output: epi::backend::AppOutput,
) { ) {
let epi::backend::AppOutput { let epi::backend::AppOutput {
quit: _, close: _,
window_size, window_size,
window_title, window_title,
decorated, decorated,
@ -183,8 +183,8 @@ pub struct EpiIntegration {
pub egui_ctx: egui::Context, pub egui_ctx: egui::Context,
pending_full_output: egui::FullOutput, pending_full_output: egui::FullOutput,
egui_winit: egui_winit::State, egui_winit: egui_winit::State,
/// When set, it is time to quit /// When set, it is time to close the native window.
quit: bool, close: bool,
can_drag_window: bool, can_drag_window: bool,
} }
@ -228,7 +228,7 @@ impl EpiIntegration {
egui_ctx, egui_ctx,
egui_winit, egui_winit,
pending_full_output: Default::default(), pending_full_output: Default::default(),
quit: false, close: false,
can_drag_window: false, can_drag_window: false,
} }
} }
@ -243,17 +243,17 @@ impl EpiIntegration {
self.egui_ctx.clear_animations(); self.egui_ctx.clear_animations();
} }
/// If `true`, it is time to shut down. /// If `true`, it is time to close the native window.
pub fn should_quit(&self) -> bool { pub fn should_close(&self) -> bool {
self.quit self.close
} }
pub fn on_event(&mut self, app: &mut dyn epi::App, event: &winit::event::WindowEvent<'_>) { pub fn on_event(&mut self, app: &mut dyn epi::App, event: &winit::event::WindowEvent<'_>) {
use winit::event::{ElementState, MouseButton, WindowEvent}; use winit::event::{ElementState, MouseButton, WindowEvent};
match event { match event {
WindowEvent::CloseRequested => self.quit = app.on_exit_event(), WindowEvent::CloseRequested => self.close = app.on_close_event(),
WindowEvent::Destroyed => self.quit = true, WindowEvent::Destroyed => self.close = true,
WindowEvent::MouseInput { WindowEvent::MouseInput {
button: MouseButton::Left, button: MouseButton::Left,
state: ElementState::Pressed, state: ElementState::Pressed,
@ -285,8 +285,8 @@ impl EpiIntegration {
let mut app_output = self.frame.take_app_output(); let mut app_output = self.frame.take_app_output();
app_output.drag_window &= self.can_drag_window; // Necessary on Windows; see https://github.com/emilk/egui/pull/1108 app_output.drag_window &= self.can_drag_window; // Necessary on Windows; see https://github.com/emilk/egui/pull/1108
self.can_drag_window = false; self.can_drag_window = false;
if app_output.quit { if app_output.close {
self.quit = app.on_exit_event(); self.close = app.on_close_event();
} }
handle_app_output(window, self.egui_ctx.pixels_per_point(), app_output); handle_app_output(window, self.egui_ctx.pixels_per_point(), app_output);
} }

View file

@ -373,7 +373,7 @@ mod glow_integration {
gl_window.swap_buffers().unwrap(); gl_window.swap_buffers().unwrap();
} }
let control_flow = if integration.should_quit() { let control_flow = if integration.should_close() {
EventResult::Exit EventResult::Exit
} else if repaint_after.is_zero() { } else if repaint_after.is_zero() {
EventResult::RepaintAsap EventResult::RepaintAsap
@ -426,7 +426,7 @@ mod glow_integration {
self.gl_window.resize(**new_inner_size); self.gl_window.resize(**new_inner_size);
} }
winit::event::WindowEvent::CloseRequested winit::event::WindowEvent::CloseRequested
if self.integration.should_quit() => if self.integration.should_close() =>
{ {
return EventResult::Exit return EventResult::Exit
} }
@ -435,7 +435,7 @@ mod glow_integration {
self.integration.on_event(self.app.as_mut(), &event); self.integration.on_event(self.app.as_mut(), &event);
if self.integration.should_quit() { if self.integration.should_close() {
EventResult::Exit EventResult::Exit
} else { } else {
// TODO(emilk): ask egui if the event warrants a repaint // TODO(emilk): ask egui if the event warrants a repaint
@ -624,7 +624,7 @@ mod wgpu_integration {
integration.post_rendering(app.as_mut(), window); integration.post_rendering(app.as_mut(), window);
let control_flow = if integration.should_quit() { let control_flow = if integration.should_close() {
EventResult::Exit EventResult::Exit
} else if repaint_after.is_zero() { } else if repaint_after.is_zero() {
EventResult::RepaintAsap EventResult::RepaintAsap
@ -690,7 +690,7 @@ mod wgpu_integration {
.on_window_resized(new_inner_size.width, new_inner_size.height); .on_window_resized(new_inner_size.width, new_inner_size.height);
} }
winit::event::WindowEvent::CloseRequested winit::event::WindowEvent::CloseRequested
if self.integration.should_quit() => if self.integration.should_close() =>
{ {
return EventResult::Exit return EventResult::Exit
} }
@ -698,7 +698,7 @@ mod wgpu_integration {
}; };
self.integration.on_event(self.app.as_mut(), &event); self.integration.on_event(self.app.as_mut(), &event);
if self.integration.should_quit() { if self.integration.should_close() {
EventResult::Exit EventResult::Exit
} else { } else {
// TODO(emilk): ask egui if the event warrants a repaint // TODO(emilk): ask egui if the event warrants a repaint

View file

@ -140,7 +140,7 @@ impl BackendPanel {
{ {
ui.separator(); ui.separator();
if ui.button("Quit").clicked() { if ui.button("Quit").clicked() {
frame.quit(); frame.close();
} }
} }
} }

View file

@ -13,14 +13,14 @@ fn main() {
#[derive(Default)] #[derive(Default)]
struct MyApp { struct MyApp {
can_exit: bool, allowed_to_close: bool,
is_exiting: bool, show_confirmation_dialog: bool,
} }
impl eframe::App for MyApp { impl eframe::App for MyApp {
fn on_exit_event(&mut self) -> bool { fn on_close_event(&mut self) -> bool {
self.is_exiting = true; self.show_confirmation_dialog = true;
self.can_exit self.allowed_to_close
} }
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
@ -28,19 +28,20 @@ impl eframe::App for MyApp {
ui.heading("Try to close the window"); ui.heading("Try to close the window");
}); });
if self.is_exiting { if self.show_confirmation_dialog {
// Show confirmation dialog:
egui::Window::new("Do you want to quit?") egui::Window::new("Do you want to quit?")
.collapsible(false) .collapsible(false)
.resizable(false) .resizable(false)
.show(ctx, |ui| { .show(ctx, |ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
if ui.button("Not yet").clicked() { if ui.button("Cancel").clicked() {
self.is_exiting = false; self.show_confirmation_dialog = false;
} }
if ui.button("Yes!").clicked() { if ui.button("Yes!").clicked() {
self.can_exit = true; self.allowed_to_close = true;
frame.quit(); frame.close();
} }
}); });
}); });

View file

@ -89,7 +89,7 @@ fn custon_window_frame(
Button::new(RichText::new("").size(height - 4.0)).frame(false), Button::new(RichText::new("").size(height - 4.0)).frame(false),
); );
if close_response.clicked() { if close_response.clicked() {
frame.quit(); frame.close();
} }
// Interact with the title bar (drag to move window): // Interact with the title bar (drag to move window):

View file

@ -46,7 +46,7 @@ impl eframe::App for MyApp {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
if ui.button("Close").clicked() { if ui.button("Close").clicked() {
eprintln!("Pressed Close button"); eprintln!("Pressed Close button");
frame.quit(); frame.close();
} }
}); });
} }