Add support for graceful exits in `Application`
- `Settings` now contains an `exit_on_close_request` field - `Application` has a new `should_exit` method
This commit is contained in:
parent
00de9d0c9b
commit
67db13ff7c
|
@ -92,10 +92,11 @@ where
|
||||||
application,
|
application,
|
||||||
compositor,
|
compositor,
|
||||||
renderer,
|
renderer,
|
||||||
context,
|
|
||||||
runtime,
|
runtime,
|
||||||
debug,
|
debug,
|
||||||
receiver,
|
receiver,
|
||||||
|
context,
|
||||||
|
settings.exit_on_close_request,
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut context = task::Context::from_waker(task::noop_waker_ref());
|
let mut context = task::Context::from_waker(task::noop_waker_ref());
|
||||||
|
@ -139,10 +140,11 @@ async fn run_instance<A, E, C>(
|
||||||
mut application: A,
|
mut application: A,
|
||||||
mut compositor: C,
|
mut compositor: C,
|
||||||
mut renderer: A::Renderer,
|
mut renderer: A::Renderer,
|
||||||
context: glutin::ContextWrapper<glutin::PossiblyCurrent, Window>,
|
|
||||||
mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,
|
mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,
|
||||||
mut debug: Debug,
|
mut debug: Debug,
|
||||||
mut receiver: mpsc::UnboundedReceiver<glutin::event::Event<'_, A::Message>>,
|
mut receiver: mpsc::UnboundedReceiver<glutin::event::Event<'_, A::Message>>,
|
||||||
|
context: glutin::ContextWrapper<glutin::PossiblyCurrent, Window>,
|
||||||
|
exit_on_close_request: bool,
|
||||||
) where
|
) where
|
||||||
A: Application + 'static,
|
A: Application + 'static,
|
||||||
E: Executor + 'static,
|
E: Executor + 'static,
|
||||||
|
@ -212,6 +214,8 @@ async fn run_instance<A, E, C>(
|
||||||
// Update window
|
// Update window
|
||||||
state.synchronize(&application, context.window());
|
state.synchronize(&application, context.window());
|
||||||
|
|
||||||
|
let should_exit = application.should_exit();
|
||||||
|
|
||||||
user_interface =
|
user_interface =
|
||||||
ManuallyDrop::new(application::build_user_interface(
|
ManuallyDrop::new(application::build_user_interface(
|
||||||
&mut application,
|
&mut application,
|
||||||
|
@ -220,6 +224,10 @@ async fn run_instance<A, E, C>(
|
||||||
state.logical_size(),
|
state.logical_size(),
|
||||||
&mut debug,
|
&mut debug,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if should_exit {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug.draw_started();
|
debug.draw_started();
|
||||||
|
@ -290,6 +298,7 @@ async fn run_instance<A, E, C>(
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if application::requests_exit(&window_event, state.modifiers())
|
if application::requests_exit(&window_event, state.modifiers())
|
||||||
|
&& exit_on_close_request
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,13 @@ pub trait Application: Sized {
|
||||||
1.0
|
1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether the [`Application`] should be terminated.
|
||||||
|
///
|
||||||
|
/// By default, it returns `false`.
|
||||||
|
fn should_exit(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs the [`Application`].
|
/// Runs the [`Application`].
|
||||||
///
|
///
|
||||||
/// On native platforms, this method will take control of the current thread
|
/// On native platforms, this method will take control of the current thread
|
||||||
|
@ -284,6 +291,10 @@ where
|
||||||
fn scale_factor(&self) -> f64 {
|
fn scale_factor(&self) -> f64 {
|
||||||
self.0.scale_factor()
|
self.0.scale_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn should_exit(&self) -> bool {
|
||||||
|
self.0.should_exit()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
|
|
@ -25,6 +25,10 @@ pub struct Settings<Flags> {
|
||||||
/// The default value is 20.
|
/// The default value is 20.
|
||||||
pub default_text_size: u16,
|
pub default_text_size: u16,
|
||||||
|
|
||||||
|
/// Whether the [`Application`] should exit when the user requests the
|
||||||
|
/// window to close (e.g. the user presses the close button).
|
||||||
|
pub exit_on_close_request: bool,
|
||||||
|
|
||||||
/// If set to true, the renderer will try to perform antialiasing for some
|
/// If set to true, the renderer will try to perform antialiasing for some
|
||||||
/// primitives.
|
/// primitives.
|
||||||
///
|
///
|
||||||
|
@ -46,10 +50,11 @@ impl<Flags> Settings<Flags> {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
flags,
|
flags,
|
||||||
antialiasing: default_settings.antialiasing,
|
window: default_settings.window,
|
||||||
default_font: default_settings.default_font,
|
default_font: default_settings.default_font,
|
||||||
default_text_size: default_settings.default_text_size,
|
default_text_size: default_settings.default_text_size,
|
||||||
window: default_settings.window,
|
exit_on_close_request: default_settings.exit_on_close_request,
|
||||||
|
antialiasing: default_settings.antialiasing,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,10 +66,11 @@ where
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
antialiasing: Default::default(),
|
window: Default::default(),
|
||||||
default_font: Default::default(),
|
default_font: Default::default(),
|
||||||
default_text_size: 20,
|
default_text_size: 20,
|
||||||
window: Default::default(),
|
exit_on_close_request: true,
|
||||||
|
antialiasing: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +81,7 @@ impl<Flags> From<Settings<Flags>> for iced_winit::Settings<Flags> {
|
||||||
iced_winit::Settings {
|
iced_winit::Settings {
|
||||||
window: settings.window.into(),
|
window: settings.window.into(),
|
||||||
flags: settings.flags,
|
flags: settings.flags,
|
||||||
|
exit_on_close_request: settings.exit_on_close_request,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,13 @@ pub trait Application: Program<Clipboard = Clipboard> {
|
||||||
fn scale_factor(&self) -> f64 {
|
fn scale_factor(&self) -> f64 {
|
||||||
1.0
|
1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether the [`Application`] should be terminated.
|
||||||
|
///
|
||||||
|
/// By default, it returns `false`.
|
||||||
|
fn should_exit(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs an [`Application`] with an executor, compositor, and the provided
|
/// Runs an [`Application`] with an executor, compositor, and the provided
|
||||||
|
@ -149,10 +156,11 @@ where
|
||||||
application,
|
application,
|
||||||
compositor,
|
compositor,
|
||||||
renderer,
|
renderer,
|
||||||
window,
|
|
||||||
runtime,
|
runtime,
|
||||||
debug,
|
debug,
|
||||||
receiver,
|
receiver,
|
||||||
|
window,
|
||||||
|
settings.exit_on_close_request,
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut context = task::Context::from_waker(task::noop_waker_ref());
|
let mut context = task::Context::from_waker(task::noop_waker_ref());
|
||||||
|
@ -196,10 +204,11 @@ async fn run_instance<A, E, C>(
|
||||||
mut application: A,
|
mut application: A,
|
||||||
mut compositor: C,
|
mut compositor: C,
|
||||||
mut renderer: A::Renderer,
|
mut renderer: A::Renderer,
|
||||||
window: winit::window::Window,
|
|
||||||
mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,
|
mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,
|
||||||
mut debug: Debug,
|
mut debug: Debug,
|
||||||
mut receiver: mpsc::UnboundedReceiver<winit::event::Event<'_, A::Message>>,
|
mut receiver: mpsc::UnboundedReceiver<winit::event::Event<'_, A::Message>>,
|
||||||
|
window: winit::window::Window,
|
||||||
|
exit_on_close_request: bool,
|
||||||
) where
|
) where
|
||||||
A: Application + 'static,
|
A: Application + 'static,
|
||||||
E: Executor + 'static,
|
E: Executor + 'static,
|
||||||
|
@ -279,6 +288,8 @@ async fn run_instance<A, E, C>(
|
||||||
// Update window
|
// Update window
|
||||||
state.synchronize(&application, &window);
|
state.synchronize(&application, &window);
|
||||||
|
|
||||||
|
let should_exit = application.should_exit();
|
||||||
|
|
||||||
user_interface = ManuallyDrop::new(build_user_interface(
|
user_interface = ManuallyDrop::new(build_user_interface(
|
||||||
&mut application,
|
&mut application,
|
||||||
cache,
|
cache,
|
||||||
|
@ -286,6 +297,10 @@ async fn run_instance<A, E, C>(
|
||||||
state.logical_size(),
|
state.logical_size(),
|
||||||
&mut debug,
|
&mut debug,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if should_exit {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug.draw_started();
|
debug.draw_started();
|
||||||
|
@ -358,7 +373,9 @@ async fn run_instance<A, E, C>(
|
||||||
event: window_event,
|
event: window_event,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if requests_exit(&window_event, state.modifiers()) {
|
if requests_exit(&window_event, state.modifiers())
|
||||||
|
&& exit_on_close_request
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ pub struct Settings<Flags> {
|
||||||
///
|
///
|
||||||
/// [`Application`]: crate::Application
|
/// [`Application`]: crate::Application
|
||||||
pub flags: Flags,
|
pub flags: Flags,
|
||||||
|
|
||||||
|
/// Whether the [`Application`] should exit when the user requests the
|
||||||
|
/// window to close (e.g. the user presses the close button).
|
||||||
|
pub exit_on_close_request: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The window settings of an application.
|
/// The window settings of an application.
|
||||||
|
|
Loading…
Reference in New Issue