diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f5a13bc8..f16eca382b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ And please only add new entries to the top of this list, right below the `# Unre - **Breaking:** Replaced `EventLoopExtMacOS` with `EventLoopBuilderExtMacOS` (which also has renamed methods). - **Breaking:** Replaced `EventLoopExtWindows` with `EventLoopBuilderExtWindows` (which also has renamed methods). - **Breaking:** Replaced `EventLoopExtUnix` with `EventLoopBuilderExtUnix` (which also has renamed methods). +- Changed to Results instead of a panic for creating a new EventLoop # 0.26.1 (2022-01-05) diff --git a/examples/custom_events.rs b/examples/custom_events.rs index 8337ab4de8..b2e2a56265 100644 --- a/examples/custom_events.rs +++ b/examples/custom_events.rs @@ -13,7 +13,7 @@ fn main() { } SimpleLogger::new().init().unwrap(); - let event_loop = EventLoopBuilder::::with_user_event().build(); + let event_loop = EventLoopBuilder::::with_user_event().build().unwrap(); let _window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/src/error.rs b/src/error.rs index c039f3b868..8a7901e9e6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -80,3 +80,18 @@ impl fmt::Display for NotSupportedError { impl error::Error for OsError {} impl error::Error for ExternalError {} impl error::Error for NotSupportedError {} + +#[derive(Debug)] +pub enum CreationError { + EventLoop(String), + InitializeBackend(String), +} + +impl fmt::Display for CreationError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + CreationError::EventLoop(s) => f.write_str(s), + CreationError::InitializeBackend(s) => f.write_str(s), + } + } +} \ No newline at end of file diff --git a/src/event_loop.rs b/src/event_loop.rs index a86cfee1ac..2d9ab16e56 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -14,6 +14,7 @@ use std::marker::PhantomData; use std::ops::Deref; use std::{error, fmt}; +use crate::error::CreationError; 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 @@ -93,11 +94,14 @@ impl EventLoopBuilder { /// /// - **iOS:** Can only be called on the main thread. #[inline] - pub fn build(&mut self) -> EventLoop { - EventLoop { - event_loop: platform_impl::EventLoop::new(&self.platform_specific), + pub fn build(&mut self) -> Result, CreationError> { + Ok(EventLoop { + event_loop: match platform_impl::EventLoop::new(&self.platform_specific) { + Ok(event_loop) => event_loop, + Err(err) => return Err(err), + }, _marker: PhantomData, - } + }) } } @@ -175,17 +179,20 @@ impl Default for ControlFlow { } impl EventLoop<()> { - /// Alias for `EventLoopBuilder::new().build()`. + /// Alias for `EventLoopBuilder::new().build().unwrap()`. #[inline] pub fn new() -> EventLoop<()> { - EventLoopBuilder::new().build() + EventLoopBuilder::new().build().unwrap() } } impl EventLoop { #[deprecated = "Use `EventLoopBuilder::::with_user_event().build()` instead."] pub fn with_user_event() -> EventLoop { - EventLoopBuilder::::with_user_event().build() + match EventLoopBuilder::::with_user_event().build() { + Ok(event_loop) => event_loop, + Err(err) => panic!("Failed to create event loop: {}", err), + } } /// Hijacks the calling thread and initializes the winit event loop with the provided diff --git a/src/lib.rs b/src/lib.rs index 13b3c9ac3d..6565d1b217 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! //! ```no_run //! use winit::event_loop::EventLoop; -//! let event_loop = EventLoop::new(); +//! let event_loop = EventLoop::new().unwrap(); //! ``` //! //! Once this is done there are two ways to create a [`Window`]: @@ -48,7 +48,7 @@ //! window::WindowBuilder, //! }; //! -//! let event_loop = EventLoop::new(); +//! let event_loop = EventLoop::new().unwrap(); //! let window = WindowBuilder::new().build(&event_loop).unwrap(); //! //! event_loop.run(move |event, _, control_flow| { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 16f66e34b4..449ee708b8 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -25,7 +25,7 @@ pub use self::x11::XNotSupported; use self::x11::{ffi::XVisualInfo, util::WindowType as XWindowType, XConnection, XError}; use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, - error::{ExternalError, NotSupportedError, OsError as RootOsError}, + error::{ExternalError, NotSupportedError, OsError as RootOsError, CreationError}, event::Event, event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW}, icon::Icon, @@ -606,7 +606,7 @@ impl Clone for EventLoopProxy { } impl EventLoop { - pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self { + pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Result { if !attributes.any_thread && !is_main_thread() { panic!( "Initializing the event loop outside of the main thread is a significant \ @@ -619,13 +619,13 @@ impl EventLoop { #[cfg(feature = "x11")] if attributes.forced_backend == Some(Backend::X) { // TODO: Propagate - return EventLoop::new_x11_any_thread().unwrap(); + return Ok(EventLoop::new_x11_any_thread().unwrap()); } #[cfg(feature = "wayland")] if attributes.forced_backend == Some(Backend::Wayland) { // TODO: Propagate - return EventLoop::new_wayland_any_thread().expect("failed to open Wayland connection"); + return Ok(EventLoop::new_wayland_any_thread().expect("failed to open Wayland connection")); } if let Ok(env_var) = env::var(BACKEND_PREFERENCE_ENV_VAR) { @@ -633,18 +633,24 @@ impl EventLoop { "x11" => { // TODO: propagate #[cfg(feature = "x11")] - return EventLoop::new_x11_any_thread() - .expect("Failed to initialize X11 backend"); + return match EventLoop::new_x11_any_thread() { + Ok(event_loop) => Ok(event_loop), + Err(e) => Err(CreationError::InitializeBackend(format!("Failed to initialize X11 Backend: {}", e))), + }; + #[cfg(not(feature = "x11"))] - panic!("x11 feature is not enabled") + Err("x11 feature is not enabled") } "wayland" => { #[cfg(feature = "wayland")] - return EventLoop::new_wayland_any_thread() - .expect("Failed to initialize Wayland backend"); + return match EventLoop::new_wayland_any_thread() { + Ok(event_loop) => Ok(event_loop), + Err(e) => Err(CreationError::InitializeBackend(format!("Failed to initialize Wayland Backend: {}", e))), + }; #[cfg(not(feature = "wayland"))] - panic!("wayland feature is not enabled"); + Err("wayland feature is not enabled"); } + // I don't know what to convert this to for the Result, so I'll keep it for now _ => panic!( "Unknown environment variable value for {}, try one of `x11`,`wayland`", BACKEND_PREFERENCE_ENV_VAR, @@ -654,13 +660,13 @@ impl EventLoop { #[cfg(feature = "wayland")] let wayland_err = match EventLoop::new_wayland_any_thread() { - Ok(event_loop) => return event_loop, + Ok(event_loop) => return Ok(event_loop), Err(err) => err, }; #[cfg(feature = "x11")] let x11_err = match EventLoop::new_x11_any_thread() { - Ok(event_loop) => return event_loop, + Ok(event_loop) => return Ok(event_loop), Err(err) => err, };