diff --git a/CHANGELOG.md b/CHANGELOG.md index 07240dff..ae43fda9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,6 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased -- **Breaking:** `EventLoop::new` and `EventLoopBuilder::build` now return `Result` - **Breaking:** on Wayland, dispatching user created wayland queue won't wake up the loop unless winit has event to send back. - Removed platform-specific extensions that should be retrieved through `raw-window-handle` trait implementations instead: - `platform::windows::HINSTANCE`. @@ -51,7 +50,7 @@ And please only add new entries to the top of this list, right below the `# Unre - On Web, remove unnecessary `Window::is_dark_mode()`, which was replaced with `Window::theme()`. - On Web, add `WindowBuilderExtWebSys::with_append()` to append the canvas element to the web page on creation. - On Windows, add `drag_resize_window` method support. -- **Breaking** `run() ->!` has been replaced by `run() -> Result<(), EventLoopError>` for returning errors without calling `std::process::exit()` ([#2767](https://github.com/rust-windowing/winit/pull/2767)) +- **Breaking** `run() ->!` has been replaced by `run() -> Result<(), RunLoopError>` for returning errors without calling `std::process::exit()` ([#2767](https://github.com/rust-windowing/winit/pull/2767)) - **Breaking** Removed `EventLoopExtRunReturn` / `run_return` in favor of `EventLoopExtPumpEvents` / `pump_events` and `EventLoopExtRunOnDemand` / `run_ondemand` ([#2767](https://github.com/rust-windowing/winit/pull/2767)) - `RedrawRequested` is no longer guaranteed to be emitted after `MainEventsCleared`, it is now platform-specific when the event is emitted after being requested via `redraw_request()`. - On Windows, `RedrawRequested` is now driven by `WM_PAINT` messages which are requested via `redraw_request()` diff --git a/examples/child_window.rs b/examples/child_window.rs index ef28757d..9d3bc053 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -36,7 +36,7 @@ fn main() -> Result<(), impl std::error::Error> { let mut windows = HashMap::new(); - let event_loop: EventLoop<()> = EventLoop::new().unwrap(); + let event_loop: EventLoop<()> = EventLoop::new(); let parent_window = WindowBuilder::new() .with_title("parent window") .with_position(Position::Logical(LogicalPosition::new(0.0, 0.0))) diff --git a/examples/control_flow.rs b/examples/control_flow.rs index 8ed24f4f..cde56265 100644 --- a/examples/control_flow.rs +++ b/examples/control_flow.rs @@ -36,7 +36,7 @@ fn main() -> Result<(), impl std::error::Error> { println!("Press 'R' to toggle request_redraw() calls."); println!("Press 'Esc' to close the window."); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.") .build(&event_loop) diff --git a/examples/cursor.rs b/examples/cursor.rs index bba0d012..e7d3b9d5 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -12,7 +12,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); window.set_title("A fantastic window!"); diff --git a/examples/cursor_grab.rs b/examples/cursor_grab.rs index 99a42825..b69ab47c 100644 --- a/examples/cursor_grab.rs +++ b/examples/cursor_grab.rs @@ -13,7 +13,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("Super Cursor Grab'n'Hide Simulator 9000") diff --git a/examples/custom_events.rs b/examples/custom_events.rs index ecadebf5..2e8f5472 100644 --- a/examples/custom_events.rs +++ b/examples/custom_events.rs @@ -18,9 +18,7 @@ fn main() -> Result<(), impl std::error::Error> { } SimpleLogger::new().init().unwrap(); - let event_loop = EventLoopBuilder::::with_user_event() - .build() - .unwrap(); + let event_loop = EventLoopBuilder::::with_user_event().build(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/drag_window.rs b/examples/drag_window.rs index 97ed5c8d..55056001 100644 --- a/examples/drag_window.rs +++ b/examples/drag_window.rs @@ -13,7 +13,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window_1 = WindowBuilder::new().build(&event_loop).unwrap(); let window_2 = WindowBuilder::new().build(&event_loop).unwrap(); diff --git a/examples/fullscreen.rs b/examples/fullscreen.rs index 4ff40885..675ad8ff 100644 --- a/examples/fullscreen.rs +++ b/examples/fullscreen.rs @@ -15,7 +15,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let mut decorations = true; let mut minimized = false; diff --git a/examples/handling_close.rs b/examples/handling_close.rs index 578e9539..5fa90283 100644 --- a/examples/handling_close.rs +++ b/examples/handling_close.rs @@ -13,7 +13,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("Your faithful window") diff --git a/examples/ime.rs b/examples/ime.rs index fe33fa6c..319e0615 100644 --- a/examples/ime.rs +++ b/examples/ime.rs @@ -24,7 +24,7 @@ fn main() -> Result<(), impl std::error::Error> { println!("Press F2 to toggle IME. See the documentation of `set_ime_allowed` for more info"); println!("Press F3 to cycle through IME purposes."); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_inner_size(winit::dpi::LogicalSize::new(256f64, 128f64)) diff --git a/examples/key_binding.rs b/examples/key_binding.rs index 5f438a0e..ef5d5319 100644 --- a/examples/key_binding.rs +++ b/examples/key_binding.rs @@ -22,7 +22,7 @@ fn main() -> Result<(), impl std::error::Error> { mod fill; simple_logger::SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_inner_size(LogicalSize::new(400.0, 200.0)) diff --git a/examples/monitor_list.rs b/examples/monitor_list.rs index b156028d..23081b63 100644 --- a/examples/monitor_list.rs +++ b/examples/monitor_list.rs @@ -7,7 +7,7 @@ use winit::{event_loop::EventLoop, window::WindowBuilder}; fn main() { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); if let Some(mon) = window.primary_monitor() { diff --git a/examples/mouse_wheel.rs b/examples/mouse_wheel.rs index 9c32aa35..38d06aff 100644 --- a/examples/mouse_wheel.rs +++ b/examples/mouse_wheel.rs @@ -12,7 +12,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("Mouse Wheel events") diff --git a/examples/multithreaded.rs b/examples/multithreaded.rs index 290cb51a..c1557821 100644 --- a/examples/multithreaded.rs +++ b/examples/multithreaded.rs @@ -17,7 +17,7 @@ fn main() -> Result<(), impl std::error::Error> { const WINDOW_SIZE: PhysicalSize = PhysicalSize::new(600, 400); SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let mut window_senders = HashMap::with_capacity(WINDOW_COUNT); for _ in 0..WINDOW_COUNT { let window = WindowBuilder::new() diff --git a/examples/multiwindow.rs b/examples/multiwindow.rs index b4e82cdc..7fcb724b 100644 --- a/examples/multiwindow.rs +++ b/examples/multiwindow.rs @@ -15,7 +15,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let mut windows = HashMap::new(); for _ in 0..3 { diff --git a/examples/request_redraw.rs b/examples/request_redraw.rs index fe3810e6..a064cd39 100644 --- a/examples/request_redraw.rs +++ b/examples/request_redraw.rs @@ -12,7 +12,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/request_redraw_threaded.rs b/examples/request_redraw_threaded.rs index 173b399f..2010f96e 100644 --- a/examples/request_redraw_threaded.rs +++ b/examples/request_redraw_threaded.rs @@ -15,7 +15,7 @@ fn main() -> Result<(), impl std::error::Error> { mod fill; SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = { let window = WindowBuilder::new() diff --git a/examples/resizable.rs b/examples/resizable.rs index c6d0d095..ecec14b2 100644 --- a/examples/resizable.rs +++ b/examples/resizable.rs @@ -14,7 +14,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let mut resizable = false; diff --git a/examples/startup_notification.rs b/examples/startup_notification.rs index 5b684b87..fdd68d51 100644 --- a/examples/startup_notification.rs +++ b/examples/startup_notification.rs @@ -19,7 +19,7 @@ mod example { pub(super) fn main() -> Result<(), impl std::error::Error> { // Create the event loop and get the activation token. - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let mut current_token = match event_loop.read_token_from_env() { Some(token) => Some(token), None => { diff --git a/examples/theme.rs b/examples/theme.rs index 485d2481..b3dac443 100644 --- a/examples/theme.rs +++ b/examples/theme.rs @@ -13,7 +13,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/timer.rs b/examples/timer.rs index 329c36b8..13fceb51 100644 --- a/examples/timer.rs +++ b/examples/timer.rs @@ -18,7 +18,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/touchpad_gestures.rs b/examples/touchpad_gestures.rs index 44f2eee1..0cca2c2c 100644 --- a/examples/touchpad_gestures.rs +++ b/examples/touchpad_gestures.rs @@ -10,7 +10,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("Touchpad gestures") diff --git a/examples/transparent.rs b/examples/transparent.rs index 9d3a470a..b093867d 100644 --- a/examples/transparent.rs +++ b/examples/transparent.rs @@ -12,7 +12,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_decorations(false) diff --git a/examples/video_modes.rs b/examples/video_modes.rs index 75acdbd4..3b262c7b 100644 --- a/examples/video_modes.rs +++ b/examples/video_modes.rs @@ -5,7 +5,7 @@ use winit::event_loop::EventLoop; fn main() { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let monitor = match event_loop.primary_monitor() { Some(monitor) => monitor, None => { diff --git a/examples/web.rs b/examples/web.rs index b8ba1671..f8237a7b 100644 --- a/examples/web.rs +++ b/examples/web.rs @@ -8,7 +8,7 @@ use winit::{ }; pub fn main() -> Result<(), impl std::error::Error> { - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let builder = WindowBuilder::new().with_title("A fantastic window!"); #[cfg(wasm_platform)] diff --git a/examples/web_aspect_ratio.rs b/examples/web_aspect_ratio.rs index 2b19f776..e0f5ba16 100644 --- a/examples/web_aspect_ratio.rs +++ b/examples/web_aspect_ratio.rs @@ -31,7 +31,7 @@ This example demonstrates the desired future functionality which will possibly b #[wasm_bindgen(start)] pub fn run() { console_log::init_with_level(log::Level::Debug).expect("error initializing logger"); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/window.rs b/examples/window.rs index 21be03f0..0c2729ec 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -12,7 +12,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/window_buttons.rs b/examples/window_buttons.rs index c7f04a34..b531531c 100644 --- a/examples/window_buttons.rs +++ b/examples/window_buttons.rs @@ -16,7 +16,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/window_debug.rs b/examples/window_debug.rs index e7283942..5c7f2326 100644 --- a/examples/window_debug.rs +++ b/examples/window_debug.rs @@ -16,7 +16,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/window_drag_resize.rs b/examples/window_drag_resize.rs index 73908cac..3232c4c8 100644 --- a/examples/window_drag_resize.rs +++ b/examples/window_drag_resize.rs @@ -15,7 +15,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_inner_size(winit::dpi::LogicalSize::new(600.0, 400.0)) diff --git a/examples/window_icon.rs b/examples/window_icon.rs index 1811812e..6e65f348 100644 --- a/examples/window_icon.rs +++ b/examples/window_icon.rs @@ -23,7 +23,7 @@ fn main() -> Result<(), impl std::error::Error> { let icon = load_icon(Path::new(path)); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("An iconic window!") diff --git a/examples/window_ondemand.rs b/examples/window_ondemand.rs index faa63e17..0a59f4fc 100644 --- a/examples/window_ondemand.rs +++ b/examples/window_ondemand.rs @@ -8,7 +8,7 @@ fn main() -> Result<(), impl std::error::Error> { use simple_logger::SimpleLogger; use winit::{ - error::EventLoopError, + error::RunLoopError, event::{Event, WindowEvent}, event_loop::EventLoop, platform::run_ondemand::EventLoopExtRunOnDemand, @@ -25,9 +25,9 @@ fn main() -> Result<(), impl std::error::Error> { } SimpleLogger::new().init().unwrap(); - let mut event_loop = EventLoop::new().unwrap(); + let mut event_loop = EventLoop::new(); - fn run_app(event_loop: &mut EventLoop<()>, idx: usize) -> Result<(), EventLoopError> { + fn run_app(event_loop: &mut EventLoop<()>, idx: usize) -> Result<(), RunLoopError> { let mut app = App::default(); event_loop.run_ondemand(move |event, event_loop, control_flow| { diff --git a/examples/window_option_as_alt.rs b/examples/window_option_as_alt.rs index a28374be..60c6fce3 100644 --- a/examples/window_option_as_alt.rs +++ b/examples/window_option_as_alt.rs @@ -19,7 +19,7 @@ mod fill; /// A left mouse click will toggle option_is_alt. #[cfg(target_os = "macos")] fn main() -> Result<(), impl std::error::Error> { - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/window_pump_events.rs b/examples/window_pump_events.rs index 0317981a..2de01bc8 100644 --- a/examples/window_pump_events.rs +++ b/examples/window_pump_events.rs @@ -22,7 +22,7 @@ fn main() -> std::process::ExitCode { #[path = "util/fill.rs"] mod fill; - let mut event_loop = EventLoop::new().unwrap(); + let mut event_loop = EventLoop::new(); SimpleLogger::new().init().unwrap(); let window = WindowBuilder::new() diff --git a/examples/window_resize_increments.rs b/examples/window_resize_increments.rs index 6b04072d..0fcf4b9c 100644 --- a/examples/window_resize_increments.rs +++ b/examples/window_resize_increments.rs @@ -13,7 +13,7 @@ mod fill; fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_title("A fantastic window!") diff --git a/examples/window_tabbing.rs b/examples/window_tabbing.rs index 732a5b62..1989a8f3 100644 --- a/examples/window_tabbing.rs +++ b/examples/window_tabbing.rs @@ -21,7 +21,7 @@ mod fill; #[cfg(target_os = "macos")] fn main() -> Result<(), impl std::error::Error> { SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); + let event_loop = EventLoop::new(); let mut windows = HashMap::new(); let window = Window::new(&event_loop).unwrap(); diff --git a/src/error.rs b/src/error.rs index 0f04e9bf..42a3f43c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -30,7 +30,7 @@ pub struct OsError { /// A general error that may occur while running the Winit event loop #[derive(Debug)] -pub enum EventLoopError { +pub enum RunLoopError { /// The operation is not supported by the backend. NotSupported(NotSupportedError), /// The OS cannot perform the operation. @@ -41,12 +41,6 @@ pub enum EventLoopError { ExitFailure(i32), } -impl From for EventLoopError { - fn from(value: OsError) -> Self { - Self::Os(value) - } -} - impl NotSupportedError { #[inline] #[allow(dead_code)] @@ -100,13 +94,13 @@ impl fmt::Display for NotSupportedError { } } -impl fmt::Display for EventLoopError { +impl fmt::Display for RunLoopError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match self { - EventLoopError::AlreadyRunning => write!(f, "EventLoop is already running"), - EventLoopError::NotSupported(e) => e.fmt(f), - EventLoopError::Os(e) => e.fmt(f), - EventLoopError::ExitFailure(status) => write!(f, "Exit Failure: {status}"), + RunLoopError::AlreadyRunning => write!(f, "EventLoop is already running"), + RunLoopError::NotSupported(e) => e.fmt(f), + RunLoopError::Os(e) => e.fmt(f), + RunLoopError::ExitFailure(status) => write!(f, "Exit Failure: {status}"), } } } @@ -114,7 +108,7 @@ impl fmt::Display for EventLoopError { impl error::Error for OsError {} impl error::Error for ExternalError {} impl error::Error for NotSupportedError {} -impl error::Error for EventLoopError {} +impl error::Error for RunLoopError {} #[cfg(test)] mod tests { diff --git a/src/event_loop.rs b/src/event_loop.rs index 96fd9f0a..0986b3aa 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -18,7 +18,7 @@ use std::time::{Duration, Instant}; #[cfg(wasm_platform)] use web_time::{Duration, Instant}; -use crate::error::EventLoopError; +use crate::error::RunLoopError; 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 @@ -88,18 +88,21 @@ impl EventLoopBuilder { /// ***For cross-platform compatibility, the [`EventLoop`] must be created on the main thread, /// and only once per application.*** /// - /// Attempting to create the event loop on a different thread, or multiple - /// event loops in the same application, will panic. This restriction - /// isn't strictly necessary on all platforms, but is imposed to eliminate - /// any nasty surprises when porting to platforms that require it. - /// `EventLoopBuilderExt::any_thread` functions are exposed in the relevant - /// [`platform`] module if the target platform supports creating an event - /// loop on any thread. + /// Attempting to create the event loop on a different thread, or multiple event loops in + /// the same application, will panic. This restriction isn't + /// strictly necessary on all platforms, but is imposed to eliminate any nasty surprises when + /// porting to platforms that require it. `EventLoopBuilderExt::any_thread` functions are exposed + /// in the relevant [`platform`] module if the target platform supports creating an event loop on + /// any thread. /// /// Calling this function will result in display backend initialisation. /// /// ## Platform-specific /// + /// - **Linux:** Backend type can be controlled using an environment variable + /// `WINIT_UNIX_BACKEND`. Legal values are `x11` and `wayland`. + /// If it is not set, winit will try to connect to a Wayland connection, and if that fails, + /// will fall back on X11. If this variable is set with any other value, winit will panic. /// - **Android:** Must be configured with an `AndroidApp` from `android_main()` by calling /// [`.with_android_app(app)`] before calling `.build()`. /// @@ -113,17 +116,17 @@ impl EventLoopBuilder { doc = "[`.with_android_app(app)`]: #only-available-on-android" )] #[inline] - pub fn build(&mut self) -> Result, EventLoopError> { + pub fn build(&mut self) -> EventLoop { if EVENT_LOOP_CREATED.swap(true, Ordering::Relaxed) { - return Err(EventLoopError::AlreadyRunning); + panic!("Creating EventLoop multiple times is not supported."); } // Certain platforms accept a mutable reference in their API. #[allow(clippy::unnecessary_mut_passed)] - Ok(EventLoop { - event_loop: platform_impl::EventLoop::new(&mut self.platform_specific)?, + EventLoop { + event_loop: platform_impl::EventLoop::new(&mut self.platform_specific), _marker: PhantomData, - }) + } } #[cfg(wasm_platform)] @@ -266,14 +269,20 @@ impl EventLoop<()> { /// /// [`EventLoopBuilder::new().build()`]: EventLoopBuilder::build #[inline] - pub fn new() -> Result, EventLoopError> { + pub fn new() -> EventLoop<()> { EventLoopBuilder::new().build() } } +impl Default for EventLoop<()> { + fn default() -> Self { + Self::new() + } +} + impl EventLoop { #[deprecated = "Use `EventLoopBuilder::::with_user_event().build()` instead."] - pub fn with_user_event() -> Result, EventLoopError> { + pub fn with_user_event() -> EventLoop { EventLoopBuilder::::with_user_event().build() } @@ -306,7 +315,7 @@ impl EventLoop { /// [`ControlFlow`]: crate::event_loop::ControlFlow #[inline] #[cfg(not(all(wasm_platform, target_feature = "exception-handling")))] - pub fn run(self, event_handler: F) -> Result<(), EventLoopError> + pub fn run(self, event_handler: F) -> Result<(), RunLoopError> where F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow), { diff --git a/src/lib.rs b/src/lib.rs index ae1281ce..c2e27acb 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().unwrap(); +//! let event_loop = EventLoop::new(); //! ``` //! //! Once this is done there are two ways to create a [`Window`]: @@ -48,7 +48,7 @@ //! window::WindowBuilder, //! }; //! -//! let event_loop = EventLoop::new().unwrap(); +//! let event_loop = EventLoop::new(); //! let window = WindowBuilder::new().build(&event_loop).unwrap(); //! //! event_loop.run(move |event, _, control_flow| { diff --git a/src/platform/pump_events.rs b/src/platform/pump_events.rs index fa970ca1..d9bdf8f4 100644 --- a/src/platform/pump_events.rs +++ b/src/platform/pump_events.rs @@ -53,7 +53,7 @@ pub trait EventLoopExtPumpEvents { /// # platform::pump_events::{EventLoopExtPumpEvents, PumpStatus}, /// # window::WindowBuilder, /// # }; - /// let mut event_loop = EventLoop::new().unwrap(); + /// let mut event_loop = EventLoop::new(); /// # /// # SimpleLogger::new().init().unwrap(); /// let window = WindowBuilder::new() diff --git a/src/platform/run_ondemand.rs b/src/platform/run_ondemand.rs index 031b670c..c1e36326 100644 --- a/src/platform/run_ondemand.rs +++ b/src/platform/run_ondemand.rs @@ -1,5 +1,5 @@ use crate::{ - error::EventLoopError, + error::RunLoopError, event::Event, event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget}, }; @@ -57,7 +57,7 @@ pub trait EventLoopExtRunOnDemand { /// polled to ask for new events. Events are delivered via callbacks based /// on an event loop that is internal to the browser itself. /// - **iOS:** It's not possible to stop and start an `NSApplication` repeatedly on iOS. - fn run_ondemand(&mut self, event_handler: F) -> Result<(), EventLoopError> + fn run_ondemand(&mut self, event_handler: F) -> Result<(), RunLoopError> where F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow); } @@ -65,7 +65,7 @@ pub trait EventLoopExtRunOnDemand { impl EventLoopExtRunOnDemand for EventLoop { type UserEvent = T; - fn run_ondemand(&mut self, event_handler: F) -> Result<(), EventLoopError> + fn run_ondemand(&mut self, event_handler: F) -> Result<(), RunLoopError> where F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow), { diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index c52c7f65..c40377be 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -30,7 +30,7 @@ use crate::{ self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel, }, }; -use crate::{error::EventLoopError, platform_impl::Fullscreen}; +use crate::{error::RunLoopError, platform_impl::Fullscreen}; mod keycodes; @@ -186,15 +186,13 @@ fn sticky_exit_callback( } impl EventLoop { - pub(crate) fn new( - attributes: &PlatformSpecificEventLoopAttributes, - ) -> Result { + pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self { let (user_events_sender, user_events_receiver) = mpsc::channel(); let android_app = attributes.android_app.as_ref().expect("An `AndroidApp` as passed to android_main() is required to create an `EventLoop` on Android"); let redraw_flag = SharedFlag::new(); - Ok(Self { + Self { android_app: android_app.clone(), window_target: event_loop::EventLoopWindowTarget { p: EventLoopWindowTarget { @@ -216,7 +214,7 @@ impl EventLoop { control_flow: Default::default(), cause: StartCause::Init, ignore_volume_keys: attributes.ignore_volume_keys, - }) + } } fn single_iteration(&mut self, main_event: Option>, callback: &mut F) @@ -526,19 +524,19 @@ impl EventLoop { self.pending_redraw = pending_redraw; } - pub fn run(mut self, event_handler: F) -> Result<(), EventLoopError> + pub fn run(mut self, event_handler: F) -> Result<(), RunLoopError> where F: FnMut(event::Event, &event_loop::EventLoopWindowTarget, &mut ControlFlow), { self.run_ondemand(event_handler) } - pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> + pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), RunLoopError> where F: FnMut(event::Event, &event_loop::EventLoopWindowTarget, &mut ControlFlow), { if self.loop_running { - return Err(EventLoopError::AlreadyRunning); + return Err(RunLoopError::AlreadyRunning); } loop { @@ -547,7 +545,7 @@ impl EventLoop { break Ok(()); } PumpStatus::Exit(code) => { - break Err(EventLoopError::ExitFailure(code)); + break Err(RunLoopError::ExitFailure(code)); } _ => { continue; diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index 88a08182..070f0cb3 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -19,9 +19,11 @@ use objc2::rc::Id; use objc2::ClassType; use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle}; +use super::uikit::{UIApplication, UIApplicationMain, UIDevice, UIScreen}; +use super::view::WinitUIWindow; +use super::{app_state, monitor, view, MonitorHandle}; use crate::{ dpi::LogicalSize, - error::EventLoopError, event::Event, event_loop::{ ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootEventLoopWindowTarget, @@ -29,10 +31,6 @@ use crate::{ platform::ios::Idiom, }; -use super::uikit::{UIApplication, UIApplicationMain, UIDevice, UIScreen}; -use super::view::WinitUIWindow; -use super::{app_state, monitor, view, MonitorHandle}; - #[derive(Debug)] pub(crate) enum EventWrapper { StaticEvent(Event), @@ -77,9 +75,7 @@ pub struct EventLoop { pub(crate) struct PlatformSpecificEventLoopAttributes {} impl EventLoop { - pub(crate) fn new( - _: &PlatformSpecificEventLoopAttributes, - ) -> Result, EventLoopError> { + pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> EventLoop { assert_main_thread!("`EventLoop` can only be created on the main thread on iOS"); static mut SINGLETON_INIT: bool = false; @@ -97,7 +93,7 @@ impl EventLoop { // this line sets up the main run loop before `UIApplicationMain` setup_control_flow_observers(); - Ok(EventLoop { + EventLoop { window_target: RootEventLoopWindowTarget { p: EventLoopWindowTarget { receiver, @@ -105,7 +101,7 @@ impl EventLoop { }, _marker: PhantomData, }, - }) + } } pub fn run(self, event_handler: F) -> ! diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 7d535f3b..dedc3c51 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -3,22 +3,33 @@ #[cfg(all(not(x11_platform), not(wayland_platform)))] compile_error!("Please select a feature to build for unix: `x11`, `wayland`"); -use std::sync::Arc; -use std::time::Duration; +#[cfg(wayland_platform)] +use std::error::Error; + use std::{collections::VecDeque, env, fmt}; #[cfg(x11_platform)] -use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Mutex}; +use std::{ + ffi::CStr, + mem::MaybeUninit, + os::raw::*, + sync::{Arc, Mutex}, +}; #[cfg(x11_platform)] use once_cell::sync::Lazy; use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; use smol_str::SmolStr; +use std::time::Duration; +#[cfg(x11_platform)] +pub use self::x11::XNotSupported; +#[cfg(x11_platform)] +use self::x11::{util::WindowType as XWindowType, X11Error, XConnection, XError}; #[cfg(x11_platform)] use crate::platform::x11::XlibErrorHook; use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, - error::{EventLoopError, ExternalError, NotSupportedError, OsError as RootOsError}, + error::{ExternalError, NotSupportedError, OsError as RootOsError, RunLoopError}, event::{Event, KeyEvent}, event_loop::{ AsyncRequestSerial, ControlFlow, DeviceEvents, EventLoopClosed, @@ -35,10 +46,6 @@ use crate::{ UserAttentionType, WindowAttributes, WindowButtons, WindowLevel, }, }; -#[cfg(x11_platform)] -pub use x11::XNotSupported; -#[cfg(x11_platform)] -use x11::{util::WindowType as XWindowType, X11Error, XConnection, XError}; pub(crate) use crate::icon::RgbaIcon as PlatformIcon; pub(crate) use crate::platform_impl::Fullscreen; @@ -49,6 +56,15 @@ pub mod wayland; #[cfg(x11_platform)] pub mod x11; +/// Environment variable specifying which backend should be used on unix platform. +/// +/// Legal values are x11 and wayland. If this variable is set only the named backend +/// will be tried by winit. If it is not set, winit will try to connect to a wayland connection, +/// and if it fails will fallback on x11. +/// +/// If this variable is set with any other value, winit will panic. +const BACKEND_PREFERENCE_ENV_VAR: &str = "WINIT_UNIX_BACKEND"; + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub(crate) enum Backend { #[cfg(x11_platform)] @@ -116,21 +132,23 @@ pub(crate) static X11_BACKEND: Lazy, XNotSupported #[derive(Debug, Clone)] pub enum OsError { - Misc(&'static str), #[cfg(x11_platform)] XError(Arc), + #[cfg(x11_platform)] + XMisc(&'static str), #[cfg(wayland_platform)] - WaylandError(Arc), + WaylandMisc(&'static str), } impl fmt::Display for OsError { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { - OsError::Misc(e) => _f.pad(e), #[cfg(x11_platform)] OsError::XError(ref e) => fmt::Display::fmt(e, _f), + #[cfg(x11_platform)] + OsError::XMisc(e) => _f.pad(e), #[cfg(wayland_platform)] - OsError::WaylandError(ref e) => fmt::Display::fmt(e, _f), + OsError::WaylandMisc(e) => _f.pad(e), } } } @@ -726,9 +744,7 @@ impl Clone for EventLoopProxy { } impl EventLoop { - pub(crate) fn new( - attributes: &PlatformSpecificEventLoopAttributes, - ) -> Result { + pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self { if !attributes.any_thread && !is_main_thread() { panic!( "Initializing the event loop outside of the main thread is a significant \ @@ -738,26 +754,65 @@ impl EventLoop { ); } - // NOTE: Wayland first because of X11 could be present under wayland as well. - #[cfg(wayland_platform)] - if attributes.forced_backend == Some(Backend::Wayland) - || env::var("WAYLAND_DISPLAY").is_ok() - { - return EventLoop::new_wayland_any_thread().map_err(Into::into); + #[cfg(x11_platform)] + if attributes.forced_backend == Some(Backend::X) { + // TODO: Propagate + return EventLoop::new_x11_any_thread().unwrap(); } + #[cfg(wayland_platform)] + if attributes.forced_backend == Some(Backend::Wayland) { + // TODO: Propagate + return EventLoop::new_wayland_any_thread().expect("failed to open Wayland connection"); + } + + if let Ok(env_var) = env::var(BACKEND_PREFERENCE_ENV_VAR) { + match env_var.as_str() { + "x11" => { + // TODO: propagate + #[cfg(x11_platform)] + return EventLoop::new_x11_any_thread() + .expect("Failed to initialize X11 backend"); + #[cfg(not(x11_platform))] + panic!("x11 feature is not enabled") + } + "wayland" => { + #[cfg(wayland_platform)] + return EventLoop::new_wayland_any_thread() + .expect("Failed to initialize Wayland backend"); + #[cfg(not(wayland_platform))] + panic!("wayland feature is not enabled"); + } + _ => panic!( + "Unknown environment variable value for {BACKEND_PREFERENCE_ENV_VAR}, try one of `x11`,`wayland`", + ), + } + } + + #[cfg(wayland_platform)] + let wayland_err = match EventLoop::new_wayland_any_thread() { + Ok(event_loop) => return event_loop, + Err(err) => err, + }; + #[cfg(x11_platform)] - if attributes.forced_backend == Some(Backend::X) || env::var("DISPLAY").is_ok() { - return Ok(EventLoop::new_x11_any_thread().unwrap()); - } + let x11_err = match EventLoop::new_x11_any_thread() { + Ok(event_loop) => return event_loop, + Err(err) => err, + }; - Err(EventLoopError::Os(os_error!(OsError::Misc( - "neither WAYLAND_DISPLAY nor DISPLAY is set." - )))) + #[cfg(not(wayland_platform))] + let wayland_err = "backend disabled"; + #[cfg(not(x11_platform))] + let x11_err = "backend disabled"; + + panic!( + "Failed to initialize any backend! Wayland status: {wayland_err:?} X11 status: {x11_err:?}", + ); } #[cfg(wayland_platform)] - fn new_wayland_any_thread() -> Result, EventLoopError> { + fn new_wayland_any_thread() -> Result, Box> { wayland::EventLoop::new().map(|evlp| EventLoop::Wayland(Box::new(evlp))) } @@ -775,14 +830,14 @@ impl EventLoop { x11_or_wayland!(match self; EventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy) } - pub fn run(mut self, callback: F) -> Result<(), EventLoopError> + pub fn run(mut self, callback: F) -> Result<(), RunLoopError> where F: FnMut(crate::event::Event, &RootELW, &mut ControlFlow), { self.run_ondemand(callback) } - pub fn run_ondemand(&mut self, callback: F) -> Result<(), EventLoopError> + pub fn run_ondemand(&mut self, callback: F) -> Result<(), RunLoopError> where F: FnMut(crate::event::Event, &RootELW, &mut ControlFlow), { diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index c691d7e0..28d83802 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -1,6 +1,7 @@ //! The event-loop routines. use std::cell::RefCell; +use std::error::Error; use std::io::Result as IOResult; use std::marker::PhantomData; use std::mem; @@ -12,12 +13,11 @@ use std::time::{Duration, Instant}; use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle}; use sctk::reexports::calloop; -use sctk::reexports::calloop::Error as CalloopError; use sctk::reexports::client::globals; use sctk::reexports::client::{Connection, Proxy, QueueHandle, WaylandSource}; use crate::dpi::{LogicalSize, PhysicalSize}; -use crate::error::{EventLoopError, OsError as RootOsError}; +use crate::error::{OsError as RootOsError, RunLoopError}; use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent}; use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget}; use crate::platform::pump_events::PumpStatus; @@ -33,7 +33,7 @@ use sink::EventSink; use super::state::{WindowCompositorUpdate, WinitState}; use super::window::state::FrameCallbackState; -use super::{DeviceId, WaylandError, WindowId}; +use super::{DeviceId, WindowId}; type WaylandDispatcher = calloop::Dispatcher<'static, WaylandSource, WinitState>; @@ -73,38 +73,22 @@ pub struct EventLoop { } impl EventLoop { - pub fn new() -> Result, EventLoopError> { - macro_rules! map_err { - ($e:expr, $err:expr) => { - $e.map_err(|error| os_error!($err(error).into())) - }; - } + pub fn new() -> Result, Box> { + let connection = Connection::connect_to_env()?; - let connection = map_err!(Connection::connect_to_env(), WaylandError::Connection)?; - - let (globals, mut event_queue) = map_err!( - globals::registry_queue_init(&connection), - WaylandError::Global - )?; + let (globals, mut event_queue) = globals::registry_queue_init(&connection)?; let queue_handle = event_queue.handle(); - let event_loop = map_err!( - calloop::EventLoop::::try_new(), - WaylandError::Calloop - )?; + let event_loop = calloop::EventLoop::::try_new()?; - let mut winit_state = WinitState::new(&globals, &queue_handle, event_loop.handle()) - .map_err(|error| os_error!(error))?; + let mut winit_state = WinitState::new(&globals, &queue_handle, event_loop.handle())?; // NOTE: do a roundtrip after binding the globals to prevent potential // races with the server. - map_err!( - event_queue.roundtrip(&mut winit_state), - WaylandError::Dispatch - )?; + event_queue.roundtrip(&mut winit_state)?; // Register Wayland source. - let wayland_source = map_err!(WaylandSource::new(event_queue), WaylandError::Wire)?; + let wayland_source = WaylandSource::new(event_queue)?; let wayland_dispatcher = calloop::Dispatcher::new(wayland_source, |_, queue, winit_state: &mut WinitState| { let result = queue.dispatch_pending(winit_state); @@ -117,52 +101,32 @@ impl EventLoop { result }); - map_err!( - event_loop - .handle() - .register_dispatcher(wayland_dispatcher.clone()), - WaylandError::Calloop - )?; + event_loop + .handle() + .register_dispatcher(wayland_dispatcher.clone())?; // Setup the user proxy. let pending_user_events = Rc::new(RefCell::new(Vec::new())); let pending_user_events_clone = pending_user_events.clone(); let (user_events_sender, user_events_channel) = calloop::channel::channel(); - map_err!( - event_loop - .handle() - .insert_source( - user_events_channel, - move |event, _, winit_state: &mut WinitState| { - if let calloop::channel::Event::Msg(msg) = event { - winit_state.dispatched_events = true; - pending_user_events_clone.borrow_mut().push(msg); - } - }, - ) - .map_err(|error| error.error), - WaylandError::Calloop + event_loop.handle().insert_source( + user_events_channel, + move |event, _, winit_state: &mut WinitState| { + if let calloop::channel::Event::Msg(msg) = event { + winit_state.dispatched_events = true; + pending_user_events_clone.borrow_mut().push(msg); + } + }, )?; // An event's loop awakener to wake up for window events from winit's windows. - let (event_loop_awakener, event_loop_awakener_source) = map_err!( - calloop::ping::make_ping() - .map_err(|error| CalloopError::OtherError(Box::new(error).into())), - WaylandError::Calloop - )?; - - map_err!( - event_loop - .handle() - .insert_source( - event_loop_awakener_source, - move |_, _, winit_state: &mut WinitState| { - // No extra handling is required, we just need to wake-up. - winit_state.dispatched_events = true; - }, - ) - .map_err(|error| error.error), - WaylandError::Calloop + let (event_loop_awakener, event_loop_awakener_source) = calloop::ping::make_ping()?; + event_loop.handle().insert_source( + event_loop_awakener_source, + move |_, _, winit_state: &mut WinitState| { + // No extra handling is required, we just need to wake-up. + winit_state.dispatched_events = true; + }, )?; let window_target = EventLoopWindowTarget { @@ -194,12 +158,12 @@ impl EventLoop { Ok(event_loop) } - pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> + pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), RunLoopError> where F: FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { if self.loop_running { - return Err(EventLoopError::AlreadyRunning); + return Err(RunLoopError::AlreadyRunning); } let exit = loop { @@ -208,7 +172,7 @@ impl EventLoop { break Ok(()); } PumpStatus::Exit(code) => { - break Err(EventLoopError::ExitFailure(code)); + break Err(RunLoopError::ExitFailure(code)); } _ => { continue; @@ -220,7 +184,7 @@ impl EventLoop { // `run_ondemand` calls but if they have only just dropped their // windows we need to make sure those last requests are sent to the // compositor. - let _ = self.roundtrip().map_err(EventLoopError::Os); + let _ = self.roundtrip().map_err(RunLoopError::Os); exit } @@ -653,10 +617,10 @@ impl EventLoop { let mut wayland_source = self.wayland_dispatcher.as_source_mut(); let event_queue = wayland_source.queue(); - event_queue.roundtrip(state).map_err(|error| { - os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch( - error - )))) + event_queue.roundtrip(state).map_err(|_| { + os_error!(OsError::WaylandMisc( + "failed to do a final roundtrip before exiting the loop." + )) }) } } diff --git a/src/platform_impl/linux/wayland/mod.rs b/src/platform_impl/linux/wayland/mod.rs index 6d232b0d..36439821 100644 --- a/src/platform_impl/linux/wayland/mod.rs +++ b/src/platform_impl/linux/wayland/mod.rs @@ -2,14 +2,10 @@ //! Winit's Wayland backend. -use std::fmt::Display; -use std::sync::Arc; - -use sctk::reexports::client::globals::{BindError, GlobalError}; use sctk::reexports::client::protocol::wl_surface::WlSurface; -use sctk::reexports::client::{self, ConnectError, DispatchError, Proxy}; +use sctk::reexports::client::Proxy; -pub use crate::platform_impl::platform::{OsError, WindowId}; +pub use crate::platform_impl::platform::WindowId; pub use event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget}; pub use output::{MonitorHandle, VideoMode}; pub use window::Window; @@ -21,46 +17,6 @@ mod state; mod types; mod window; -#[derive(Debug)] -pub enum WaylandError { - /// Error connecting to the socket. - Connection(ConnectError), - - /// Error binding the global. - Global(GlobalError), - - // Bind error. - Bind(BindError), - - /// Error during the dispatching the event queue. - Dispatch(DispatchError), - - /// Calloop error. - Calloop(calloop::Error), - - /// Wayland - Wire(client::backend::WaylandError), -} - -impl Display for WaylandError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - WaylandError::Connection(error) => error.fmt(f), - WaylandError::Global(error) => error.fmt(f), - WaylandError::Bind(error) => error.fmt(f), - WaylandError::Dispatch(error) => error.fmt(f), - WaylandError::Calloop(error) => error.fmt(f), - WaylandError::Wire(error) => error.fmt(f), - } - } -} - -impl From for OsError { - fn from(value: WaylandError) -> Self { - Self::WaylandError(Arc::new(value)) - } -} - /// Dummy device id, since Wayland doesn't have device events. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId; diff --git a/src/platform_impl/linux/wayland/state.rs b/src/platform_impl/linux/wayland/state.rs index 762f97ac..5c9bf9c7 100644 --- a/src/platform_impl/linux/wayland/state.rs +++ b/src/platform_impl/linux/wayland/state.rs @@ -1,4 +1,5 @@ use std::cell::RefCell; +use std::error::Error; use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex}; @@ -23,7 +24,6 @@ use sctk::shm::{Shm, ShmHandler}; use sctk::subcompositor::SubcompositorState; use crate::dpi::LogicalSize; -use crate::platform_impl::OsError; use super::event_loop::sink::EventSink; use super::output::MonitorHandle; @@ -35,7 +35,7 @@ use super::types::wp_fractional_scaling::FractionalScalingManager; use super::types::wp_viewporter::ViewporterState; use super::types::xdg_activation::XdgActivationState; use super::window::{WindowRequests, WindowState}; -use super::{WaylandError, WindowId}; +use super::WindowId; /// Winit's Wayland state. pub struct WinitState { @@ -116,16 +116,14 @@ impl WinitState { globals: &GlobalList, queue_handle: &QueueHandle, loop_handle: LoopHandle<'static, WinitState>, - ) -> Result { + ) -> Result> { let registry_state = RegistryState::new(globals); - let compositor_state = - CompositorState::bind(globals, queue_handle).map_err(WaylandError::Bind)?; + let compositor_state = CompositorState::bind(globals, queue_handle)?; let subcompositor_state = SubcompositorState::bind( compositor_state.wl_compositor().clone(), globals, queue_handle, - ) - .map_err(WaylandError::Bind)?; + )?; let output_state = OutputState::new(globals, queue_handle); let monitors = output_state.outputs().map(MonitorHandle::new).collect(); @@ -150,9 +148,9 @@ impl WinitState { subcompositor_state: Arc::new(subcompositor_state), output_state, seat_state, - shm: Shm::bind(globals, queue_handle).map_err(WaylandError::Bind)?, + shm: Shm::bind(globals, queue_handle)?, - xdg_shell: XdgShell::bind(globals, queue_handle).map_err(WaylandError::Bind)?, + xdg_shell: XdgShell::bind(globals, queue_handle)?, xdg_activation: XdgActivationState::bind(globals, queue_handle).ok(), windows: Default::default(), diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index c1efa322..a7c7842f 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -36,7 +36,7 @@ use super::event_loop::sink::EventSink; use super::output::MonitorHandle; use super::state::WinitState; use super::types::xdg_activation::XdgActivationTokenData; -use super::{EventLoopWindowTarget, WaylandError, WindowId}; +use super::{EventLoopWindowTarget, WindowId}; pub(crate) mod state; @@ -205,18 +205,18 @@ impl Window { let event_queue = wayland_source.queue(); // Do a roundtrip. - event_queue.roundtrip(&mut state).map_err(|error| { - os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch( - error - )))) + event_queue.roundtrip(&mut state).map_err(|_| { + os_error!(OsError::WaylandMisc( + "failed to do initial roundtrip for the window." + )) })?; // XXX Wait for the initial configure to arrive. while !window_state.lock().unwrap().is_configured() { - event_queue.blocking_dispatch(&mut state).map_err(|error| { - os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch( - error - )))) + event_queue.blocking_dispatch(&mut state).map_err(|_| { + os_error!(OsError::WaylandMisc( + "failed to dispatch queue while waiting for initial configure." + )) })?; } @@ -570,7 +570,9 @@ impl Window { Ok(()) } else { let region = Region::new(&*self.compositor).map_err(|_| { - ExternalError::Os(os_error!(OsError::Misc("failed to set input region."))) + ExternalError::Os(os_error!(OsError::WaylandMisc( + "failed to set input region." + ))) })?; region.add(0, 0, 0, 0); surface.set_input_region(Some(region.wl_region())); diff --git a/src/platform_impl/linux/wayland/window/state.rs b/src/platform_impl/linux/wayland/window/state.rs index abe88879..e0c49202 100644 --- a/src/platform_impl/linux/wayland/window/state.rs +++ b/src/platform_impl/linux/wayland/window/state.rs @@ -712,7 +712,7 @@ impl WindowState { // Positon can be set only for locked cursor. if self.cursor_grab_mode.current_grab_mode != CursorGrabMode::Locked { return Err(ExternalError::Os(os_error!( - crate::platform_impl::OsError::Misc( + crate::platform_impl::OsError::WaylandMisc( "cursor position can be set only for locked cursor." ) ))); diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 787f3994..0746c42d 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -64,7 +64,7 @@ use self::{ }; use super::{common::xkb_state::KbdState, OsError}; use crate::{ - error::{EventLoopError, OsError as RootOsError}, + error::{OsError as RootOsError, RunLoopError}, event::{Event, StartCause}, event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW}, platform::pump_events::PumpStatus, @@ -432,12 +432,12 @@ impl EventLoop { &self.target } - pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> + pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), RunLoopError> where F: FnMut(Event, &RootELW, &mut ControlFlow), { if self.loop_running { - return Err(EventLoopError::AlreadyRunning); + return Err(RunLoopError::AlreadyRunning); } let exit = loop { @@ -446,7 +446,7 @@ impl EventLoop { break Ok(()); } PumpStatus::Exit(code) => { - break Err(EventLoopError::ExitFailure(code)); + break Err(RunLoopError::ExitFailure(code)); } _ => { continue; @@ -460,7 +460,7 @@ impl EventLoop { // X Server. let wt = get_xtarget(&self.target); wt.x_connection().sync_with_server().map_err(|x_err| { - EventLoopError::Os(os_error!(OsError::XError(Arc::new(X11Error::Xlib(x_err))))) + RunLoopError::Os(os_error!(OsError::XError(Arc::new(X11Error::Xlib(x_err))))) })?; exit diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 7094b3b8..d44fa4fa 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -485,7 +485,7 @@ impl UnownedWindow { &mut supported_ptr, ); if supported_ptr == ffi::False { - return Err(os_error!(OsError::Misc( + return Err(os_error!(OsError::XMisc( "`XkbSetDetectableAutoRepeat` failed" ))); } @@ -1488,7 +1488,7 @@ impl UnownedWindow { } _ => unreachable!(), } - .map_err(|err| ExternalError::Os(os_error!(OsError::Misc(err)))) + .map_err(|err| ExternalError::Os(os_error!(OsError::XMisc(err)))) } CursorGrabMode::Locked => { return Err(ExternalError::NotSupported(NotSupportedError::new())); diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index f4f2ea49..9d8b4782 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -24,7 +24,7 @@ use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle}; use super::appkit::{NSApp, NSApplicationActivationPolicy, NSEvent, NSWindow}; use crate::{ - error::EventLoopError, + error::RunLoopError, event::Event, event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootWindowTarget}, platform::{macos::ActivationPolicy, pump_events::PumpStatus}, @@ -148,9 +148,7 @@ impl Default for PlatformSpecificEventLoopAttributes { } impl EventLoop { - pub(crate) fn new( - attributes: &PlatformSpecificEventLoopAttributes, - ) -> Result { + pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self { if !is_main_thread() { panic!("On macOS, `EventLoop` must be created on the main thread!"); } @@ -180,7 +178,7 @@ impl EventLoop { let panic_info: Rc = Default::default(); setup_control_flow_observers(Rc::downgrade(&panic_info)); - Ok(EventLoop { + EventLoop { _delegate: delegate, window_target: Rc::new(RootWindowTarget { p: Default::default(), @@ -188,14 +186,14 @@ impl EventLoop { }), panic_info, _callback: None, - }) + } } pub fn window_target(&self) -> &RootWindowTarget { &self.window_target } - pub fn run(mut self, callback: F) -> Result<(), EventLoopError> + pub fn run(mut self, callback: F) -> Result<(), RunLoopError> where F: FnMut(Event, &RootWindowTarget, &mut ControlFlow), { @@ -206,12 +204,12 @@ impl EventLoop { // `pump_events` elegantly (we just ask to run the loop for a "short" amount of // time and so a layered implementation would end up using a lot of CPU due to // redundant wake ups. - pub fn run_ondemand(&mut self, callback: F) -> Result<(), EventLoopError> + pub fn run_ondemand(&mut self, callback: F) -> Result<(), RunLoopError> where F: FnMut(Event, &RootWindowTarget, &mut ControlFlow), { if AppState::is_running() { - return Err(EventLoopError::AlreadyRunning); + return Err(RunLoopError::AlreadyRunning); } // # Safety @@ -289,7 +287,7 @@ impl EventLoop { if exit_code == 0 { Ok(()) } else { - Err(EventLoopError::ExitFailure(exit_code)) + Err(RunLoopError::ExitFailure(exit_code)) } } diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index 5ffe3864..71d733d9 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -12,7 +12,7 @@ use orbclient::{ use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle}; use crate::{ - error::EventLoopError, + error::RunLoopError, event::{self, Ime, Modifiers, StartCause}, event_loop::{self, ControlFlow}, keyboard::{ @@ -22,8 +22,8 @@ use crate::{ }; use super::{ - DeviceId, KeyEventExtra, MonitorHandle, OsError, PlatformSpecificEventLoopAttributes, - RedoxSocket, TimeSocket, WindowId, WindowProperties, + DeviceId, KeyEventExtra, MonitorHandle, PlatformSpecificEventLoopAttributes, RedoxSocket, + TimeSocket, WindowId, WindowProperties, }; fn convert_scancode(scancode: u8) -> KeyCode { @@ -270,20 +270,12 @@ pub struct EventLoop { } impl EventLoop { - pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result { + pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Self { let (user_events_sender, user_events_receiver) = mpsc::channel(); - let event_socket = Arc::new( - RedoxSocket::event() - .map_err(OsError::new) - .map_err(|error| EventLoopError::Os(os_error!(error)))?, - ); + let event_socket = Arc::new(RedoxSocket::event().unwrap()); - let wake_socket = Arc::new( - TimeSocket::open() - .map_err(OsError::new) - .map_err(|error| EventLoopError::Os(os_error!(error)))?, - ); + let wake_socket = Arc::new(TimeSocket::open().unwrap()); event_socket .write(&syscall::Event { @@ -291,10 +283,9 @@ impl EventLoop { flags: syscall::EventFlags::EVENT_READ, data: wake_socket.0.fd, }) - .map_err(OsError::new) - .map_err(|error| EventLoopError::Os(os_error!(error)))?; + .unwrap(); - Ok(Self { + Self { windows: Vec::new(), window_target: event_loop::EventLoopWindowTarget { p: EventLoopWindowTarget { @@ -308,7 +299,7 @@ impl EventLoop { }, _marker: std::marker::PhantomData, }, - }) + } } fn process_event( @@ -452,7 +443,7 @@ impl EventLoop { } } - pub fn run(mut self, mut event_handler_inner: F) -> Result<(), EventLoopError> + pub fn run(mut self, mut event_handler_inner: F) -> Result<(), RunLoopError> where F: FnMut(event::Event, &event_loop::EventLoopWindowTarget, &mut ControlFlow), { @@ -694,7 +685,7 @@ impl EventLoop { if code == 0 { Ok(()) } else { - Err(EventLoopError::ExitFailure(code)) + Err(RunLoopError::ExitFailure(code)) } } diff --git a/src/platform_impl/orbital/mod.rs b/src/platform_impl/orbital/mod.rs index 5aa56328..961f6c4e 100644 --- a/src/platform_impl/orbital/mod.rs +++ b/src/platform_impl/orbital/mod.rs @@ -1,8 +1,6 @@ #![cfg(target_os = "redox")] -use std::fmt::{self, Display, Formatter}; use std::str; -use std::sync::Arc; use crate::dpi::{PhysicalPosition, PhysicalSize}; @@ -178,18 +176,13 @@ impl<'a> fmt::Display for WindowProperties<'a> { } } -#[derive(Clone, Debug)] -pub struct OsError(Arc); - -impl OsError { - fn new(error: syscall::Error) -> Self { - Self(Arc::new(error)) - } -} +#[derive(Default, Clone, Debug)] +pub struct OsError; +use std::fmt::{self, Display, Formatter}; impl Display for OsError { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> { - self.0.fmt(fmt) + write!(fmt, "Redox OS Error") } } diff --git a/src/platform_impl/web/event_loop/mod.rs b/src/platform_impl/web/event_loop/mod.rs index 48c95fc2..60c9a086 100644 --- a/src/platform_impl/web/event_loop/mod.rs +++ b/src/platform_impl/web/event_loop/mod.rs @@ -1,18 +1,16 @@ -use std::marker::PhantomData; - -use crate::error::EventLoopError; -use crate::event::Event; -use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget}; - -use super::{backend, device, window}; - mod proxy; pub(crate) mod runner; mod state; mod window_target; -pub use proxy::EventLoopProxy; -pub use window_target::EventLoopWindowTarget; +pub use self::proxy::EventLoopProxy; +pub use self::window_target::EventLoopWindowTarget; + +use super::{backend, device, window}; +use crate::event::Event; +use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget}; + +use std::marker::PhantomData; pub struct EventLoop { elw: RootEventLoopWindowTarget, @@ -22,13 +20,13 @@ pub struct EventLoop { pub(crate) struct PlatformSpecificEventLoopAttributes {} impl EventLoop { - pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result { - Ok(EventLoop { + pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Self { + EventLoop { elw: RootEventLoopWindowTarget { p: EventLoopWindowTarget::new(), _marker: PhantomData, }, - }) + } } pub fn run(self, mut event_handler: F) -> ! diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 791c64b4..7f6c1888 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -75,7 +75,7 @@ use windows_sys::Win32::{ use crate::{ dpi::{PhysicalPosition, PhysicalSize}, - error::EventLoopError, + error::RunLoopError, event::{ DeviceEvent, Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase, WindowEvent, @@ -201,9 +201,7 @@ pub struct EventLoopWindowTarget { } impl EventLoop { - pub(crate) fn new( - attributes: &mut PlatformSpecificEventLoopAttributes, - ) -> Result { + pub(crate) fn new(attributes: &mut PlatformSpecificEventLoopAttributes) -> Self { let thread_id = unsafe { GetCurrentThreadId() }; if !attributes.any_thread && thread_id != main_thread_id() { @@ -230,7 +228,7 @@ impl EventLoop { Default::default(), ); - Ok(EventLoop { + EventLoop { thread_msg_sender, window_target: RootELW { p: EventLoopWindowTarget { @@ -241,28 +239,28 @@ impl EventLoop { _marker: PhantomData, }, msg_hook: attributes.msg_hook.take(), - }) + } } pub fn window_target(&self) -> &RootELW { &self.window_target } - pub fn run(mut self, event_handler: F) -> Result<(), EventLoopError> + pub fn run(mut self, event_handler: F) -> Result<(), RunLoopError> where F: FnMut(Event, &RootELW, &mut ControlFlow), { self.run_ondemand(event_handler) } - pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> + pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), RunLoopError> where F: FnMut(Event, &RootELW, &mut ControlFlow), { { let runner = &self.window_target.p.runner_shared; if runner.state() != RunnerState::Uninitialized { - return Err(EventLoopError::AlreadyRunning); + return Err(RunLoopError::AlreadyRunning); } let event_loop_windows_ref = &self.window_target; @@ -297,7 +295,7 @@ impl EventLoop { if exit_code == 0 { Ok(()) } else { - Err(EventLoopError::ExitFailure(exit_code)) + Err(RunLoopError::ExitFailure(exit_code)) } } diff --git a/src/window.rs b/src/window.rs index c03eb0f5..be515a95 100644 --- a/src/window.rs +++ b/src/window.rs @@ -29,7 +29,7 @@ pub use cursor_icon::{CursorIcon, ParseError as CursorIconParseError}; /// window::Window, /// }; /// -/// let mut event_loop = EventLoop::new().unwrap(); +/// let mut event_loop = EventLoop::new(); /// let window = Window::new(&event_loop).unwrap(); /// /// event_loop.run(move |event, _, control_flow| { @@ -570,7 +570,7 @@ impl Window { /// ```no_run /// # use winit::event_loop::EventLoop; /// # use winit::window::Window; - /// # let mut event_loop = EventLoop::new().unwrap(); + /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// # fn swap_buffers() {} /// // Do the actual drawing with OpenGL. @@ -660,7 +660,7 @@ impl Window { /// # use winit::dpi::{LogicalPosition, PhysicalPosition}; /// # use winit::event_loop::EventLoop; /// # use winit::window::Window; - /// # let mut event_loop = EventLoop::new().unwrap(); + /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// // Specify the position in logical dimensions like this: /// window.set_outer_position(LogicalPosition::new(400.0, 200.0)); @@ -720,7 +720,7 @@ impl Window { /// # use winit::dpi::{LogicalSize, PhysicalSize}; /// # use winit::event_loop::EventLoop; /// # use winit::window::Window; - /// # let mut event_loop = EventLoop::new().unwrap(); + /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// // Specify the size in logical dimensions like this: /// let _ = window.request_inner_size(LogicalSize::new(400.0, 200.0)); @@ -763,7 +763,7 @@ impl Window { /// # use winit::dpi::{LogicalSize, PhysicalSize}; /// # use winit::event_loop::EventLoop; /// # use winit::window::Window; - /// # let mut event_loop = EventLoop::new().unwrap(); + /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// // Specify the size in logical dimensions like this: /// window.set_min_inner_size(Some(LogicalSize::new(400.0, 200.0))); @@ -786,7 +786,7 @@ impl Window { /// # use winit::dpi::{LogicalSize, PhysicalSize}; /// # use winit::event_loop::EventLoop; /// # use winit::window::Window; - /// # let mut event_loop = EventLoop::new().unwrap(); + /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// // Specify the size in logical dimensions like this: /// window.set_max_inner_size(Some(LogicalSize::new(400.0, 200.0))); @@ -1098,7 +1098,7 @@ impl Window { /// # use winit::dpi::{LogicalPosition, PhysicalPosition, LogicalSize, PhysicalSize}; /// # use winit::event_loop::EventLoop; /// # use winit::window::Window; - /// # let mut event_loop = EventLoop::new().unwrap(); + /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// // Specify the position in logical dimensions like this: /// window.set_ime_cursor_area(LogicalPosition::new(400.0, 200.0), LogicalSize::new(100, 100)); @@ -1266,7 +1266,7 @@ impl Window { /// # use winit::dpi::{LogicalPosition, PhysicalPosition}; /// # use winit::event_loop::EventLoop; /// # use winit::window::Window; - /// # let mut event_loop = EventLoop::new().unwrap(); + /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// // Specify the position in logical dimensions like this: /// window.set_cursor_position(LogicalPosition::new(400.0, 200.0)); @@ -1292,7 +1292,7 @@ impl Window { /// ```no_run /// # use winit::event_loop::EventLoop; /// # use winit::window::{CursorGrabMode, Window}; - /// # let mut event_loop = EventLoop::new().unwrap(); + /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// window.set_cursor_grab(CursorGrabMode::Confined) /// .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked))