From 7293fe0518d833a9e58af5f6ecfb78ed44ca0a76 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 11 Apr 2023 12:50:52 +0100 Subject: [PATCH] Re-work event loop run() API so it can return a Result This re-works the portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: #2709 By moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: #2709 --- examples/child_window.rs | 2 +- examples/control_flow.rs | 4 ++-- examples/cursor.rs | 4 ++-- examples/cursor_grab.rs | 4 ++-- examples/custom_events.rs | 4 ++-- examples/drag_window.rs | 4 ++-- examples/fullscreen.rs | 4 ++-- examples/handling_close.rs | 4 ++-- examples/ime.rs | 4 ++-- examples/key_binding.rs | 4 ++-- examples/mouse_wheel.rs | 4 ++-- examples/multithreaded.rs | 2 +- examples/multiwindow.rs | 2 +- examples/request_redraw.rs | 4 ++-- examples/request_redraw_threaded.rs | 4 ++-- examples/resizable.rs | 4 ++-- examples/theme.rs | 4 ++-- examples/timer.rs | 4 ++-- examples/touchpad_gestures.rs | 4 ++-- examples/transparent.rs | 4 ++-- examples/web.rs | 6 +++--- examples/web_aspect_ratio.rs | 2 +- examples/window.rs | 9 +++++--- examples/window_buttons.rs | 4 ++-- examples/window_debug.rs | 4 ++-- examples/window_drag_resize.rs | 4 ++-- examples/window_icon.rs | 4 ++-- examples/window_option_as_alt.rs | 4 ++-- examples/window_resize_increments.rs | 4 ++-- src/event_loop.rs | 21 ++++++++++++++----- src/platform_impl/android/mod.rs | 9 ++------ src/platform_impl/linux/mod.rs | 6 +++--- .../linux/wayland/event_loop/mod.rs | 12 ----------- src/platform_impl/linux/x11/mod.rs | 12 ----------- src/platform_impl/macos/event_loop.rs | 11 +++------- src/platform_impl/orbital/event_loop.rs | 9 ++++++-- src/platform_impl/windows/event_loop.rs | 9 ++------ 37 files changed, 92 insertions(+), 112 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index 775c180c684..755dec35b52 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -3,7 +3,7 @@ mod fill; #[cfg(any(x11_platform, macos_platform, windows_platform))] -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { use std::collections::HashMap; use raw_window_handle::HasRawWindowHandle; diff --git a/examples/control_flow.rs b/examples/control_flow.rs index fd39d4761b6..650436a2fdf 100644 --- a/examples/control_flow.rs +++ b/examples/control_flow.rs @@ -27,7 +27,7 @@ enum Mode { const WAIT_TIME: time::Duration = time::Duration::from_millis(100); const POLL_SLEEP_TIME: time::Duration = time::Duration::from_millis(100); -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); println!("Press '1' to switch to Wait mode."); @@ -122,5 +122,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/cursor.rs b/examples/cursor.rs index c9edf2a0cb4..b2836540405 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -10,7 +10,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -54,7 +54,7 @@ fn main() { } _ => (), } - }); + }) } const CURSORS: &[CursorIcon] = &[ diff --git a/examples/cursor_grab.rs b/examples/cursor_grab.rs index 72ba14e56c1..a3a66781abb 100644 --- a/examples/cursor_grab.rs +++ b/examples/cursor_grab.rs @@ -11,7 +11,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -73,5 +73,5 @@ fn main() { Event::RedrawRequested(_) => fill::fill_window(&window), _ => (), } - }); + }) } diff --git a/examples/custom_events.rs b/examples/custom_events.rs index b3a3d2176a3..e1ece1636bb 100644 --- a/examples/custom_events.rs +++ b/examples/custom_events.rs @@ -1,7 +1,7 @@ #![allow(clippy::single_match)] #[cfg(not(wasm_platform))] -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { use simple_logger::SimpleLogger; use winit::{ event::{Event, WindowEvent}, @@ -52,7 +52,7 @@ fn main() { } _ => (), } - }); + }) } #[cfg(wasm_platform)] diff --git a/examples/drag_window.rs b/examples/drag_window.rs index af5c824d439..a2c30379f70 100644 --- a/examples/drag_window.rs +++ b/examples/drag_window.rs @@ -11,7 +11,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -69,7 +69,7 @@ fn main() { } } _ => (), - }); + }) } fn name_windows(window_id: WindowId, switched: bool, window_1: &Window, window_2: &Window) { diff --git a/examples/fullscreen.rs b/examples/fullscreen.rs index e38390ebc89..740dc158db7 100644 --- a/examples/fullscreen.rs +++ b/examples/fullscreen.rs @@ -12,7 +12,7 @@ use winit::platform::macos::WindowExtMacOS; #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -131,5 +131,5 @@ fn main() { } _ => {} } - }); + }) } diff --git a/examples/handling_close.rs b/examples/handling_close.rs index c5d95471a68..3d1274272f2 100644 --- a/examples/handling_close.rs +++ b/examples/handling_close.rs @@ -11,7 +11,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -87,5 +87,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/ime.rs b/examples/ime.rs index d108c8fc6dc..5c6745a23f3 100644 --- a/examples/ime.rs +++ b/examples/ime.rs @@ -13,7 +13,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new() .with_level(LevelFilter::Trace) .init() @@ -105,5 +105,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/key_binding.rs b/examples/key_binding.rs index 7d4968f3a10..eae74fbdd00 100644 --- a/examples/key_binding.rs +++ b/examples/key_binding.rs @@ -17,7 +17,7 @@ fn main() { } #[cfg(any(target_os = "macos", target_os = "windows", target_os = "linux"))] -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { #[path = "util/fill.rs"] mod fill; @@ -61,5 +61,5 @@ fn main() { } _ => (), }; - }); + }) } diff --git a/examples/mouse_wheel.rs b/examples/mouse_wheel.rs index ea0c962bbec..84a79eb34b1 100644 --- a/examples/mouse_wheel.rs +++ b/examples/mouse_wheel.rs @@ -10,7 +10,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -64,5 +64,5 @@ In other words, the deltas indicate the direction in which to move the content ( } _ => (), } - }); + }) } diff --git a/examples/multithreaded.rs b/examples/multithreaded.rs index d1bff70f85c..61aaae1714f 100644 --- a/examples/multithreaded.rs +++ b/examples/multithreaded.rs @@ -1,7 +1,7 @@ #![allow(clippy::single_match)] #[cfg(not(wasm_platform))] -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { use std::{collections::HashMap, sync::mpsc, thread, time::Duration}; use simple_logger::SimpleLogger; diff --git a/examples/multiwindow.rs b/examples/multiwindow.rs index 03812afc6f3..b6677ae7fe6 100644 --- a/examples/multiwindow.rs +++ b/examples/multiwindow.rs @@ -13,7 +13,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); diff --git a/examples/request_redraw.rs b/examples/request_redraw.rs index 16ec6ca7c2b..ab4abec1c8c 100644 --- a/examples/request_redraw.rs +++ b/examples/request_redraw.rs @@ -10,7 +10,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -41,5 +41,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/request_redraw_threaded.rs b/examples/request_redraw_threaded.rs index afe874978a0..d055f59d546 100644 --- a/examples/request_redraw_threaded.rs +++ b/examples/request_redraw_threaded.rs @@ -1,7 +1,7 @@ #![allow(clippy::single_match)] #[cfg(not(wasm_platform))] -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { use std::{sync::Arc, thread, time}; use simple_logger::SimpleLogger; @@ -49,7 +49,7 @@ fn main() { } _ => (), } - }); + }) } #[cfg(wasm_platform)] diff --git a/examples/resizable.rs b/examples/resizable.rs index b0c0f6ea7df..ee74539a859 100644 --- a/examples/resizable.rs +++ b/examples/resizable.rs @@ -12,7 +12,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -53,5 +53,5 @@ fn main() { } _ => (), }; - }); + }) } diff --git a/examples/theme.rs b/examples/theme.rs index 7b132a9d83f..10d3397d775 100644 --- a/examples/theme.rs +++ b/examples/theme.rs @@ -11,7 +11,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -75,5 +75,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/timer.rs b/examples/timer.rs index 273cc638e11..c013f06bbed 100644 --- a/examples/timer.rs +++ b/examples/timer.rs @@ -16,7 +16,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -47,5 +47,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/touchpad_gestures.rs b/examples/touchpad_gestures.rs index 2ebe83623bf..15503a55bb9 100644 --- a/examples/touchpad_gestures.rs +++ b/examples/touchpad_gestures.rs @@ -8,7 +8,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -47,5 +47,5 @@ fn main() { } else if let Event::RedrawRequested(_) = event { fill::fill_window(&window); } - }); + }) } diff --git a/examples/transparent.rs b/examples/transparent.rs index 134be3adadc..8b40d5c813a 100644 --- a/examples/transparent.rs +++ b/examples/transparent.rs @@ -10,7 +10,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -36,5 +36,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/web.rs b/examples/web.rs index c1df6987737..4444f8cb601 100644 --- a/examples/web.rs +++ b/examples/web.rs @@ -7,7 +7,7 @@ use winit::{ window::{Fullscreen, WindowBuilder}, }; -pub fn main() { +pub fn main() -> std::result::Result<(), impl std::error::Error> { let event_loop = EventLoop::new(); let window = WindowBuilder::new() @@ -53,7 +53,7 @@ pub fn main() { } _ => (), } - }); + }) } #[cfg(wasm_platform)] @@ -66,7 +66,7 @@ mod wasm { console_log::init_with_level(log::Level::Debug).expect("error initializing logger"); #[allow(clippy::main_recursion)] - super::main(); + let _ = super::main(); } pub fn insert_canvas_and_create_log_list(window: &Window) -> web_sys::Element { diff --git a/examples/web_aspect_ratio.rs b/examples/web_aspect_ratio.rs index cd832af44b0..47fb45d7a76 100644 --- a/examples/web_aspect_ratio.rs +++ b/examples/web_aspect_ratio.rs @@ -45,7 +45,7 @@ This example demonstrates the desired future functionality which will possibly b // Render once with the size info we currently have render_circle(&canvas, window.inner_size()); - event_loop.run(move |event, _, control_flow| { + let _ = event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; match event { diff --git a/examples/window.rs b/examples/window.rs index 4a5d8b00682..d8f6a3ca065 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -10,7 +10,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -28,7 +28,10 @@ fn main() { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == window.id() => control_flow.set_exit(), + } if window_id == window.id() => { + log::warn!("Close button pressed"); + control_flow.set_exit() + } Event::MainEventsCleared => { window.request_redraw(); } @@ -37,5 +40,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/window_buttons.rs b/examples/window_buttons.rs index 1f28412c4c9..ce2301ddcc6 100644 --- a/examples/window_buttons.rs +++ b/examples/window_buttons.rs @@ -14,7 +14,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -71,5 +71,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/window_debug.rs b/examples/window_debug.rs index d1b3ba3d7ef..942246f22e4 100644 --- a/examples/window_debug.rs +++ b/examples/window_debug.rs @@ -14,7 +14,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -139,5 +139,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/examples/window_drag_resize.rs b/examples/window_drag_resize.rs index 84dae6e03b7..b2305bea21c 100644 --- a/examples/window_drag_resize.rs +++ b/examples/window_drag_resize.rs @@ -13,7 +13,7 @@ const BORDER: f64 = 8.0; #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -72,7 +72,7 @@ fn main() { fill::fill_window(&window); } _ => (), - }); + }) } fn cursor_direction_icon(resize_direction: Option) -> CursorIcon { diff --git a/examples/window_icon.rs b/examples/window_icon.rs index e87372c2082..2383ee7b68b 100644 --- a/examples/window_icon.rs +++ b/examples/window_icon.rs @@ -12,7 +12,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); // You'll have to choose an icon size at your own discretion. On X11, the desired size varies @@ -48,7 +48,7 @@ fn main() { } else if let Event::RedrawRequested(_) = event { fill::fill_window(&window); } - }); + }) } fn load_icon(path: &Path) -> Icon { diff --git a/examples/window_option_as_alt.rs b/examples/window_option_as_alt.rs index fc2e4582853..6d7792b540f 100644 --- a/examples/window_option_as_alt.rs +++ b/examples/window_option_as_alt.rs @@ -18,7 +18,7 @@ mod fill; /// Prints the keyboard events characters received when option_is_alt is true versus false. /// A left mouse click will toggle option_is_alt. #[cfg(target_os = "macos")] -fn main() { +fn main() -> Result<(), impl std::error::Error> { let event_loop = EventLoop::new(); let window = WindowBuilder::new() @@ -66,7 +66,7 @@ fn main() { } _ => (), } - }); + }) } #[cfg(not(target_os = "macos"))] diff --git a/examples/window_resize_increments.rs b/examples/window_resize_increments.rs index 1c713ba72c0..325c9b2497a 100644 --- a/examples/window_resize_increments.rs +++ b/examples/window_resize_increments.rs @@ -11,7 +11,7 @@ use winit::{ #[path = "util/fill.rs"] mod fill; -fn main() { +fn main() -> std::result::Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); let event_loop = EventLoop::new(); @@ -60,5 +60,5 @@ fn main() { } _ => (), } - }); + }) } diff --git a/src/event_loop.rs b/src/event_loop.rs index f16213689bc..459459333f8 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -18,6 +18,7 @@ use std::time::{Duration, Instant}; #[cfg(wasm_platform)] use web_time::{Duration, Instant}; +use crate::error::ExternalError; use crate::{event::Event, monitor::MonitorHandle, platform_impl}; /// Provides a way to retrieve events from the system and from the windows that were registered to @@ -278,23 +279,33 @@ impl EventLoop { EventLoopBuilder::::with_user_event().build() } - /// Hijacks the calling thread and initializes the winit event loop with the provided - /// closure. Since the closure is `'static`, it must be a `move` closure if it needs to + /// Runs the event loop in the calling thread and calls the given `event_handler` closure + /// to dispatch any window system events. + /// + /// Since the closure is `'static`, it must be a `move` closure if it needs to /// access any data from the calling context. /// /// See the [`ControlFlow`] docs for information on how changes to `&mut ControlFlow` impact the /// event loop's behavior. /// - /// Any values not passed to this function will *not* be dropped. - /// /// ## Platform-specific /// /// - **X11 / Wayland:** The program terminates with exit code 1 if the display server /// disconnects. + /// - **iOS:** Will never return to the caller and so values not passed to this function will + /// *not* be dropped before the process exits. + /// - **Web:** Will _act_ as if it never returns to the caller by throwing a Javascript exception + /// (that Rust doesn't see) that will also mean that any values not passed to this function + /// will *not* be dropped. + /// + /// Web applications are recommended to use `spawn()` instead of `run()` to avoid the need + /// for the Javascript exception trick, and to make it clearer that the event loop runs + /// asynchronously (via the browser's own, internal, event loop) and doesn't block the + /// current thread of execution like it does on other platforms. /// /// [`ControlFlow`]: crate::event_loop::ControlFlow #[inline] - pub fn run(self, event_handler: F) -> ! + pub fn run(self, event_handler: F) -> Result<(), ExternalError> where F: 'static + FnMut(Event<'_, T>, &EventLoopWindowTarget, &mut ControlFlow), { diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 3e742afdbf2..7080c83f84c 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -525,17 +525,12 @@ impl EventLoop { self.pending_redraw = pending_redraw; } - pub fn run(mut self, event_handler: F) -> ! + pub fn run(mut self, event_handler: F) -> Result<(), ExternalError> where F: 'static + FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget, &mut ControlFlow), { - let exit_code = match self.run_ondemand(event_handler) { - Err(ExternalError::ExitFailure(code)) => code, - Err(_err) => 1, - Ok(_) => 0, - }; - ::std::process::exit(exit_code); + self.run_ondemand(event_handler) } pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), ExternalError> diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index ea314fa2799..bc59e988517 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -817,11 +817,11 @@ impl EventLoop { x11_or_wayland!(match self; EventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy) } - pub fn run(self, callback: F) -> ! + pub fn run(mut self, callback: F) -> Result<(), ExternalError> where - F: 'static + FnMut(crate::event::Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(crate::event::Event<'_, T>, &RootELW, &mut ControlFlow), { - x11_or_wayland!(match self; EventLoop(evlp) => evlp.run(callback)) + self.run_ondemand(callback) } pub fn run_ondemand(&mut self, callback: F) -> Result<(), ExternalError> diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index ee01a4db4b4..e56539a3675 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -147,18 +147,6 @@ impl EventLoop { Ok(event_loop) } - pub fn run(mut self, callback: F) -> ! - where - F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow) + 'static, - { - let exit_code = match self.run_ondemand(callback) { - Err(ExternalError::ExitFailure(code)) => code, - Err(_err) => 1, - Ok(_) => 0, - }; - ::std::process::exit(exit_code) - } - pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), ExternalError> where F: FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget, &mut ControlFlow), diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 99dd64102ad..2564ce2e27d 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -365,18 +365,6 @@ impl EventLoop { &self.target } - pub fn run(mut self, callback: F) -> ! - where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow) + 'static, - { - let exit_code = match self.run_ondemand(callback) { - Err(ExternalError::ExitFailure(code)) => code, - Err(_err) => 1, - Ok(_) => 0, - }; - ::std::process::exit(exit_code) - } - pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), ExternalError> where F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index b7fbf41926f..e089af035db 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -6,7 +6,7 @@ use std::{ mem, os::raw::c_void, panic::{catch_unwind, resume_unwind, AssertUnwindSafe, RefUnwindSafe, UnwindSafe}, - process, ptr, + ptr, rc::{Rc, Weak}, sync::mpsc, }; @@ -184,16 +184,11 @@ impl EventLoop { &self.window_target } - pub fn run(mut self, callback: F) -> ! + pub fn run(mut self, callback: F) -> Result<(), ExternalError> where F: 'static + FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow), { - let exit_code = match self.run_ondemand(callback) { - Err(ExternalError::ExitFailure(code)) => code, - Err(_err) => 1, - Ok(_) => 0, - }; - process::exit(exit_code); + self.run_ondemand(callback) } // NB: we don't base this on `pump_events` because for `MacOs` we can't support diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index 0b23e5d5bb3..26d34cbbefa 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -12,6 +12,7 @@ use orbclient::{ use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle}; use crate::{ + error::ExternalError, event::{self, Ime, Modifiers, StartCause}, event_loop::{self, ControlFlow}, keyboard::{ @@ -442,7 +443,7 @@ impl EventLoop { } } - pub fn run(mut self, event_handler: F) -> ! + pub fn run(mut self, mut event_handler_inner: F) -> Result<(), ExternalError> where F: 'static + FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget, &mut ControlFlow), @@ -688,7 +689,11 @@ impl EventLoop { &mut control_flow, ); - ::std::process::exit(code); + if code == 0 { + Ok(()) + } else { + Err(ExternalError::ExitFailure(code)) + } } pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget { diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 52831d9b967..c84b7824cc9 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -245,16 +245,11 @@ impl EventLoop { &self.window_target } - pub fn run(mut self, event_handler: F) -> ! + pub fn run(mut self, event_handler: F) -> Result<(), ExternalError> where F: 'static + FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), { - let exit_code = match self.run_ondemand(event_handler) { - Err(ExternalError::ExitFailure(code)) => code, - Err(_err) => 1, - Ok(_) => 0, - }; - ::std::process::exit(exit_code); + self.run_ondemand(event_handler) } pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), ExternalError>