From b674d20edf4c212d4a98040e4a99013a76287f1e Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Fri, 6 Sep 2024 17:20:11 +0300 Subject: [PATCH] api: unify error handling Make error infrastructure more backend agnostic and let backends just forward the os errors opaquely. --- examples/window.rs | 4 +- src/error.rs | 202 ++++++++++-------- src/event.rs | 6 +- src/event_loop.rs | 8 +- src/platform/startup_notify.rs | 8 +- src/platform_impl/android/mod.rs | 38 ++-- src/platform_impl/apple/appkit/cursor.rs | 9 +- src/platform_impl/apple/appkit/event_loop.rs | 6 +- src/platform_impl/apple/appkit/mod.rs | 17 -- src/platform_impl/apple/appkit/window.rs | 37 ++-- .../apple/appkit/window_delegate.rs | 46 ++-- src/platform_impl/apple/uikit/event_loop.rs | 8 +- src/platform_impl/apple/uikit/window.rs | 75 +++---- src/platform_impl/linux/mod.rs | 40 +--- .../linux/wayland/event_loop/mod.rs | 59 ++--- src/platform_impl/linux/wayland/mod.rs | 48 +---- src/platform_impl/linux/wayland/state.rs | 10 +- src/platform_impl/linux/wayland/window/mod.rs | 44 ++-- .../linux/wayland/window/state.rs | 27 ++- src/platform_impl/linux/x11/ime/context.rs | 16 +- src/platform_impl/linux/x11/mod.rs | 16 +- src/platform_impl/linux/x11/util/cursor.rs | 8 +- src/platform_impl/linux/x11/window.rs | 125 +++++------ src/platform_impl/orbital/event_loop.rs | 29 +-- src/platform_impl/orbital/mod.rs | 29 +-- src/platform_impl/orbital/window.rs | 50 ++--- .../web/event_loop/window_target.rs | 11 +- src/platform_impl/web/mod.rs | 1 - src/platform_impl/web/web_sys/canvas.rs | 10 +- src/platform_impl/web/window.rs | 37 ++-- src/platform_impl/windows/event_loop.rs | 6 +- src/platform_impl/windows/icon.rs | 14 +- src/platform_impl/windows/mod.rs | 2 - src/platform_impl/windows/window.rs | 31 +-- src/window.rs | 38 ++-- 35 files changed, 496 insertions(+), 619 deletions(-) diff --git a/examples/window.rs b/examples/window.rs index 719011c1af..650b0a7cb2 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -17,7 +17,7 @@ use rwh_06::{DisplayHandle, HasDisplayHandle}; use softbuffer::{Context, Surface}; use winit::application::ApplicationHandler; use winit::dpi::{LogicalSize, PhysicalPosition, PhysicalSize}; -use winit::error::ExternalError; +use winit::error::RequestError; use winit::event::{DeviceEvent, DeviceId, Ime, MouseButton, MouseScrollDelta, WindowEvent}; use winit::event_loop::{ActiveEventLoop, EventLoop}; use winit::keyboard::{Key, ModifiersState}; @@ -76,7 +76,7 @@ struct Application { receiver: Receiver, sender: Sender, /// Custom cursors assets. - custom_cursors: Result, ExternalError>, + custom_cursors: Result, RequestError>, /// Application icon. icon: Icon, windows: HashMap, diff --git a/src/error.rs b/src/error.rs index 3e9ec8525a..697b37dd15 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,45 +1,40 @@ -use std::{error, fmt}; +use std::error::Error; +use std::fmt::{self, Display}; -use crate::platform_impl; - -// TODO: Rename -/// An error that may be generated when requesting Winit state -#[derive(Debug)] -pub enum ExternalError { - /// The operation is not supported by the backend. - NotSupported(NotSupportedError), - /// The operation was ignored. - Ignored, - /// The OS cannot perform the operation. - Os(OsError), -} - -/// The error type for when the requested operation is not supported by the backend. -#[derive(Clone, Copy, Default, Eq, Hash, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct NotSupportedError { - _marker: (), -} - -/// The error type for when the OS cannot perform the requested operation. -#[derive(Debug)] -pub struct OsError { - line: u32, - file: &'static str, - error: platform_impl::OsError, -} - -/// A general error that may occur while running the Winit event loop +/// A general error that may occur while running or creating +/// the event loop. #[derive(Debug)] +#[non_exhaustive] pub enum EventLoopError { - /// The operation is not supported by the backend. - NotSupported(NotSupportedError), - /// The OS cannot perform the operation. - Os(OsError), /// The event loop can't be re-created. RecreationAttempt, /// Application has exit with an error status. ExitFailure(i32), + /// Got unspecified OS-specific error during the request. + Os(OsError), + /// Creating the event loop with the requested configuration is not supported. + NotSupported(NotSupportedError), +} + +impl fmt::Display for EventLoopError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::RecreationAttempt => write!(f, "EventLoop can't be recreated"), + Self::Os(err) => err.fmt(f), + Self::ExitFailure(status) => write!(f, "Exit Failure: {status}"), + Self::NotSupported(err) => err.fmt(f), + } + } +} + +impl Error for EventLoopError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + if let Self::Os(err) = self { + err.source() + } else { + None + } + } } impl From for EventLoopError { @@ -48,85 +43,108 @@ impl From for EventLoopError { } } -impl NotSupportedError { - #[inline] - #[allow(dead_code)] - pub(crate) fn new() -> NotSupportedError { - NotSupportedError { _marker: () } +impl From for EventLoopError { + fn from(value: NotSupportedError) -> Self { + Self::NotSupported(value) } } -impl OsError { - #[allow(dead_code)] - pub(crate) fn new(line: u32, file: &'static str, error: platform_impl::OsError) -> OsError { - OsError { line, file, error } - } +/// A general error that may occur during a request to the windowing system. +#[derive(Debug)] +#[non_exhaustive] +pub enum RequestError { + /// The request is not supported. + NotSupported(NotSupportedError), + /// The request was ignored by the operating system. + Ignored, + /// Got unspecified OS specific error during the request. + Os(OsError), } -#[allow(unused_macros)] -macro_rules! os_error { - ($error:expr) => {{ - crate::error::OsError::new(line!(), file!(), $error) - }}; +impl Display for RequestError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::NotSupported(err) => err.fmt(f), + Self::Ignored => write!(f, "The request was ignored"), + Self::Os(err) => err.fmt(f), + } + } +} +impl Error for RequestError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + if let Self::Os(err) = self { + err.source() + } else { + None + } + } } -impl fmt::Display for OsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.pad(&format!("os error at {}:{}: {}", self.file, self.line, self.error)) +impl From for RequestError { + fn from(value: NotSupportedError) -> Self { + Self::NotSupported(value) } } -impl fmt::Display for ExternalError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - ExternalError::NotSupported(e) => e.fmt(f), - ExternalError::Ignored => write!(f, "Operation was ignored"), - ExternalError::Os(e) => e.fmt(f), - } +impl From for RequestError { + fn from(value: OsError) -> Self { + Self::Os(value) } } -impl fmt::Debug for NotSupportedError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.debug_struct("NotSupportedError").finish() +/// The requested operation is not supported. +#[derive(Debug)] +pub struct NotSupportedError { + /// The reason why a certain operation is not supported. + reason: &'static str, +} + +impl NotSupportedError { + pub(crate) fn new(reason: &'static str) -> Self { + Self { reason } } } impl fmt::Display for NotSupportedError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.pad("the requested operation is not supported by Winit") + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Operation is not supported: {}", self.reason) } } +impl Error for NotSupportedError {} -impl fmt::Display for EventLoopError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - EventLoopError::RecreationAttempt => write!(f, "EventLoop can't be recreated"), - EventLoopError::NotSupported(e) => e.fmt(f), - EventLoopError::Os(e) => e.fmt(f), - EventLoopError::ExitFailure(status) => write!(f, "Exit Failure: {status}"), - } +/// Unclassified error from the OS. +#[derive(Debug)] +pub struct OsError { + line: u32, + file: &'static str, + error: Box, +} + +impl OsError { + #[allow(dead_code)] + pub(crate) fn new( + line: u32, + file: &'static str, + error: impl Into>, + ) -> Self { + Self { line, file, error: error.into() } } } -impl error::Error for OsError {} -impl error::Error for ExternalError {} -impl error::Error for NotSupportedError {} -impl error::Error for EventLoopError {} - -#[cfg(test)] -#[allow(clippy::redundant_clone)] -mod tests { - use super::*; - - // Eat attributes for testing - #[test] - fn ensure_fmt_does_not_panic() { - let _ = format!("{:?}, {}", NotSupportedError::new(), NotSupportedError::new().clone()); - let _ = format!( - "{:?}, {}", - ExternalError::NotSupported(NotSupportedError::new()), - ExternalError::NotSupported(NotSupportedError::new()) - ); +impl Display for OsError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad(&format!("os error at {}:{}: {}", self.file, self.line, self.error)) + } +} +impl Error for OsError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(self.error.as_ref()) } } + +#[allow(unused_macros)] +macro_rules! os_error { + ($error:expr) => {{ + crate::error::OsError::new(line!(), file!(), $error) + }}; +} diff --git a/src/event.rs b/src/event.rs index 67ee7a53d2..223992db8f 100644 --- a/src/event.rs +++ b/src/event.rs @@ -46,7 +46,7 @@ use smol_str::SmolStr; use web_time::Instant; use crate::dpi::{PhysicalPosition, PhysicalSize}; -use crate::error::ExternalError; +use crate::error::RequestError; use crate::event_loop::AsyncRequestSerial; use crate::keyboard::{self, ModifiersKeyState, ModifiersKeys, ModifiersState}; use crate::platform_impl; @@ -1016,12 +1016,12 @@ impl SurfaceSizeWriter { pub fn request_surface_size( &mut self, new_surface_size: PhysicalSize, - ) -> Result<(), ExternalError> { + ) -> Result<(), RequestError> { if let Some(inner) = self.new_surface_size.upgrade() { *inner.lock().unwrap() = new_surface_size; Ok(()) } else { - Err(ExternalError::Ignored) + Err(RequestError::Ignored) } } } diff --git a/src/event_loop.rs b/src/event_loop.rs index d631e0d847..edcac345f8 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -20,7 +20,7 @@ use std::time::{Duration, Instant}; use web_time::{Duration, Instant}; use crate::application::ApplicationHandler; -use crate::error::{EventLoopError, ExternalError, OsError}; +use crate::error::{EventLoopError, RequestError}; use crate::monitor::MonitorHandle; use crate::platform_impl; use crate::utils::AsAny; @@ -268,7 +268,7 @@ impl EventLoop { pub fn create_custom_cursor( &self, custom_cursor: CustomCursorSource, - ) -> Result { + ) -> Result { self.event_loop.window_target().create_custom_cursor(custom_cursor) } } @@ -324,7 +324,7 @@ pub trait ActiveEventLoop: AsAny { fn create_window( &self, window_attributes: WindowAttributes, - ) -> Result, OsError>; + ) -> Result, RequestError>; /// Create custom cursor. /// @@ -334,7 +334,7 @@ pub trait ActiveEventLoop: AsAny { fn create_custom_cursor( &self, custom_cursor: CustomCursorSource, - ) -> Result; + ) -> Result; /// Returns the list of all the monitors available on the system. /// diff --git a/src/platform/startup_notify.rs b/src/platform/startup_notify.rs index c09aa6629b..1329ff2689 100644 --- a/src/platform/startup_notify.rs +++ b/src/platform/startup_notify.rs @@ -23,7 +23,7 @@ use std::env; -use crate::error::NotSupportedError; +use crate::error::{NotSupportedError, RequestError}; use crate::event_loop::{ActiveEventLoop, AsyncRequestSerial}; #[cfg(wayland_platform)] use crate::platform::wayland::ActiveEventLoopExtWayland; @@ -46,7 +46,7 @@ pub trait WindowExtStartupNotify { /// Request a new activation token. /// /// The token will be delivered inside - fn request_activation_token(&self) -> Result; + fn request_activation_token(&self) -> Result; } pub trait WindowAttributesExtStartupNotify { @@ -73,7 +73,7 @@ impl EventLoopExtStartupNotify for dyn ActiveEventLoop + '_ { } impl WindowExtStartupNotify for dyn Window + '_ { - fn request_activation_token(&self) -> Result { + fn request_activation_token(&self) -> Result { #[cfg(wayland_platform)] if let Some(window) = self.as_any().downcast_ref::() { @@ -87,7 +87,7 @@ impl WindowExtStartupNotify for dyn Window + '_ { return window.request_activation_token(); } - Err(NotSupportedError::new()) + Err(NotSupportedError::new("startup notify is not supported").into()) } } diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 1da2a0130d..426dd0fb35 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -14,7 +14,7 @@ use tracing::{debug, trace, warn}; use crate::application::ApplicationHandler; use crate::cursor::Cursor; use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error::{self, EventLoopError, ExternalError, NotSupportedError}; +use crate::error::{EventLoopError, NotSupportedError, RequestError}; use crate::event::{self, Force, StartCause, SurfaceSizeWriter}; use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, @@ -592,15 +592,15 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_window( &self, window_attributes: WindowAttributes, - ) -> Result, error::OsError> { + ) -> Result, RequestError> { Ok(Box::new(Window::new(self, window_attributes)?)) } fn create_custom_cursor( &self, _source: CustomCursorSource, - ) -> Result { - Err(ExternalError::NotSupported(NotSupportedError::new())) + ) -> Result { + Err(NotSupportedError::new("create_custom_cursor is not supported").into()) } fn available_monitors(&self) -> Box> { @@ -715,7 +715,7 @@ impl Window { pub(crate) fn new( el: &ActiveEventLoop, _window_attrs: window::WindowAttributes, - ) -> Result { + ) -> Result { // FIXME this ignores requested window attributes Ok(Self { app: el.app.clone(), redraw_requester: el.redraw_requester.clone() }) @@ -796,12 +796,12 @@ impl CoreWindow for Window { fn pre_present_notify(&self) {} - fn inner_position(&self) -> Result, error::NotSupportedError> { - Err(error::NotSupportedError::new()) + fn inner_position(&self) -> Result, RequestError> { + Err(NotSupportedError::new("inner_position is not supported").into()) } - fn outer_position(&self) -> Result, error::NotSupportedError> { - Err(error::NotSupportedError::new()) + fn outer_position(&self) -> Result, RequestError> { + Err(NotSupportedError::new("outer_position is not supported").into()) } fn set_outer_position(&self, _position: Position) { @@ -896,29 +896,29 @@ impl CoreWindow for Window { fn set_cursor(&self, _: Cursor) {} - fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> { - Err(error::ExternalError::NotSupported(error::NotSupportedError::new())) + fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_position is not supported").into()) } - fn set_cursor_grab(&self, _: CursorGrabMode) -> Result<(), error::ExternalError> { - Err(error::ExternalError::NotSupported(error::NotSupportedError::new())) + fn set_cursor_grab(&self, _: CursorGrabMode) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_grab is not supported").into()) } fn set_cursor_visible(&self, _: bool) {} - fn drag_window(&self) -> Result<(), error::ExternalError> { - Err(error::ExternalError::NotSupported(error::NotSupportedError::new())) + fn drag_window(&self) -> Result<(), RequestError> { + Err(NotSupportedError::new("drag_window is not supported").into()) } - fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), error::ExternalError> { - Err(error::ExternalError::NotSupported(error::NotSupportedError::new())) + fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), RequestError> { + Err(NotSupportedError::new("drag_resize_window").into()) } #[inline] fn show_window_menu(&self, _position: Position) {} - fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), error::ExternalError> { - Err(error::ExternalError::NotSupported(error::NotSupportedError::new())) + fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) } fn set_theme(&self, _theme: Option) {} diff --git a/src/platform_impl/apple/appkit/cursor.rs b/src/platform_impl/apple/appkit/cursor.rs index fd474f18f4..70a36e1110 100644 --- a/src/platform_impl/apple/appkit/cursor.rs +++ b/src/platform_impl/apple/appkit/cursor.rs @@ -11,9 +11,8 @@ use objc2_foundation::{ NSString, }; -use super::OsError; use crate::cursor::{CursorImage, OnlyCursorImageSource}; -use crate::error::ExternalError; +use crate::error::RequestError; use crate::window::CursorIcon; #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -25,12 +24,12 @@ unsafe impl Send for CustomCursor {} unsafe impl Sync for CustomCursor {} impl CustomCursor { - pub(crate) fn new(cursor: OnlyCursorImageSource) -> Result { + pub(crate) fn new(cursor: OnlyCursorImageSource) -> Result { cursor_from_image(&cursor.0).map(Self) } } -pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Result, ExternalError> { +pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Result, RequestError> { let width = cursor.width; let height = cursor.height; @@ -48,7 +47,7 @@ pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Result Result, crate::error::OsError> { + ) -> Result, RequestError> { Ok(Box::new(Window::new(self, window_attributes)?)) } fn create_custom_cursor( &self, source: CustomCursorSource, - ) -> Result { + ) -> Result { Ok(RootCustomCursor { inner: CustomCursor::new(source.inner)? }) } diff --git a/src/platform_impl/apple/appkit/mod.rs b/src/platform_impl/apple/appkit/mod.rs index f02c26d16a..8724c24938 100644 --- a/src/platform_impl/apple/appkit/mod.rs +++ b/src/platform_impl/apple/appkit/mod.rs @@ -14,8 +14,6 @@ mod view; mod window; mod window_delegate; -use std::fmt; - pub(crate) use self::cursor::CustomCursor as PlatformCustomCursor; pub(crate) use self::event::{physicalkey_to_scancode, scancode_to_physicalkey, KeyEventExtra}; pub(crate) use self::event_loop::{ @@ -50,18 +48,3 @@ impl FingerId { FingerId } } - -#[derive(Debug)] -pub enum OsError { - CGError(core_graphics::base::CGError), - CreationError(&'static str), -} - -impl fmt::Display for OsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - OsError::CGError(e) => f.pad(&format!("CGError {e}")), - OsError::CreationError(e) => f.pad(e), - } - } -} diff --git a/src/platform_impl/apple/appkit/window.rs b/src/platform_impl/apple/appkit/window.rs index 11c241dc45..3a454e0457 100644 --- a/src/platform_impl/apple/appkit/window.rs +++ b/src/platform_impl/apple/appkit/window.rs @@ -8,7 +8,7 @@ use objc2_foundation::{MainThreadBound, MainThreadMarker, NSObject}; use super::event_loop::ActiveEventLoop; use super::window_delegate::WindowDelegate; -use crate::error::OsError as RootOsError; +use crate::error::RequestError; use crate::monitor::MonitorHandle as CoreMonitorHandle; use crate::window::{ Cursor, Fullscreen, Icon, ImePurpose, Theme, UserAttentionType, Window as CoreWindow, @@ -25,7 +25,7 @@ impl Window { pub(crate) fn new( window_target: &ActiveEventLoop, attributes: WindowAttributes, - ) -> Result { + ) -> Result { let mtm = window_target.mtm; let delegate = autoreleasepool(|_| WindowDelegate::new(&window_target.app_state, attributes, mtm))?; @@ -111,16 +111,12 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.reset_dead_keys()); } - fn inner_position( - &self, - ) -> Result, crate::error::NotSupportedError> { - self.maybe_wait_on_main(|delegate| delegate.inner_position()) + fn inner_position(&self) -> Result, RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.inner_position())) } - fn outer_position( - &self, - ) -> Result, crate::error::NotSupportedError> { - self.maybe_wait_on_main(|delegate| delegate.outer_position()) + fn outer_position(&self) -> Result, RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.outer_position())) } fn set_outer_position(&self, position: Position) { @@ -275,14 +271,11 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor)); } - fn set_cursor_position(&self, position: Position) -> Result<(), crate::error::ExternalError> { + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position)) } - fn set_cursor_grab( - &self, - mode: crate::window::CursorGrabMode, - ) -> Result<(), crate::error::ExternalError> { + fn set_cursor_grab(&self, mode: crate::window::CursorGrabMode) -> Result<(), RequestError> { self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode)) } @@ -290,23 +283,25 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_cursor_visible(visible)) } - fn drag_window(&self) -> Result<(), crate::error::ExternalError> { - self.maybe_wait_on_main(|delegate| delegate.drag_window()) + fn drag_window(&self) -> Result<(), RequestError> { + self.maybe_wait_on_main(|delegate| delegate.drag_window()); + Ok(()) } fn drag_resize_window( &self, direction: crate::window::ResizeDirection, - ) -> Result<(), crate::error::ExternalError> { - self.maybe_wait_on_main(|delegate| delegate.drag_resize_window(direction)) + ) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.drag_resize_window(direction))?) } fn show_window_menu(&self, position: Position) { self.maybe_wait_on_main(|delegate| delegate.show_window_menu(position)) } - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), crate::error::ExternalError> { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest)) + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { + self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest)); + Ok(()) } fn current_monitor(&self) -> Option { diff --git a/src/platform_impl/apple/appkit/window_delegate.rs b/src/platform_impl/apple/appkit/window_delegate.rs index 52ef4759de..fdad0c515e 100644 --- a/src/platform_impl/apple/appkit/window_delegate.rs +++ b/src/platform_impl/apple/appkit/window_delegate.rs @@ -33,9 +33,9 @@ use super::monitor::{self, flip_window_screen_coordinates, get_display_id}; use super::observer::RunLoop; use super::view::WinitView; use super::window::WinitWindow; -use super::{ffi, Fullscreen, MonitorHandle, OsError, WindowId}; +use super::{ffi, Fullscreen, MonitorHandle, WindowId}; use crate::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError}; +use crate::error::{NotSupportedError, RequestError}; use crate::event::{SurfaceSizeWriter, WindowEvent}; use crate::platform::macos::{OptionAsAlt, WindowExtMacOS}; use crate::window::{ @@ -677,9 +677,9 @@ impl WindowDelegate { app_state: &Rc, attrs: WindowAttributes, mtm: MainThreadMarker, - ) -> Result, RootOsError> { + ) -> Result, RequestError> { let window = new_window(app_state, &attrs, mtm) - .ok_or_else(|| os_error!(OsError::CreationError("couldn't create `NSWindow`")))?; + .ok_or_else(|| os_error!("couldn't create `NSWindow`"))?; #[cfg(feature = "rwh_06")] match attrs.parent_window.map(|handle| handle.0) { @@ -688,9 +688,9 @@ impl WindowDelegate { // Unwrap is fine, since the pointer comes from `NonNull`. let parent_view: Retained = unsafe { Retained::retain(handle.ns_view.as_ptr().cast()) }.unwrap(); - let parent = parent_view.window().ok_or_else(|| { - os_error!(OsError::CreationError("parent view should be installed in a window")) - })?; + let parent = parent_view + .window() + .ok_or_else(|| os_error!("parent view should be installed in a window"))?; // SAFETY: We know that there are no parent -> child -> parent cycles since the only // place in `winit` where we allow making a window a child window is @@ -925,15 +925,15 @@ impl WindowDelegate { #[inline] pub fn pre_present_notify(&self) {} - pub fn outer_position(&self) -> Result, NotSupportedError> { + pub fn outer_position(&self) -> PhysicalPosition { let position = flip_window_screen_coordinates(self.window().frame()); - Ok(LogicalPosition::new(position.x, position.y).to_physical(self.scale_factor())) + LogicalPosition::new(position.x, position.y).to_physical(self.scale_factor()) } - pub fn inner_position(&self) -> Result, NotSupportedError> { + pub fn inner_position(&self) -> PhysicalPosition { let content_rect = self.window().contentRectForFrameRect(self.window().frame()); let position = flip_window_screen_coordinates(content_rect); - Ok(LogicalPosition::new(position.x, position.y).to_physical(self.scale_factor())) + LogicalPosition::new(position.x, position.y).to_physical(self.scale_factor()) } pub fn set_outer_position(&self, position: Position) { @@ -1125,18 +1125,18 @@ impl WindowDelegate { } #[inline] - pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> { + pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { let associate_mouse_cursor = match mode { CursorGrabMode::Locked => false, CursorGrabMode::None => true, CursorGrabMode::Confined => { - return Err(ExternalError::NotSupported(NotSupportedError::new())) + return Err(NotSupportedError::new("confined cursor is not supported").into()) }, }; // TODO: Do this for real https://stackoverflow.com/a/40922095/5435443 CGDisplay::associate_mouse_and_mouse_cursor_position(associate_mouse_cursor) - .map_err(|status| ExternalError::Os(os_error!(OsError::CGError(status)))) + .map_err(|status| os_error!(format!("CGError {status}")).into()) } #[inline] @@ -1154,8 +1154,8 @@ impl WindowDelegate { } #[inline] - pub fn set_cursor_position(&self, cursor_position: Position) -> Result<(), ExternalError> { - let physical_window_position = self.inner_position().unwrap(); + pub fn set_cursor_position(&self, cursor_position: Position) -> Result<(), RequestError> { + let physical_window_position = self.inner_position(); let scale_factor = self.scale_factor(); let window_position = physical_window_position.to_logical::(scale_factor); let logical_cursor_position = cursor_position.to_logical::(scale_factor); @@ -1164,33 +1164,31 @@ impl WindowDelegate { y: logical_cursor_position.y + window_position.y, }; CGDisplay::warp_mouse_cursor_position(point) - .map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?; + .map_err(|status| os_error!(format!("CGError {status}")))?; CGDisplay::associate_mouse_and_mouse_cursor_position(true) - .map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?; + .map_err(|status| os_error!(format!("CGError {status}")))?; Ok(()) } #[inline] - pub fn drag_window(&self) -> Result<(), ExternalError> { + pub fn drag_window(&self) { let mtm = MainThreadMarker::from(self); let event = NSApplication::sharedApplication(mtm).currentEvent().unwrap(); self.window().performWindowDragWithEvent(&event); - Ok(()) } #[inline] - pub fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + pub fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), NotSupportedError> { + Err(NotSupportedError::new("drag_resize_window is not supported")) } #[inline] pub fn show_window_menu(&self, _position: Position) {} #[inline] - pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> { + pub fn set_cursor_hittest(&self, hittest: bool) { self.window().setIgnoresMouseEvents(!hittest); - Ok(()) } pub(crate) fn is_zoomed(&self) -> bool { diff --git a/src/platform_impl/apple/uikit/event_loop.rs b/src/platform_impl/apple/uikit/event_loop.rs index 2146262ba5..a3b31fde54 100644 --- a/src/platform_impl/apple/uikit/event_loop.rs +++ b/src/platform_impl/apple/uikit/event_loop.rs @@ -25,7 +25,7 @@ use super::super::notification_center::create_observer; use super::app_state::{send_occluded_event_for_all_windows, AppState, EventWrapper}; use super::{app_state, monitor, MonitorHandle}; use crate::application::ApplicationHandler; -use crate::error::{EventLoopError, ExternalError, NotSupportedError, OsError}; +use crate::error::{EventLoopError, NotSupportedError, RequestError}; use crate::event::Event; use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, @@ -49,15 +49,15 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_window( &self, window_attributes: crate::window::WindowAttributes, - ) -> Result, OsError> { + ) -> Result, RequestError> { Ok(Box::new(Window::new(self, window_attributes)?)) } fn create_custom_cursor( &self, _source: CustomCursorSource, - ) -> Result { - Err(ExternalError::NotSupported(NotSupportedError::new())) + ) -> Result { + Err(NotSupportedError::new("create_custom_cursor is not supported").into()) } fn available_monitors(&self) -> Box> { diff --git a/src/platform_impl/apple/uikit/window.rs b/src/platform_impl/apple/uikit/window.rs index 6e01947813..b4ca0bc721 100644 --- a/src/platform_impl/apple/uikit/window.rs +++ b/src/platform_impl/apple/uikit/window.rs @@ -20,7 +20,7 @@ use super::view_controller::WinitViewController; use super::{app_state, monitor, ActiveEventLoop, Fullscreen, MonitorHandle}; use crate::cursor::Cursor; use crate::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError}; +use crate::error::{NotSupportedError, RequestError}; use crate::event::{Event, WindowEvent}; use crate::icon::Icon; use crate::monitor::MonitorHandle as CoreMonitorHandle; @@ -159,20 +159,20 @@ impl Inner { pub fn pre_present_notify(&self) {} - pub fn inner_position(&self) -> Result, NotSupportedError> { + pub fn inner_position(&self) -> PhysicalPosition { let safe_area = self.safe_area_screen_space(); let position = LogicalPosition { x: safe_area.origin.x as f64, y: safe_area.origin.y as f64 }; let scale_factor = self.scale_factor(); - Ok(position.to_physical(scale_factor)) + position.to_physical(scale_factor) } - pub fn outer_position(&self) -> Result, NotSupportedError> { + pub fn outer_position(&self) -> PhysicalPosition { let screen_frame = self.screen_frame(); let position = LogicalPosition { x: screen_frame.origin.x as f64, y: screen_frame.origin.y as f64 }; let scale_factor = self.scale_factor(); - Ok(position.to_physical(scale_factor)) + position.to_physical(scale_factor) } pub fn set_outer_position(&self, physical_position: Position) { @@ -256,31 +256,31 @@ impl Inner { debug!("`Window::set_cursor` ignored on iOS") } - pub fn set_cursor_position(&self, _position: Position) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + pub fn set_cursor_position(&self, _position: Position) -> Result<(), NotSupportedError> { + Err(NotSupportedError::new("set_cursor_position is not supported")) } - pub fn set_cursor_grab(&self, _: CursorGrabMode) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + pub fn set_cursor_grab(&self, _: CursorGrabMode) -> Result<(), NotSupportedError> { + Err(NotSupportedError::new("set_cursor_grab is not supported")) } pub fn set_cursor_visible(&self, _visible: bool) { debug!("`Window::set_cursor_visible` is ignored on iOS") } - pub fn drag_window(&self) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + pub fn drag_window(&self) -> Result<(), NotSupportedError> { + Err(NotSupportedError::new("drag_window is not supported")) } - pub fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + pub fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), NotSupportedError> { + Err(NotSupportedError::new("drag_resize_window is not supported")) } #[inline] pub fn show_window_menu(&self, _position: Position) {} - pub fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + pub fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), NotSupportedError> { + Err(NotSupportedError::new("set_cursor_hittest is not supported")) } pub fn set_minimized(&self, _minimized: bool) { @@ -466,7 +466,7 @@ impl Window { pub(crate) fn new( event_loop: &ActiveEventLoop, window_attributes: WindowAttributes, - ) -> Result { + ) -> Result { let mtm = event_loop.mtm; if window_attributes.min_surface_size.is_some() { @@ -606,31 +606,27 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.reset_dead_keys()); } - fn inner_position( - &self, - ) -> Result, crate::error::NotSupportedError> { - self.maybe_wait_on_main(|delegate| delegate.inner_position()) + fn inner_position(&self) -> Result, RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.inner_position())) } - fn outer_position( - &self, - ) -> Result, crate::error::NotSupportedError> { - self.maybe_wait_on_main(|delegate| delegate.outer_position()) + fn outer_position(&self) -> Result, RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.outer_position())) } fn set_outer_position(&self, position: Position) { self.maybe_wait_on_main(|delegate| delegate.set_outer_position(position)); } - fn surface_size(&self) -> dpi::PhysicalSize { + fn surface_size(&self) -> PhysicalSize { self.maybe_wait_on_main(|delegate| delegate.surface_size()) } - fn request_surface_size(&self, size: Size) -> Option> { + fn request_surface_size(&self, size: Size) -> Option> { self.maybe_wait_on_main(|delegate| delegate.request_surface_size(size)) } - fn outer_size(&self) -> dpi::PhysicalSize { + fn outer_size(&self) -> PhysicalSize { self.maybe_wait_on_main(|delegate| delegate.outer_size()) } @@ -642,7 +638,7 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_max_surface_size(max_size)); } - fn surface_resize_increments(&self) -> Option> { + fn surface_resize_increments(&self) -> Option> { self.maybe_wait_on_main(|delegate| delegate.surface_resize_increments()) } @@ -770,38 +766,35 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor)); } - fn set_cursor_position(&self, position: Position) -> Result<(), crate::error::ExternalError> { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position)) + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position))?) } - fn set_cursor_grab( - &self, - mode: crate::window::CursorGrabMode, - ) -> Result<(), crate::error::ExternalError> { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode)) + fn set_cursor_grab(&self, mode: crate::window::CursorGrabMode) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode))?) } fn set_cursor_visible(&self, visible: bool) { self.maybe_wait_on_main(|delegate| delegate.set_cursor_visible(visible)) } - fn drag_window(&self) -> Result<(), crate::error::ExternalError> { - self.maybe_wait_on_main(|delegate| delegate.drag_window()) + fn drag_window(&self) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.drag_window())?) } fn drag_resize_window( &self, direction: crate::window::ResizeDirection, - ) -> Result<(), crate::error::ExternalError> { - self.maybe_wait_on_main(|delegate| delegate.drag_resize_window(direction)) + ) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.drag_resize_window(direction))?) } fn show_window_menu(&self, position: Position) { self.maybe_wait_on_main(|delegate| delegate.show_window_menu(position)) } - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), crate::error::ExternalError> { - self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest)) + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { + Ok(self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest))?) } fn current_monitor(&self) -> Option { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 0935d6e1ef..b715e40ac2 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -3,25 +3,24 @@ #[cfg(all(not(x11_platform), not(wayland_platform)))] compile_error!("Please select a feature to build for unix: `x11`, `wayland`"); +use std::env; use std::num::{NonZeroU16, NonZeroU32}; use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}; -use std::sync::Arc; use std::time::Duration; -use std::{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, sync::Mutex}; use smol_str::SmolStr; pub(crate) use self::common::xkb::{physicalkey_to_scancode, scancode_to_physicalkey}; #[cfg(x11_platform)] -use self::x11::{X11Error, XConnection, XError, XNotSupported}; +use self::x11::{XConnection, XError, XNotSupported}; use crate::application::ApplicationHandler; pub(crate) use crate::cursor::OnlyCursorImageSource as PlatformCustomCursorSource; #[cfg(x11_platform)] use crate::dpi::Size; use crate::dpi::{PhysicalPosition, PhysicalSize}; -use crate::error::EventLoopError; +use crate::error::{EventLoopError, NotSupportedError}; use crate::event_loop::ActiveEventLoop; pub(crate) use crate::icon::RgbaIcon as PlatformIcon; use crate::keyboard::Key; @@ -108,31 +107,6 @@ impl Default for PlatformSpecificWindowAttributes { pub(crate) static X11_BACKEND: Lazy, XNotSupported>>> = Lazy::new(|| Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))); -#[derive(Debug, Clone)] -pub enum OsError { - Misc(&'static str), - #[cfg(x11_platform)] - XNotSupported(XNotSupported), - #[cfg(x11_platform)] - XError(Arc), - #[cfg(wayland_platform)] - WaylandError(Arc), -} - -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::XNotSupported(ref e) => fmt::Display::fmt(e, _f), - #[cfg(x11_platform)] - OsError::XError(ref e) => fmt::Display::fmt(e, _f), - #[cfg(wayland_platform)] - OsError::WaylandError(ref e) => fmt::Display::fmt(e, _f), - } - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(u64); @@ -411,7 +385,7 @@ impl EventLoop { } else { "neither WAYLAND_DISPLAY nor WAYLAND_SOCKET nor DISPLAY is set." }; - return Err(EventLoopError::Os(os_error!(OsError::Misc(msg)))); + return Err(NotSupportedError::new(msg).into()); }, }; @@ -433,9 +407,7 @@ impl EventLoop { fn new_x11_any_thread() -> Result { let xconn = match X11_BACKEND.lock().unwrap_or_else(|e| e.into_inner()).as_ref() { Ok(xconn) => xconn.clone(), - Err(err) => { - return Err(EventLoopError::Os(os_error!(OsError::XNotSupported(err.clone())))) - }, + Err(err) => return Err(os_error!(err.clone()).into()), }; Ok(EventLoop::X(x11::EventLoop::new(xconn))) diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 8ccddf803c..1ba1667e8c 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -8,19 +8,18 @@ use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; -use sctk::reexports::calloop::Error as CalloopError; use sctk::reexports::calloop_wayland_source::WaylandSource; use sctk::reexports::client::{globals, Connection, QueueHandle}; use crate::application::ApplicationHandler; use crate::cursor::OnlyCursorImage; use crate::dpi::LogicalSize; -use crate::error::{EventLoopError, ExternalError, OsError as RootOsError}; +use crate::error::{EventLoopError, OsError, RequestError}; use crate::event::{Event, StartCause, SurfaceSizeWriter, WindowEvent}; use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents}; use crate::platform::pump_events::PumpStatus; use crate::platform_impl::platform::min_timeout; -use crate::platform_impl::{OsError, PlatformCustomCursor}; +use crate::platform_impl::PlatformCustomCursor; use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, Theme}; mod proxy; @@ -31,7 +30,7 @@ use sink::EventSink; use super::state::{WindowCompositorUpdate, WinitState}; use super::window::state::FrameCallbackState; -use super::{logical_to_physical_rounded, DeviceId, WaylandError, WindowId}; +use super::{logical_to_physical_rounded, DeviceId, WindowId}; type WaylandDispatcher = calloop::Dispatcher<'static, WaylandSource, WinitState>; @@ -61,27 +60,20 @@ pub struct EventLoop { impl EventLoop { pub fn new() -> Result { - macro_rules! map_err { - ($e:expr, $err:expr) => { - $e.map_err(|error| os_error!($err(error).into())) - }; - } - - let connection = map_err!(Connection::connect_to_env(), WaylandError::Connection)?; + let connection = Connection::connect_to_env().map_err(|err| os_error!(err))?; let (globals, mut event_queue) = - map_err!(globals::registry_queue_init(&connection), WaylandError::Global)?; + globals::registry_queue_init(&connection).map_err(|err| os_error!(err))?; let queue_handle = event_queue.handle(); let event_loop = - map_err!(calloop::EventLoop::::try_new(), WaylandError::Calloop)?; + calloop::EventLoop::::try_new().map_err(|err| os_error!(err))?; - 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).map_err(|err| os_error!(err))?; // Register Wayland source. let wayland_source = WaylandSource::new(connection.clone(), event_queue); @@ -97,37 +89,32 @@ impl EventLoop { result }); - map_err!( - event_loop.handle().register_dispatcher(wayland_dispatcher.clone()), - WaylandError::Calloop - )?; + event_loop + .handle() + .register_dispatcher(wayland_dispatcher.clone()) + .map_err(|err| os_error!(err))?; // Setup the user proxy. let (ping, ping_source) = calloop::ping::make_ping().unwrap(); - let result = event_loop + event_loop .handle() .insert_source(ping_source, move |_, _, winit_state: &mut WinitState| { winit_state.dispatched_events = true; winit_state.proxy_wake_up = true; }) - .map_err(|error| error.error); - map_err!(result, WaylandError::Calloop)?; + .map_err(|err| os_error!(err))?; // 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 - )?; + let (event_loop_awakener, event_loop_awakener_source) = + calloop::ping::make_ping().map_err(|err| os_error!(err))?; - let result = event_loop + event_loop .handle() .insert_source(event_loop_awakener_source, move |_, _, winit_state: &mut WinitState| { // Mark that we have something to dispatch. winit_state.dispatched_events = true; }) - .map_err(|error| error.error); - map_err!(result, WaylandError::Calloop)?; + .map_err(|err| os_error!(err))?; let active_event_loop = ActiveEventLoop { connection: connection.clone(), @@ -517,14 +504,12 @@ impl EventLoop { }) } - fn roundtrip(&mut self) -> Result { + fn roundtrip(&mut self) -> Result { let state = &mut self.active_event_loop.state.get_mut(); 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(|err| os_error!(err)) } fn control_flow(&self) -> ControlFlow { @@ -614,7 +599,7 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_custom_cursor( &self, cursor: CustomCursorSource, - ) -> Result { + ) -> Result { Ok(RootCustomCursor { inner: PlatformCustomCursor::Wayland(OnlyCursorImage(Arc::from(cursor.inner.0))), }) @@ -628,7 +613,7 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_window( &self, window_attributes: crate::window::WindowAttributes, - ) -> Result, RootOsError> { + ) -> Result, RequestError> { let window = crate::platform_impl::wayland::Window::new(self, window_attributes)?; Ok(Box::new(window)) } diff --git a/src/platform_impl/linux/wayland/mod.rs b/src/platform_impl/linux/wayland/mod.rs index 18de24277d..214b4a71d5 100644 --- a/src/platform_impl/linux/wayland/mod.rs +++ b/src/platform_impl/linux/wayland/mod.rs @@ -1,18 +1,14 @@ //! Winit's Wayland backend. -use std::fmt::Display; -use std::sync::Arc; - pub use event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy}; pub use output::{MonitorHandle, VideoModeHandle}; -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 window::Window; pub(super) use crate::cursor::OnlyCursorImage as CustomCursor; use crate::dpi::{LogicalSize, PhysicalSize}; -pub use crate::platform_impl::platform::{OsError, WindowId}; +pub use crate::platform_impl::platform::WindowId; mod event_loop; mod output; @@ -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 2b9f9fa8ff..bec0a55d3a 100644 --- a/src/platform_impl/linux/wayland/state.rs +++ b/src/platform_impl/linux/wayland/state.rs @@ -21,6 +21,7 @@ use sctk::shm::slot::SlotPool; use sctk::shm::{Shm, ShmHandler}; use sctk::subcompositor::SubcompositorState; +use crate::error::OsError; use crate::platform_impl::wayland::event_loop::sink::EventSink; use crate::platform_impl::wayland::output::MonitorHandle; use crate::platform_impl::wayland::seat::{ @@ -32,8 +33,7 @@ use crate::platform_impl::wayland::types::wp_fractional_scaling::FractionalScali use crate::platform_impl::wayland::types::wp_viewporter::ViewporterState; use crate::platform_impl::wayland::types::xdg_activation::XdgActivationState; use crate::platform_impl::wayland::window::{WindowRequests, WindowState}; -use crate::platform_impl::wayland::{WaylandError, WindowId}; -use crate::platform_impl::OsError; +use crate::platform_impl::wayland::WindowId; /// Winit's Wayland state. pub struct WinitState { @@ -126,7 +126,7 @@ impl WinitState { ) -> Result { let registry_state = RegistryState::new(globals); let compositor_state = - CompositorState::bind(globals, queue_handle).map_err(WaylandError::Bind)?; + CompositorState::bind(globals, queue_handle).map_err(|err| os_error!(err))?; let subcompositor_state = match SubcompositorState::bind( compositor_state.wl_compositor().clone(), globals, @@ -156,7 +156,7 @@ impl WinitState { (None, None) }; - let shm = Shm::bind(globals, queue_handle).map_err(WaylandError::Bind)?; + let shm = Shm::bind(globals, queue_handle).map_err(|err| os_error!(err))?; let custom_cursor_pool = Arc::new(Mutex::new(SlotPool::new(2, &shm).unwrap())); Ok(Self { @@ -168,7 +168,7 @@ impl WinitState { shm, custom_cursor_pool, - xdg_shell: XdgShell::bind(globals, queue_handle).map_err(WaylandError::Bind)?, + xdg_shell: XdgShell::bind(globals, queue_handle).map_err(|err| os_error!(err))?, 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 814061dd8f..42f37a0963 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -16,13 +16,13 @@ use super::event_loop::sink::EventSink; use super::output::MonitorHandle; use super::state::WinitState; use super::types::xdg_activation::XdgActivationTokenData; -use super::{ActiveEventLoop, WaylandError, WindowId}; +use super::{ActiveEventLoop, WindowId}; use crate::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError}; +use crate::error::{NotSupportedError, RequestError}; use crate::event::{Ime, WindowEvent}; use crate::event_loop::AsyncRequestSerial; use crate::monitor::MonitorHandle as CoreMonitorHandle; -use crate::platform_impl::{Fullscreen, MonitorHandle as PlatformMonitorHandle, OsError}; +use crate::platform_impl::{Fullscreen, MonitorHandle as PlatformMonitorHandle}; use crate::window::{ Cursor, CursorGrabMode, Fullscreen as CoreFullscreen, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons, @@ -77,7 +77,7 @@ impl Window { pub(crate) fn new( event_loop_window_target: &ActiveEventLoop, attributes: WindowAttributes, - ) -> Result { + ) -> Result { let queue_handle = event_loop_window_target.queue_handle.clone(); let mut state = event_loop_window_target.state.borrow_mut(); @@ -190,15 +190,11 @@ 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(|err| os_error!(err))?; // 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(|err| os_error!(err))?; } // Wake-up event loop, so it'll send initial redraw requested. @@ -223,10 +219,10 @@ impl Window { } impl Window { - pub fn request_activation_token(&self) -> Result { + pub fn request_activation_token(&self) -> Result { let xdg_activation = match self.xdg_activation.as_ref() { Some(xdg_activation) => xdg_activation, - None => return Err(NotSupportedError::new()), + None => return Err(NotSupportedError::new("xdg_activation_v1 is not available").into()), }; let serial = AsyncRequestSerial::get(); @@ -309,12 +305,14 @@ impl CoreWindow for Window { crate::platform_impl::common::xkb::reset_dead_keys() } - fn inner_position(&self) -> Result, NotSupportedError> { - Err(NotSupportedError::new()) + fn inner_position(&self) -> Result, RequestError> { + Err(NotSupportedError::new("window position information is not available on Wayland") + .into()) } - fn outer_position(&self) -> Result, NotSupportedError> { - Err(NotSupportedError::new()) + fn outer_position(&self) -> Result, RequestError> { + Err(NotSupportedError::new("window position information is not available on Wayland") + .into()) } fn set_outer_position(&self, _position: Position) { @@ -576,7 +574,7 @@ impl CoreWindow for Window { } } - fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> { + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { let scale_factor = self.scale_factor(); let position = position.to_logical(scale_factor); self.window_state @@ -587,7 +585,7 @@ impl CoreWindow for Window { .map(|_| self.request_redraw()) } - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> { + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { self.window_state.lock().unwrap().set_cursor_grab(mode) } @@ -595,11 +593,11 @@ impl CoreWindow for Window { self.window_state.lock().unwrap().set_cursor_visible(visible); } - fn drag_window(&self) -> Result<(), ExternalError> { + fn drag_window(&self) -> Result<(), RequestError> { self.window_state.lock().unwrap().drag_window() } - fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> { + fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError> { self.window_state.lock().unwrap().drag_resize_window(direction) } @@ -609,16 +607,14 @@ impl CoreWindow for Window { self.window_state.lock().unwrap().show_window_menu(position); } - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> { + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { let surface = self.window.wl_surface(); if hittest { surface.set_input_region(None); Ok(()) } else { - let region = Region::new(&*self.compositor).map_err(|_| { - ExternalError::Os(os_error!(OsError::Misc("failed to set input region."))) - })?; + let region = Region::new(&*self.compositor).map_err(|err| os_error!(err))?; region.add(0, 0, 0, 0); surface.set_input_region(Some(region.wl_region())); Ok(()) diff --git a/src/platform_impl/linux/wayland/window/state.rs b/src/platform_impl/linux/wayland/window/state.rs index 79c1766b60..e21e6e03d5 100644 --- a/src/platform_impl/linux/wayland/window/state.rs +++ b/src/platform_impl/linux/wayland/window/state.rs @@ -30,7 +30,7 @@ use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur; use crate::cursor::CustomCursor as RootCustomCursor; use crate::dpi::{LogicalPosition, LogicalSize, PhysicalSize, Size}; -use crate::error::{ExternalError, NotSupportedError}; +use crate::error::{NotSupportedError, RequestError}; use crate::platform_impl::wayland::logical_to_physical_rounded; use crate::platform_impl::wayland::seat::{ PointerConstraintsState, WinitPointerData, WinitPointerDataExt, ZwpTextInputV3Ext, @@ -388,7 +388,7 @@ impl WindowState { } /// Start interacting drag resize. - pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> { + pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError> { let xdg_toplevel = self.window.xdg_toplevel(); // TODO(kchibisov) handle touch serials. @@ -402,7 +402,7 @@ impl WindowState { } /// Start the window drag. - pub fn drag_window(&self) -> Result<(), ExternalError> { + pub fn drag_window(&self) -> Result<(), RequestError> { let xdg_toplevel = self.window.xdg_toplevel(); // TODO(kchibisov) handle touch serials. self.apply_on_pointer(|_, data| { @@ -799,7 +799,7 @@ impl WindowState { } /// Set the cursor grabbing state on the top-level. - pub fn set_cursor_grab(&mut self, mode: CursorGrabMode) -> Result<(), ExternalError> { + pub fn set_cursor_grab(&mut self, mode: CursorGrabMode) -> Result<(), RequestError> { if self.cursor_grab_mode.user_grab_mode == mode { return Ok(()); } @@ -817,11 +817,15 @@ impl WindowState { } /// Set the grabbing state on the surface. - fn set_cursor_grab_inner(&mut self, mode: CursorGrabMode) -> Result<(), ExternalError> { + fn set_cursor_grab_inner(&mut self, mode: CursorGrabMode) -> Result<(), RequestError> { let pointer_constraints = match self.pointer_constraints.as_ref() { Some(pointer_constraints) => pointer_constraints, None if mode == CursorGrabMode::None => return Ok(()), - None => return Err(ExternalError::NotSupported(NotSupportedError::new())), + None => { + return Err( + NotSupportedError::new("zwp_pointer_constraints is not available").into() + ) + }, }; // Replace the current mode. @@ -865,16 +869,17 @@ impl WindowState { } /// Set the position of the cursor. - pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> { + pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), RequestError> { if self.pointer_constraints.is_none() { - return Err(ExternalError::NotSupported(NotSupportedError::new())); + return Err(NotSupportedError::new("zwp_pointer_constraints is not available").into()); } // Position 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( - "cursor position can be set only for locked cursor." - )))); + return Err(NotSupportedError::new( + "cursor position could only be changed for locked pointer", + ) + .into()); } self.apply_on_pointer(|_, data| { diff --git a/src/platform_impl/linux/x11/ime/context.rs b/src/platform_impl/linux/x11/ime/context.rs index 2ffaa9a32c..bb1ef64240 100644 --- a/src/platform_impl/linux/x11/ime/context.rs +++ b/src/platform_impl/linux/x11/ime/context.rs @@ -1,7 +1,8 @@ +use std::error::Error; use std::ffi::CStr; use std::os::raw::c_short; use std::sync::Arc; -use std::{mem, ptr}; +use std::{fmt, mem, ptr}; use x11_dl::xlib::{XIMCallback, XIMPreeditCaretCallbackStruct, XIMPreeditDrawCallbackStruct}; @@ -19,6 +20,19 @@ pub enum ImeContextCreationError { Null, } +impl fmt::Display for ImeContextCreationError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ImeContextCreationError::XError(err) => err.fmt(f), + ImeContextCreationError::Null => { + write!(f, "got null pointer from Xlib without exact reason") + }, + } + } +} + +impl Error for ImeContextCreationError {} + /// The callback used by XIM preedit functions. type XIMProcNonnull = unsafe extern "C" fn(ffi::XIM, ffi::XPointer, ffi::XPointer); diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index b156d7d437..cada63f42e 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -23,7 +23,7 @@ use x11rb::x11_utils::X11Error as LogicalError; use x11rb::xcb_ffi::ReplyOrIdError; use crate::application::ApplicationHandler; -use crate::error::{EventLoopError, ExternalError, OsError as RootOsError}; +use crate::error::{EventLoopError, RequestError}; use crate::event::{Event, StartCause, WindowEvent}; use crate::event_loop::{ ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, @@ -33,7 +33,7 @@ use crate::platform::pump_events::PumpStatus; use crate::platform_impl::common::xkb::Context; use crate::platform_impl::platform::{min_timeout, WindowId}; use crate::platform_impl::x11::window::Window; -use crate::platform_impl::{OsError, OwnedDisplayHandle, PlatformCustomCursor}; +use crate::platform_impl::{OwnedDisplayHandle, PlatformCustomCursor}; use crate::window::{ CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as CoreWindow, WindowAttributes, @@ -399,9 +399,11 @@ impl EventLoop { // `run_on_demand` calls but if they have only just dropped their // windows we need to make sure those last requests are sent to the // X Server. - self.event_processor.target.x_connection().sync_with_server().map_err(|x_err| { - EventLoopError::Os(os_error!(OsError::XError(Arc::new(X11Error::Xlib(x_err))))) - })?; + self.event_processor + .target + .x_connection() + .sync_with_server() + .map_err(|x_err| EventLoopError::Os(os_error!(X11Error::Xlib(x_err))))?; exit } @@ -688,14 +690,14 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_window( &self, window_attributes: WindowAttributes, - ) -> Result, RootOsError> { + ) -> Result, RequestError> { Ok(Box::new(Window::new(self, window_attributes)?)) } fn create_custom_cursor( &self, custom_cursor: CustomCursorSource, - ) -> Result { + ) -> Result { Ok(RootCustomCursor { inner: PlatformCustomCursor::X(CustomCursor::new(self, custom_cursor.inner)?), }) diff --git a/src/platform_impl/linux/x11/util/cursor.rs b/src/platform_impl/linux/x11/util/cursor.rs index 36e35ccdb8..bd4adace6b 100644 --- a/src/platform_impl/linux/x11/util/cursor.rs +++ b/src/platform_impl/linux/x11/util/cursor.rs @@ -9,8 +9,8 @@ use x11rb::protocol::xproto; use super::super::ActiveEventLoop; use super::*; -use crate::error::ExternalError; -use crate::platform_impl::{OsError, PlatformCustomCursorSource}; +use crate::error::RequestError; +use crate::platform_impl::PlatformCustomCursorSource; use crate::window::CursorIcon; impl XConnection { @@ -193,7 +193,7 @@ impl CustomCursor { pub(crate) fn new( event_loop: &ActiveEventLoop, mut cursor: PlatformCustomCursorSource, - ) -> Result { + ) -> Result { // Reverse RGBA order to BGRA. cursor.0.rgba.chunks_mut(4).for_each(|chunk| { let chunk: &mut [u8; 4] = chunk.try_into().unwrap(); @@ -215,7 +215,7 @@ impl CustomCursor { cursor.0.hotspot_y, &cursor.0.rgba, ) - .map_err(|err| ExternalError::Os(os_error!(OsError::XError(err.into()))))?; + .map_err(|err| os_error!(err))?; Ok(Self { inner: Arc::new(CustomCursorInner { xconn: event_loop.xconn.clone(), cursor }) }) } diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index c56e5f7080..ac5a0bc0d9 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -22,7 +22,7 @@ use super::{ }; use crate::cursor::{Cursor, CustomCursor as RootCustomCursor}; use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError}; +use crate::error::{NotSupportedError, RequestError}; use crate::event::{Event, SurfaceSizeWriter, WindowEvent}; use crate::event_loop::AsyncRequestSerial; use crate::platform::x11::WindowType; @@ -31,8 +31,8 @@ use crate::platform_impl::x11::{ xinput_fp1616_to_float, MonitorHandle as X11MonitorHandle, WakeSender, X11Error, }; use crate::platform_impl::{ - common, Fullscreen, MonitorHandle as PlatformMonitorHandle, OsError, PlatformCustomCursor, - PlatformIcon, VideoModeHandle as PlatformVideoModeHandle, + common, Fullscreen, MonitorHandle as PlatformMonitorHandle, PlatformCustomCursor, PlatformIcon, + VideoModeHandle as PlatformVideoModeHandle, }; use crate::window::{ CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow, @@ -54,7 +54,7 @@ impl Window { pub(crate) fn new( event_loop: &ActiveEventLoop, attribs: WindowAttributes, - ) -> Result { + ) -> Result { let window = Arc::new(UnownedWindow::new(event_loop, attribs)?); event_loop.windows.borrow_mut().insert(window.id(), Arc::downgrade(&window)); Ok(Window(window)) @@ -82,11 +82,11 @@ impl CoreWindow for Window { common::xkb::reset_dead_keys(); } - fn inner_position(&self) -> Result, NotSupportedError> { + fn inner_position(&self) -> Result, RequestError> { self.0.inner_position() } - fn outer_position(&self) -> Result, NotSupportedError> { + fn outer_position(&self) -> Result, RequestError> { self.0.outer_position() } @@ -242,11 +242,11 @@ impl CoreWindow for Window { self.0.set_cursor(cursor); } - fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> { + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { self.0.set_cursor_position(position) } - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> { + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { self.0.set_cursor_grab(mode) } @@ -254,11 +254,11 @@ impl CoreWindow for Window { self.0.set_cursor_visible(visible); } - fn drag_window(&self) -> Result<(), ExternalError> { + fn drag_window(&self) -> Result<(), RequestError> { self.0.drag_window() } - fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> { + fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError> { self.0.drag_resize_window(direction) } @@ -266,7 +266,7 @@ impl CoreWindow for Window { self.0.show_window_menu(position); } - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> { + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { self.0.set_cursor_hittest(hittest) } @@ -427,13 +427,9 @@ pub struct UnownedWindow { redraw_sender: WakeSender, activation_sender: WakeSender, } - macro_rules! leap { ($e:expr) => { - match $e { - Ok(x) => x, - Err(err) => return Err(os_error!(OsError::XError(X11Error::from(err).into()))), - } + $e.map_err(|err| os_error!(err))? }; } @@ -442,7 +438,7 @@ impl UnownedWindow { pub(crate) fn new( event_loop: &ActiveEventLoop, window_attrs: WindowAttributes, - ) -> Result { + ) -> Result { let xconn = &event_loop.xconn; let atoms = xconn.atoms(); #[cfg(feature = "rwh_06")] @@ -527,10 +523,9 @@ impl UnownedWindow { match window_attrs.platform_specific.x11.visual_id { Some(vi) => { // Find this specific visual. - let (visualtype, depth) = - all_visuals.find(|(visual, _)| visual.visual_id == vi).ok_or_else( - || os_error!(OsError::XError(X11Error::NoSuchVisual(vi).into())), - )?; + let (visualtype, depth) = all_visuals + .find(|(visual, _)| visual.visual_id == vi) + .ok_or_else(|| os_error!(X11Error::NoSuchVisual(vi)))?; (Some(visualtype), depth, true) }, @@ -828,7 +823,7 @@ impl UnownedWindow { &mut supported_ptr, ); if supported_ptr == ffi::False { - return Err(os_error!(OsError::Misc("`XkbSetDetectableAutoRepeat` failed"))); + return Err(os_error!("`XkbSetDetectableAutoRepeat` failed").into()); } } @@ -848,14 +843,16 @@ impl UnownedWindow { // Try to create input context for the window. if let Some(ime) = event_loop.ime.as_ref() { - let result = ime.borrow_mut().create_context(window.xwindow as ffi::Window, false); - leap!(result); + ime.borrow_mut() + .create_context(window.xwindow as ffi::Window, false) + .map_err(|err| os_error!(err))?; } // These properties must be set after mapping if window_attrs.maximized { leap!(window.set_maximized_inner(window_attrs.maximized)).ignore_error(); } + if window_attrs.fullscreen.is_some() { if let Some(flusher) = leap!(window @@ -888,7 +885,7 @@ impl UnownedWindow { } /// Embed this window into a parent window. - pub(super) fn embed_window(&self) -> Result<(), RootOsError> { + pub(super) fn embed_window(&self) -> Result<(), RequestError> { let atoms = self.xconn.atoms(); leap!(leap!(self.xconn.change_property( self.xwindow, @@ -1500,7 +1497,7 @@ impl UnownedWindow { } #[inline] - pub fn outer_position(&self) -> Result, NotSupportedError> { + pub fn outer_position(&self) -> Result, RequestError> { let extents = self.shared_state_lock().frame_extents.clone(); if let Some(extents) = extents { let (x, y) = self.inner_position_physical(); @@ -1521,7 +1518,7 @@ impl UnownedWindow { } #[inline] - pub fn inner_position(&self) -> Result, NotSupportedError> { + pub fn inner_position(&self) -> Result, RequestError> { Ok(self.inner_position_physical().into()) } @@ -1815,7 +1812,7 @@ impl UnownedWindow { } #[inline] - pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> { + pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { let mut grabbed_lock = self.cursor_grabbed_mode.lock().unwrap(); if mode == *grabbed_lock { return Ok(()); @@ -1829,9 +1826,10 @@ impl UnownedWindow { .expect_then_ignore_error("Failed to call `xcb_ungrab_pointer`"); let result = match mode { - CursorGrabMode::None => self.xconn.flush_requests().map_err(|err| { - ExternalError::Os(os_error!(OsError::XError(X11Error::Xlib(err).into()))) - }), + CursorGrabMode::None => self + .xconn + .flush_requests() + .map_err(|err| RequestError::Os(os_error!(X11Error::Xlib(err)))), CursorGrabMode::Confined => { let result = { self.xconn @@ -1878,10 +1876,12 @@ impl UnownedWindow { }, _ => unreachable!(), } - .map_err(|err| ExternalError::Os(os_error!(OsError::Misc(err)))) + .map_err(|err| RequestError::Os(os_error!(err))) }, CursorGrabMode::Locked => { - return Err(ExternalError::NotSupported(NotSupportedError::new())); + return Err( + NotSupportedError::new("locked cursor is not implemented on X11").into() + ); }, }; @@ -1923,28 +1923,23 @@ impl UnownedWindow { self.shared_state_lock().last_monitor.scale_factor } - pub fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), ExternalError> { - { - self.xconn - .xcb_connection() - .warp_pointer(x11rb::NONE, self.xwindow, 0, 0, 0, 0, x as _, y as _) - .map_err(|e| { - ExternalError::Os(os_error!(OsError::XError(X11Error::from(e).into()))) - })?; - self.xconn.flush_requests().map_err(|e| { - ExternalError::Os(os_error!(OsError::XError(X11Error::Xlib(e).into()))) - }) - } + pub fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), RequestError> { + self.xconn + .xcb_connection() + .warp_pointer(x11rb::NONE, self.xwindow, 0, 0, 0, 0, x as _, y as _) + .map_err(|err| os_error!(X11Error::from(err)))?; + self.xconn.flush_requests().map_err(|err| os_error!(X11Error::Xlib(err)))?; + Ok(()) } #[inline] - pub fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> { + pub fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { let (x, y) = position.to_physical::(self.scale_factor()).into(); self.set_cursor_position_physical(x, y) } #[inline] - pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> { + pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { let mut rectangles: Vec = Vec::new(); if hittest { let size = self.surface_size(); @@ -1956,17 +1951,17 @@ impl UnownedWindow { }) } let region = RegionWrapper::create_region(self.xconn.xcb_connection(), &rectangles) - .map_err(|_e| ExternalError::Ignored)?; + .map_err(|_e| RequestError::Ignored)?; self.xconn .xcb_connection() .xfixes_set_window_shape_region(self.xwindow, SK::INPUT, 0, 0, region.region()) - .map_err(|_e| ExternalError::Ignored)?; + .map_err(|_e| RequestError::Ignored)?; self.shared_state_lock().cursor_hittest = Some(hittest); Ok(()) } /// Moves the window while it is being dragged. - pub fn drag_window(&self) -> Result<(), ExternalError> { + pub fn drag_window(&self) -> Result<(), RequestError> { self.drag_initiate(util::MOVERESIZE_MOVE) } @@ -1974,7 +1969,7 @@ impl UnownedWindow { pub fn show_window_menu(&self, _position: Position) {} /// Resizes the window while it is being dragged. - pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> { + pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError> { self.drag_initiate(match direction { ResizeDirection::East => util::MOVERESIZE_RIGHT, ResizeDirection::North => util::MOVERESIZE_TOP, @@ -1988,13 +1983,13 @@ impl UnownedWindow { } /// Initiates a drag operation while the left mouse button is pressed. - fn drag_initiate(&self, action: isize) -> Result<(), ExternalError> { + fn drag_initiate(&self, action: isize) -> Result<(), RequestError> { let pointer = self .xconn .query_pointer(self.xwindow, util::VIRTUAL_CORE_POINTER) - .map_err(|err| ExternalError::Os(os_error!(OsError::XError(err.into()))))?; + .map_err(|err| os_error!(err))?; - let window = self.inner_position().map_err(ExternalError::NotSupported)?; + let window_position = self.inner_position()?; let atoms = self.xconn.atoms(); let message = atoms[_NET_WM_MOVERESIZE]; @@ -2005,13 +2000,9 @@ impl UnownedWindow { self.xconn .xcb_connection() .ungrab_pointer(x11rb::CURRENT_TIME) - .map_err(|err| { - ExternalError::Os(os_error!(OsError::XError(X11Error::from(err).into()))) - })? + .map_err(|err| os_error!(X11Error::from(err)))? .ignore_error(); - self.xconn.flush_requests().map_err(|err| { - ExternalError::Os(os_error!(OsError::XError(X11Error::Xlib(err).into()))) - })?; + self.xconn.flush_requests().map_err(|err| os_error!(X11Error::Xlib(err)))?; *grabbed_lock = CursorGrabMode::None; // we keep the lock until we are done @@ -2025,18 +2016,18 @@ impl UnownedWindow { | xproto::EventMask::SUBSTRUCTURE_NOTIFY, ), [ - (window.x + xinput_fp1616_to_float(pointer.win_x) as i32) as u32, - (window.y + xinput_fp1616_to_float(pointer.win_y) as i32) as u32, + (window_position.x + xinput_fp1616_to_float(pointer.win_x) as i32) as u32, + (window_position.y + xinput_fp1616_to_float(pointer.win_y) as i32) as u32, action.try_into().unwrap(), 1, // Button 1 1, ], ) - .map_err(|err| ExternalError::Os(os_error!(OsError::XError(err.into()))))?; + .map_err(|err| os_error!(err))?; - self.xconn.flush_requests().map_err(|err| { - ExternalError::Os(os_error!(OsError::XError(X11Error::Xlib(err).into()))) - }) + self.xconn.flush_requests().map_err(|err| os_error!(X11Error::Xlib(err)))?; + + Ok(()) } #[inline] @@ -2135,7 +2126,7 @@ impl UnownedWindow { } #[inline] - pub fn request_activation_token(&self) -> Result { + pub fn request_activation_token(&self) -> Result { let serial = AsyncRequestSerial::get(); self.activation_sender.send((self.id(), serial)); Ok(serial) diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index 11a44f05b6..c40914c906 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -12,11 +12,11 @@ use orbclient::{ use smol_str::SmolStr; use super::{ - DeviceId, KeyEventExtra, MonitorHandle, OsError, PlatformSpecificEventLoopAttributes, - RedoxSocket, TimeSocket, WindowId, WindowProperties, + DeviceId, KeyEventExtra, MonitorHandle, PlatformSpecificEventLoopAttributes, RedoxSocket, + TimeSocket, WindowId, WindowProperties, }; use crate::application::ApplicationHandler; -use crate::error::{EventLoopError, ExternalError, NotSupportedError}; +use crate::error::{EventLoopError, NotSupportedError, RequestError}; use crate::event::{self, Ime, Modifiers, StartCause}; use crate::event_loop::{self, ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents}; use crate::keyboard::{ @@ -284,17 +284,11 @@ impl EventLoop { // events. let (user_events_sender, user_events_receiver) = mpsc::sync_channel(1); - 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().map_err(|error| os_error!(format!("{error}")))?); - 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().map_err(|error| os_error!(format!("{error}")))?); event_socket .write(&syscall::Event { @@ -302,8 +296,7 @@ impl EventLoop { flags: syscall::EventFlags::EVENT_READ, data: wake_socket.0.fd, }) - .map_err(OsError::new) - .map_err(|error| EventLoopError::Os(os_error!(error)))?; + .map_err(|error| os_error!(format!("{error}")))?; Ok(Self { windows: Vec::new(), @@ -731,15 +724,15 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_window( &self, window_attributes: crate::window::WindowAttributes, - ) -> Result, crate::error::OsError> { + ) -> Result, RequestError> { Ok(Box::new(Window::new(self, window_attributes)?)) } fn create_custom_cursor( &self, _: CustomCursorSource, - ) -> Result { - Err(ExternalError::NotSupported(NotSupportedError::new())) + ) -> Result { + Err(NotSupportedError::new("create_custom_cursor is not supported").into()) } fn available_monitors(&self) -> Box> { diff --git a/src/platform_impl/orbital/mod.rs b/src/platform_impl/orbital/mod.rs index 4ba0923cc6..f125b6e51d 100644 --- a/src/platform_impl/orbital/mod.rs +++ b/src/platform_impl/orbital/mod.rs @@ -1,9 +1,7 @@ #![cfg(target_os = "redox")] -use std::fmt::{self, Display, Formatter}; use std::num::{NonZeroU16, NonZeroU32}; -use std::str; -use std::sync::Arc; +use std::{fmt, str}; use smol_str::SmolStr; @@ -15,6 +13,11 @@ mod event_loop; pub use self::window::Window; mod window; +pub(crate) use crate::cursor::{ + NoCustomCursor as PlatformCustomCursor, NoCustomCursor as PlatformCustomCursorSource, +}; +pub(crate) use crate::icon::NoIcon as PlatformIcon; + struct RedoxSocket { fd: usize, } @@ -173,26 +176,6 @@ 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)) - } -} - -impl Display for OsError { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> { - self.0.fmt(fmt) - } -} - -pub(crate) use crate::cursor::{ - NoCustomCursor as PlatformCustomCursor, NoCustomCursor as PlatformCustomCursorSource, -}; -pub(crate) use crate::icon::NoIcon as PlatformIcon; - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct MonitorHandle; diff --git a/src/platform_impl/orbital/window.rs b/src/platform_impl/orbital/window.rs index c23cd88efa..25f011fa11 100644 --- a/src/platform_impl/orbital/window.rs +++ b/src/platform_impl/orbital/window.rs @@ -1,12 +1,10 @@ use std::collections::VecDeque; use std::sync::{Arc, Mutex}; -use super::{ - ActiveEventLoop, MonitorHandle, OsError, RedoxSocket, TimeSocket, WindowId, WindowProperties, -}; +use super::{ActiveEventLoop, MonitorHandle, RedoxSocket, TimeSocket, WindowId, WindowProperties}; use crate::cursor::Cursor; use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error; +use crate::error::{NotSupportedError, RequestError}; use crate::monitor::MonitorHandle as CoreMonitorHandle; use crate::window::{self, Fullscreen, ImePurpose, Window as CoreWindow, WindowId as CoreWindowId}; @@ -32,7 +30,7 @@ impl Window { pub(crate) fn new( el: &ActiveEventLoop, attrs: window::WindowAttributes, - ) -> Result { + ) -> Result { let scale = MonitorHandle.scale_factor(); let (x, y) = if let Some(pos) = attrs.position { @@ -125,20 +123,17 @@ impl Window { }) } - fn get_flag(&self, flag: char) -> Result { + fn get_flag(&self, flag: char) -> Result { let mut buf: [u8; 4096] = [0; 4096]; - let path = self - .window_socket - .fpath(&mut buf) - .map_err(|err| error::ExternalError::Os(os_error!(OsError::new(err))))?; + let path = self.window_socket.fpath(&mut buf).map_err(|err| os_error!(format!("{err}")))?; let properties = WindowProperties::new(path); Ok(properties.flags.contains(flag)) } - fn set_flag(&self, flag: char, value: bool) -> Result<(), error::ExternalError> { + fn set_flag(&self, flag: char, value: bool) -> Result<(), RequestError> { self.window_socket .write(format!("F,{flag},{}", if value { 1 } else { 0 }).as_bytes()) - .map_err(|err| error::ExternalError::Os(os_error!(OsError::new(err))))?; + .map_err(|err| os_error!(format!("{err}")))?; Ok(()) } @@ -204,7 +199,7 @@ impl CoreWindow for Window { } #[inline] - fn inner_position(&self) -> Result, error::NotSupportedError> { + fn inner_position(&self) -> Result, RequestError> { let mut buf: [u8; 4096] = [0; 4096]; let path = self.window_socket.fpath(&mut buf).expect("failed to read properties"); let properties = WindowProperties::new(path); @@ -212,7 +207,7 @@ impl CoreWindow for Window { } #[inline] - fn outer_position(&self) -> Result, error::NotSupportedError> { + fn outer_position(&self) -> Result, RequestError> { // TODO: adjust for window decorations self.inner_position() } @@ -372,12 +367,12 @@ impl CoreWindow for Window { fn set_cursor(&self, _: Cursor) {} #[inline] - fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> { - Err(error::ExternalError::NotSupported(error::NotSupportedError::new())) + fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_position is not supported").into()) } #[inline] - fn set_cursor_grab(&self, mode: window::CursorGrabMode) -> Result<(), error::ExternalError> { + fn set_cursor_grab(&self, mode: window::CursorGrabMode) -> Result<(), RequestError> { let (grab, relative) = match mode { window::CursorGrabMode::None => (false, false), window::CursorGrabMode::Confined => (true, false), @@ -385,10 +380,10 @@ impl CoreWindow for Window { }; self.window_socket .write(format!("M,G,{}", if grab { 1 } else { 0 }).as_bytes()) - .map_err(|err| error::ExternalError::Os(os_error!(OsError::new(err))))?; + .map_err(|err| os_error!(format!("{err}")))?; self.window_socket .write(format!("M,R,{}", if relative { 1 } else { 0 }).as_bytes()) - .map_err(|err| error::ExternalError::Os(os_error!(OsError::new(err))))?; + .map_err(|err| os_error!(format!("{err}")))?; Ok(()) } @@ -398,18 +393,13 @@ impl CoreWindow for Window { } #[inline] - fn drag_window(&self) -> Result<(), error::ExternalError> { - self.window_socket - .write(b"D") - .map_err(|err| error::ExternalError::Os(os_error!(OsError::new(err))))?; + fn drag_window(&self) -> Result<(), RequestError> { + self.window_socket.write(b"D").map_err(|err| os_error!(format!("{err}")))?; Ok(()) } #[inline] - fn drag_resize_window( - &self, - direction: window::ResizeDirection, - ) -> Result<(), error::ExternalError> { + fn drag_resize_window(&self, direction: window::ResizeDirection) -> Result<(), RequestError> { let arg = match direction { window::ResizeDirection::East => "R", window::ResizeDirection::North => "T", @@ -422,7 +412,7 @@ impl CoreWindow for Window { }; self.window_socket .write(format!("D,{}", arg).as_bytes()) - .map_err(|err| error::ExternalError::Os(os_error!(OsError::new(err))))?; + .map_err(|err| os_error!(format!("{err}")))?; Ok(()) } @@ -430,8 +420,8 @@ impl CoreWindow for Window { fn show_window_menu(&self, _position: Position) {} #[inline] - fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), error::ExternalError> { - Err(error::ExternalError::NotSupported(error::NotSupportedError::new())) + fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) } #[inline] diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index 50417b3aef..7b4f63da52 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -11,7 +11,7 @@ use super::event::DeviceId; use super::runner::{EventWrapper, WeakShared}; use super::window::WindowId; use super::{backend, runner, EventLoopProxy}; -use crate::error::{ExternalError, NotSupportedError}; +use crate::error::{NotSupportedError, RequestError}; use crate::event::{ DeviceId as RootDeviceId, ElementState, Event, FingerId as RootFingerId, KeyEvent, Touch, TouchPhase, WindowEvent, @@ -606,7 +606,10 @@ impl ActiveEventLoop { } pub(crate) fn has_multiple_screens(&self) -> Result { - self.runner.monitor().is_extended().ok_or(NotSupportedError::new()) + self.runner + .monitor() + .is_extended() + .ok_or(NotSupportedError::new("has_multiple_screens is not supported")) } pub(crate) fn request_detailed_monitor_permission(&self) -> MonitorPermissionFuture { @@ -631,7 +634,7 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_window( &self, window_attributes: crate::window::WindowAttributes, - ) -> Result, crate::error::OsError> { + ) -> Result, RequestError> { let window = Window::new(self, window_attributes)?; Ok(Box::new(window)) } @@ -639,7 +642,7 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_custom_cursor( &self, source: CustomCursorSource, - ) -> Result { + ) -> Result { Ok(RootCustomCursor { inner: CustomCursor::new(self, source.inner) }) } diff --git a/src/platform_impl/web/mod.rs b/src/platform_impl/web/mod.rs index d429dd07a9..b99dd3cb90 100644 --- a/src/platform_impl/web/mod.rs +++ b/src/platform_impl/web/mod.rs @@ -37,7 +37,6 @@ pub(crate) use cursor::{ CustomCursorSource as PlatformCustomCursorSource, }; -pub use self::error::OsError; pub use self::event::{DeviceId, FingerId}; pub(crate) use self::event_loop::{ ActiveEventLoop, EventLoop, EventLoopProxy, OwnedDisplayHandle, diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index f5050f4875..a1e5096e00 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -22,10 +22,10 @@ use super::media_query_handle::MediaQueryListHandle; use super::pointer::PointerHandler; use super::{event, fullscreen, ButtonsState, ResizeScaleHandle}; use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize}; -use crate::error::OsError as RootOE; +use crate::error::RequestError; use crate::event::{Force, MouseButton, MouseScrollDelta, SurfaceSizeWriter}; use crate::keyboard::{Key, KeyLocation, ModifiersState, PhysicalKey}; -use crate::platform_impl::{Fullscreen, OsError}; +use crate::platform_impl::Fullscreen; use crate::window::{WindowAttributes, WindowId as RootWindowId}; #[allow(dead_code)] @@ -83,13 +83,13 @@ impl Canvas { navigator: Navigator, document: Document, attr: WindowAttributes, - ) -> Result { + ) -> Result { let canvas = match attr.platform_specific.canvas.map(Arc::try_unwrap) { Some(Ok(canvas)) => canvas.into_inner(main_thread), Some(Err(canvas)) => canvas.get(main_thread).clone(), None => document .create_element("canvas") - .map_err(|_| os_error!(OsError("Failed to create canvas element".to_owned())))? + .map_err(|_| os_error!("Failed to create canvas element"))? .unchecked_into(), }; @@ -109,7 +109,7 @@ impl Canvas { if attr.platform_specific.focusable { canvas .set_attribute("tabindex", "0") - .map_err(|_| os_error!(OsError("Failed to set a tabindex".to_owned())))?; + .map_err(|_| os_error!("Failed to set a tabindex"))?; } let style = Style::new(&window, &canvas); diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 239c58e9d5..d979310a6e 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -9,7 +9,7 @@ use super::monitor::MonitorHandler; use super::r#async::Dispatcher; use super::{backend, lock, ActiveEventLoop}; use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error::{ExternalError, NotSupportedError, OsError as RootOE}; +use crate::error::{NotSupportedError, RequestError}; use crate::icon::Icon; use crate::monitor::MonitorHandle as RootMonitorHandle; use crate::window::{ @@ -31,7 +31,10 @@ pub struct Inner { } impl Window { - pub(crate) fn new(target: &ActiveEventLoop, attr: WindowAttributes) -> Result { + pub(crate) fn new( + target: &ActiveEventLoop, + attr: WindowAttributes, + ) -> Result { let id = target.generate_id(); let window = target.runner.window(); @@ -106,13 +109,13 @@ impl RootWindow for Window { // Not supported } - fn inner_position(&self) -> Result, NotSupportedError> { + fn inner_position(&self) -> Result, RequestError> { // Note: the canvas element has no window decorations, so this is equal to `outer_position`. self.outer_position() } - fn outer_position(&self) -> Result, NotSupportedError> { - self.inner.queue(|inner| Ok(inner.canvas.position().to_physical(inner.scale_factor()))) + fn outer_position(&self) -> Result, RequestError> { + Ok(self.inner.queue(|inner| inner.canvas.position().to_physical(inner.scale_factor()))) } fn set_outer_position(&self, position: Position) { @@ -315,12 +318,12 @@ impl RootWindow for Window { self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor(cursor)) } - fn set_cursor_position(&self, _: Position) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_position is not supported").into()) } - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> { - self.inner.queue(|inner| { + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { + Ok(self.inner.queue(|inner| { match mode { CursorGrabMode::None => inner.canvas.document().exit_pointer_lock(), CursorGrabMode::Locked => lock::request_pointer_lock( @@ -329,30 +332,30 @@ impl RootWindow for Window { inner.canvas.raw(), ), CursorGrabMode::Confined => { - return Err(ExternalError::NotSupported(NotSupportedError::new())) + return Err(NotSupportedError::new("confined cursor mode is not supported")) }, } Ok(()) - }) + })?) } fn set_cursor_visible(&self, visible: bool) { self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor_visible(visible)) } - fn drag_window(&self) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + fn drag_window(&self) -> Result<(), RequestError> { + Err(NotSupportedError::new("drag_window is not supported").into()) } - fn drag_resize_window(&self, _: ResizeDirection) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + fn drag_resize_window(&self, _: ResizeDirection) -> Result<(), RequestError> { + Err(NotSupportedError::new("drag_resize_window is not supported").into()) } fn show_window_menu(&self, _: Position) {} - fn set_cursor_hittest(&self, _: bool) -> Result<(), ExternalError> { - Err(ExternalError::NotSupported(NotSupportedError::new())) + fn set_cursor_hittest(&self, _: bool) -> Result<(), RequestError> { + Err(NotSupportedError::new("set_cursor_hittest is not supported").into()) } fn current_monitor(&self) -> Option { diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index b63ece77d7..5c7a3e1a49 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -56,7 +56,7 @@ use super::window::set_skip_taskbar; use super::SelectedCursor; use crate::application::ApplicationHandler; use crate::dpi::{PhysicalPosition, PhysicalSize}; -use crate::error::{EventLoopError, ExternalError, OsError}; +use crate::error::{EventLoopError, RequestError}; use crate::event::{ Event, FingerId as RootFingerId, Force, Ime, RawKeyEvent, SurfaceSizeWriter, Touch, TouchPhase, WindowEvent, @@ -521,14 +521,14 @@ impl RootActiveEventLoop for ActiveEventLoop { fn create_window( &self, window_attributes: WindowAttributes, - ) -> Result, OsError> { + ) -> Result, RequestError> { Ok(Box::new(Window::new(self, window_attributes)?)) } fn create_custom_cursor( &self, source: CustomCursorSource, - ) -> Result { + ) -> Result { Ok(RootCustomCursor { inner: WinCursor::new(&source.inner.0)? }) } diff --git a/src/platform_impl/windows/icon.rs b/src/platform_impl/windows/icon.rs index b3e814becc..b5f43a676e 100644 --- a/src/platform_impl/windows/icon.rs +++ b/src/platform_impl/windows/icon.rs @@ -17,7 +17,7 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{ use super::util; use crate::cursor::CursorImage; use crate::dpi::PhysicalSize; -use crate::error::ExternalError; +use crate::error::RequestError; use crate::icon::*; impl Pixel { @@ -179,7 +179,7 @@ impl Default for SelectedCursor { pub struct WinCursor(pub(super) Arc); impl WinCursor { - pub(crate) fn new(image: &CursorImage) -> Result { + pub(crate) fn new(image: &CursorImage) -> Result { let mut bgra = image.rgba.clone(); bgra.chunks_exact_mut(4).for_each(|chunk| chunk.swap(0, 2)); @@ -189,16 +189,16 @@ impl WinCursor { unsafe { let hdc_screen = GetDC(0); if hdc_screen == 0 { - return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); + return Err(os_error!(io::Error::last_os_error()).into()); } let hbm_color = CreateCompatibleBitmap(hdc_screen, w, h); ReleaseDC(0, hdc_screen); if hbm_color == 0 { - return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); + return Err(os_error!(io::Error::last_os_error()).into()); } if SetBitmapBits(hbm_color, bgra.len() as u32, bgra.as_ptr() as *const c_void) == 0 { DeleteObject(hbm_color); - return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); + return Err(os_error!(io::Error::last_os_error()).into()); }; // Mask created according to https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createbitmap#parameters @@ -206,7 +206,7 @@ impl WinCursor { let hbm_mask = CreateBitmap(w, h, 1, 1, mask_bits.as_ptr() as *const _); if hbm_mask == 0 { DeleteObject(hbm_color); - return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); + return Err(os_error!(io::Error::last_os_error()).into()); } let icon_info = ICONINFO { @@ -221,7 +221,7 @@ impl WinCursor { DeleteObject(hbm_color); DeleteObject(hbm_mask); if handle == 0 { - return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); + return Err(os_error!(io::Error::last_os_error()).into()); } Ok(Self(Arc::new(RaiiCursor { handle }))) diff --git a/src/platform_impl/windows/mod.rs b/src/platform_impl/windows/mod.rs index 93349f7f14..92079ebbc1 100644 --- a/src/platform_impl/windows/mod.rs +++ b/src/platform_impl/windows/mod.rs @@ -103,8 +103,6 @@ fn wrap_device_id(id: u32) -> RootDeviceId { RootDeviceId(DeviceId(id)) } -pub type OsError = std::io::Error; - #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct KeyEventExtra { pub text_with_all_modifiers: Option, diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index c08cc436ae..db0dd9ba7c 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -47,7 +47,7 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{ use crate::cursor::Cursor; use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError}; +use crate::error::{NotSupportedError, RequestError}; use crate::icon::Icon; use crate::monitor::MonitorHandle as CoreMonitorHandle; use crate::platform::windows::{BackdropType, Color, CornerPreference}; @@ -89,7 +89,7 @@ impl Window { pub(crate) fn new( event_loop: &ActiveEventLoop, w_attr: WindowAttributes, - ) -> Result { + ) -> Result { // We dispatch an `init` function because of code style. // First person to remove the need for cloning here gets a cookie! // @@ -411,7 +411,7 @@ impl CoreWindow for Window { fn pre_present_notify(&self) {} - fn outer_position(&self) -> Result, NotSupportedError> { + fn outer_position(&self) -> Result, RequestError> { util::WindowArea::Outer .get_rect(self.hwnd()) .map(|rect| Ok(PhysicalPosition::new(rect.left, rect.top))) @@ -421,7 +421,7 @@ impl CoreWindow for Window { ) } - fn inner_position(&self) -> Result, NotSupportedError> { + fn inner_position(&self) -> Result, RequestError> { let mut position: POINT = unsafe { mem::zeroed() }; if unsafe { ClientToScreen(self.hwnd(), &mut position) } == false.into() { panic!( @@ -588,12 +588,12 @@ impl CoreWindow for Window { } } - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> { + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> { let confine = match mode { CursorGrabMode::None => false, CursorGrabMode::Confined => true, CursorGrabMode::Locked => { - return Err(ExternalError::NotSupported(NotSupportedError::new())) + return Err(NotSupportedError::new("locked cursor is not supported").into()) }, }; @@ -608,9 +608,10 @@ impl CoreWindow for Window { .unwrap() .mouse .set_cursor_flags(window, |f| f.set(CursorFlags::GRABBED, confine)) - .map_err(|e| ExternalError::Os(os_error!(e))); + .map_err(|err| os_error!(err).into()); let _ = tx.send(result); }); + rx.recv().unwrap() } @@ -636,23 +637,23 @@ impl CoreWindow for Window { self.window_state_lock().scale_factor } - fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> { + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> { let scale_factor = self.scale_factor(); let (x, y) = position.to_physical::(scale_factor).into(); let mut point = POINT { x, y }; unsafe { if ClientToScreen(self.hwnd(), &mut point) == false.into() { - return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); + return Err(os_error!(io::Error::last_os_error()).into()); } if SetCursorPos(point.x, point.y) == false.into() { - return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); + return Err(os_error!(io::Error::last_os_error()).into()); } } Ok(()) } - fn drag_window(&self) -> Result<(), ExternalError> { + fn drag_window(&self) -> Result<(), RequestError> { unsafe { self.handle_os_dragging(HTCAPTION as WPARAM); } @@ -660,7 +661,7 @@ impl CoreWindow for Window { Ok(()) } - fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> { + fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError> { unsafe { self.handle_os_dragging(match direction { ResizeDirection::East => HTRIGHT, @@ -683,7 +684,7 @@ impl CoreWindow for Window { } } - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> { + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> { let window = self.window; let window_state = Arc::clone(&self.window_state); self.thread_executor.execute_in_thread(move || { @@ -1249,7 +1250,7 @@ impl<'a> InitData<'a> { unsafe fn init( attributes: WindowAttributes, event_loop: &ActiveEventLoop, -) -> Result { +) -> Result { let title = util::encode_wide(&attributes.title); let class_name = util::encode_wide(&attributes.platform_specific.class_name); @@ -1332,7 +1333,7 @@ unsafe fn init( } if handle == 0 { - return Err(os_error!(io::Error::last_os_error())); + return Err(os_error!(io::Error::last_os_error()).into()); } // If the handle is non-null, then window creation must have succeeded, which means diff --git a/src/window.rs b/src/window.rs index 6a3dd62539..1ded68b146 100644 --- a/src/window.rs +++ b/src/window.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; pub use crate::cursor::{BadImage, Cursor, CustomCursor, CustomCursorSource, MAX_CURSOR_SIZE}; use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error::{ExternalError, NotSupportedError}; +use crate::error::RequestError; pub use crate::icon::{BadIcon, Icon}; use crate::monitor::{MonitorHandle, VideoModeHandle}; use crate::platform_impl::{self, PlatformSpecificWindowAttributes}; @@ -601,10 +601,10 @@ pub trait Window: AsAny + Send + Sync { /// coordinate system. /// - **Web:** Returns the top-left coordinates relative to the viewport. _Note: this returns /// the same value as [`Window::outer_position`]._ - /// - **Android / Wayland:** Always returns [`NotSupportedError`]. + /// - **Android / Wayland:** Always returns [`RequestError::NotSupported`]. /// /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc - fn inner_position(&self) -> Result, NotSupportedError>; + fn inner_position(&self) -> Result, RequestError>; /// Returns the position of the top-left hand corner of the window relative to the /// top-left hand corner of the desktop. @@ -621,8 +621,8 @@ pub trait Window: AsAny + Send + Sync { /// - **iOS:** Returns the top left coordinates of the window in the screen space coordinate /// system. /// - **Web:** Returns the top-left coordinates relative to the viewport. - /// - **Android / Wayland:** Always returns [`NotSupportedError`]. - fn outer_position(&self) -> Result, NotSupportedError>; + /// - **Android / Wayland:** Always returns [`RequestError::NotSupported`]. + fn outer_position(&self) -> Result, RequestError>; /// Modifies the position of the window. /// @@ -1160,8 +1160,8 @@ pub trait Window: AsAny + Send + Sync { /// ## Platform-specific /// /// - **Wayland**: Cursor must be in [`CursorGrabMode::Locked`]. - /// - **iOS / Android / Web / Orbital:** Always returns an [`ExternalError::NotSupported`]. - fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError>; + /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`]. + fn set_cursor_position(&self, position: Position) -> Result<(), RequestError>; /// Set grabbing [mode][CursorGrabMode] on the cursor preventing it from leaving the window. /// @@ -1178,7 +1178,7 @@ pub trait Window: AsAny + Send + Sync { /// .unwrap(); /// # } /// ``` - fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError>; + fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError>; /// Modifies the cursor's visibility. /// @@ -1204,8 +1204,8 @@ pub trait Window: AsAny + Send + Sync { /// - **X11:** Un-grabs the cursor. /// - **Wayland:** Requires the cursor to be inside the window to be dragged. /// - **macOS:** May prevent the button release event to be triggered. - /// - **iOS / Android / Web:** Always returns an [`ExternalError::NotSupported`]. - fn drag_window(&self) -> Result<(), ExternalError>; + /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`]. + fn drag_window(&self) -> Result<(), RequestError>; /// Resizes the window with the left mouse button until the button is released. /// @@ -1214,9 +1214,9 @@ pub trait Window: AsAny + Send + Sync { /// /// ## Platform-specific /// - /// - **macOS:** Always returns an [`ExternalError::NotSupported`] - /// - **iOS / Android / Web:** Always returns an [`ExternalError::NotSupported`]. - fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError>; + /// - **macOS:** Always returns an [`RequestError::NotSupported`] + /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`]. + fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), RequestError>; /// Show [window menu] at a specified position . /// @@ -1237,8 +1237,8 @@ pub trait Window: AsAny + Send + Sync { /// /// ## Platform-specific /// - /// - **iOS / Android / Web / Orbital:** Always returns an [`ExternalError::NotSupported`]. - fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError>; + /// - **iOS / Android / Web / Orbital:** Always returns an [`RequestError::NotSupported`]. + fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError>; /// Returns the monitor on which the window currently resides. /// @@ -1345,8 +1345,8 @@ pub enum CursorGrabMode { /// /// ## Platform-specific /// - /// - **macOS:** Not implemented. Always returns [`ExternalError::NotSupported`] for now. - /// - **iOS / Android / Web:** Always returns an [`ExternalError::NotSupported`]. + /// - **macOS:** Not implemented. Always returns [`RequestError::NotSupported`] for now. + /// - **iOS / Android / Web:** Always returns an [`RequestError::NotSupported`]. Confined, /// The cursor is locked inside the window area to the certain position. @@ -1356,9 +1356,9 @@ pub enum CursorGrabMode { /// /// ## Platform-specific /// - /// - **X11 / Windows:** Not implemented. Always returns [`ExternalError::NotSupported`] for + /// - **X11 / Windows:** Not implemented. Always returns [`RequestError::NotSupported`] for /// now. - /// - **iOS / Android:** Always returns an [`ExternalError::NotSupported`]. + /// - **iOS / Android:** Always returns an [`RequestError::NotSupported`]. Locked, }