From e0f2d1a112b630cc7a95299b0911d1ddac67135a Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 2 Aug 2024 11:13:42 +0200 Subject: [PATCH] Change `create_custom_cursor()` to return `Result` --- examples/window.rs | 46 ++++++++++++++----- src/changelog/unreleased.md | 1 + src/cursor.rs | 8 ++-- src/event_loop.rs | 20 ++++++-- src/platform_impl/android/mod.rs | 11 +++-- src/platform_impl/apple/appkit/cursor.rs | 14 +++--- src/platform_impl/apple/appkit/event_loop.rs | 9 ++-- src/platform_impl/apple/uikit/event_loop.rs | 10 ++-- src/platform_impl/linux/mod.rs | 5 +- .../linux/wayland/event_loop/mod.rs | 11 +++-- src/platform_impl/linux/x11/mod.rs | 11 +++-- src/platform_impl/linux/x11/util/cursor.rs | 13 ++++-- src/platform_impl/orbital/event_loop.rs | 10 ++-- .../web/event_loop/window_target.rs | 9 ++-- src/platform_impl/windows/event_loop.rs | 17 +++---- src/platform_impl/windows/icon.rs | 20 ++++---- src/platform_impl/windows/window.rs | 13 ++---- 17 files changed, 141 insertions(+), 87 deletions(-) diff --git a/examples/window.rs b/examples/window.rs index 577a32406a..0d5819d50f 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -17,6 +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::event::{DeviceEvent, DeviceId, Ime, MouseButton, MouseScrollDelta, WindowEvent}; use winit::event_loop::{ActiveEventLoop, EventLoop}; use winit::keyboard::{Key, ModifiersState}; @@ -75,7 +76,7 @@ struct Application { receiver: Receiver, sender: Sender, /// Custom cursors assets. - custom_cursors: Vec, + custom_cursors: Result, ExternalError>, /// Application icon. icon: Icon, windows: HashMap, @@ -107,11 +108,13 @@ impl Application { let icon = load_icon(include_bytes!("data/icon.png")); info!("Loading cursor assets"); - let custom_cursors = vec![ + let custom_cursors = [ event_loop.create_custom_cursor(decode_cursor(include_bytes!("data/cross.png"))), event_loop.create_custom_cursor(decode_cursor(include_bytes!("data/cross2.png"))), event_loop.create_custom_cursor(decode_cursor(include_bytes!("data/gradient.png"))), - ]; + ] + .into_iter() + .collect(); Self { receiver, @@ -217,12 +220,27 @@ impl Application { Action::ToggleImeInput => window.toggle_ime(), Action::Minimize => window.minimize(), Action::NextCursor => window.next_cursor(), - Action::NextCustomCursor => window.next_custom_cursor(&self.custom_cursors), + Action::NextCustomCursor => { + if let Err(err) = self.custom_cursors.as_ref().map(|c| window.next_custom_cursor(c)) + { + error!("Error creating custom cursor: {err}"); + } + }, #[cfg(web_platform)] - Action::UrlCustomCursor => window.url_custom_cursor(event_loop), + Action::UrlCustomCursor => { + if let Err(err) = window.url_custom_cursor(event_loop) { + error!("Error creating custom cursor from URL: {err}"); + } + }, #[cfg(web_platform)] Action::AnimationCustomCursor => { - window.animation_custom_cursor(event_loop, &self.custom_cursors) + if let Err(err) = self + .custom_cursors + .as_ref() + .map(|c| window.animation_custom_cursor(event_loop, c)) + { + error!("Error creating animated custom cursor: {err}"); + } }, Action::CycleCursorGrab => window.cycle_cursor_grab(), Action::DragWindow => window.drag_window(), @@ -589,7 +607,7 @@ impl WindowState { let mut state = Self { #[cfg(macos_platform)] option_as_alt: window.option_as_alt(), - custom_idx: app.custom_cursors.len() - 1, + custom_idx: app.custom_cursors.as_ref().map(Vec::len).unwrap_or(1) - 1, cursor_grab: CursorGrabMode::None, named_idx, #[cfg(not(any(android_platform, ios_platform)))] @@ -738,10 +756,12 @@ impl WindowState { /// Custom cursor from an URL. #[cfg(web_platform)] - fn url_custom_cursor(&mut self, event_loop: &ActiveEventLoop) { - let cursor = event_loop.create_custom_cursor(url_custom_cursor()); + fn url_custom_cursor(&mut self, event_loop: &ActiveEventLoop) -> Result<(), Box> { + let cursor = event_loop.create_custom_cursor(url_custom_cursor())?; self.window.set_cursor(cursor); + + Ok(()) } /// Custom cursor from a URL. @@ -750,18 +770,20 @@ impl WindowState { &mut self, event_loop: &ActiveEventLoop, custom_cursors: &[CustomCursor], - ) { + ) -> Result<(), Box> { use std::time::Duration; let cursors = vec![ custom_cursors[0].clone(), custom_cursors[1].clone(), - event_loop.create_custom_cursor(url_custom_cursor()), + event_loop.create_custom_cursor(url_custom_cursor())?, ]; let cursor = CustomCursor::from_animation(Duration::from_secs(3), cursors).unwrap(); - let cursor = event_loop.create_custom_cursor(cursor); + let cursor = event_loop.create_custom_cursor(cursor)?; self.window.set_cursor(cursor); + + Ok(()) } /// Resize the window to the new size. diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index f66061b9f4..4b41f5f39d 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -84,6 +84,7 @@ changelog entry. - On Web, `Window::canvas()` now returns a reference. - On Web, `CursorGrabMode::Locked` now lets `DeviceEvent::MouseMotion` return raw data, not OS accelerated, if the browser supports it. +- `(Active)EventLoop::create_custom_cursor()` now returns a `Result`. ### Removed diff --git a/src/cursor.rs b/src/cursor.rs index f89639ae8f..cae0e80d89 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -66,9 +66,9 @@ impl From for Cursor { /// CustomCursor::from_url(String::from("http://localhost:3000/cursor.png"), 0, 0) /// }; /// -/// let custom_cursor = event_loop.create_custom_cursor(source); -/// -/// window.set_cursor(custom_cursor.clone()); +/// if let Ok(custom_cursor) = event_loop.create_custom_cursor(source) { +/// window.set_cursor(custom_cursor.clone()); +/// } /// # } /// ``` #[derive(Clone, Debug, Eq, Hash, PartialEq)] @@ -109,6 +109,8 @@ impl CustomCursor { /// See [`CustomCursor`] for more details. #[derive(Debug)] pub struct CustomCursorSource { + // Some platforms don't support custom cursors. + #[allow(dead_code)] pub(crate) inner: PlatformCustomCursorSource, } diff --git a/src/event_loop.rs b/src/event_loop.rs index f538813414..e4031362e7 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, OsError}; +use crate::error::{EventLoopError, ExternalError, OsError}; use crate::monitor::MonitorHandle; use crate::platform_impl; use crate::window::{CustomCursor, CustomCursorSource, Window, WindowAttributes}; @@ -270,7 +270,14 @@ impl EventLoop { } /// Create custom cursor. - pub fn create_custom_cursor(&self, custom_cursor: CustomCursorSource) -> CustomCursor { + /// + /// ## Platform-specific + /// + /// **iOS / Android / Orbital:** Unsupported. + pub fn create_custom_cursor( + &self, + custom_cursor: CustomCursorSource, + ) -> Result { self.event_loop.window_target().p.create_custom_cursor(custom_cursor) } } @@ -346,7 +353,14 @@ impl ActiveEventLoop { } /// Create custom cursor. - pub fn create_custom_cursor(&self, custom_cursor: CustomCursorSource) -> CustomCursor { + /// + /// ## Platform-specific + /// + /// **iOS / Android / Orbital:** Unsupported. + pub fn create_custom_cursor( + &self, + custom_cursor: CustomCursorSource, + ) -> Result { let _span = tracing::debug_span!("winit::ActiveEventLoop::create_custom_cursor",).entered(); self.p.create_custom_cursor(custom_cursor) diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 7a5526f779..4a76e6faf4 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -15,8 +15,7 @@ use tracing::{debug, trace, warn}; use crate::application::ApplicationHandler; use crate::cursor::Cursor; use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size}; -use crate::error; -use crate::error::EventLoopError; +use crate::error::{self, EventLoopError, ExternalError, NotSupportedError}; use crate::event::{self, Force, InnerSizeWriter, StartCause}; use crate::event_loop::{self, ControlFlow, DeviceEvents}; use crate::platform::pump_events::PumpStatus; @@ -591,9 +590,11 @@ impl ActiveEventLoop { Some(MonitorHandle::new(self.app.clone())) } - pub fn create_custom_cursor(&self, source: CustomCursorSource) -> CustomCursor { - let _ = source.inner; - CustomCursor { inner: PlatformCustomCursor } + pub fn create_custom_cursor( + &self, + _source: CustomCursorSource, + ) -> Result { + Err(ExternalError::NotSupported(NotSupportedError::new())) } pub fn available_monitors(&self) -> VecDeque { diff --git a/src/platform_impl/apple/appkit/cursor.rs b/src/platform_impl/apple/appkit/cursor.rs index cc8f5f3088..fd474f18f4 100644 --- a/src/platform_impl/apple/appkit/cursor.rs +++ b/src/platform_impl/apple/appkit/cursor.rs @@ -11,7 +11,9 @@ use objc2_foundation::{ NSString, }; +use super::OsError; use crate::cursor::{CursorImage, OnlyCursorImageSource}; +use crate::error::ExternalError; use crate::window::CursorIcon; #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -23,12 +25,12 @@ unsafe impl Send for CustomCursor {} unsafe impl Sync for CustomCursor {} impl CustomCursor { - pub(crate) fn new(cursor: OnlyCursorImageSource) -> CustomCursor { - Self(cursor_from_image(&cursor.0)) + pub(crate) fn new(cursor: OnlyCursorImageSource) -> Result { + cursor_from_image(&cursor.0).map(Self) } } -pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Retained { +pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Result, ExternalError> { let width = cursor.width; let height = cursor.height; @@ -45,8 +47,8 @@ pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Retained { NSDeviceRGBColorSpace, width as isize * 4, 32, - ).unwrap() - }; + ) + }.ok_or_else(|| ExternalError::Os(os_error!(OsError::CreationError("parent view should be installed in a window"))))?; let bitmap_data = unsafe { slice::from_raw_parts_mut(bitmap.bitmapData(), cursor.rgba.len()) }; bitmap_data.copy_from_slice(&cursor.rgba); @@ -57,7 +59,7 @@ pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Retained { let hotspot = NSPoint::new(cursor.hotspot_x as f64, cursor.hotspot_y as f64); - NSCursor::initWithImage_hotSpot(NSCursor::alloc(), &image, hotspot) + Ok(NSCursor::initWithImage_hotSpot(NSCursor::alloc(), &image, hotspot)) } pub(crate) fn default_cursor() -> Retained { diff --git a/src/platform_impl/apple/appkit/event_loop.rs b/src/platform_impl/apple/appkit/event_loop.rs index c587f75b26..5bc4521820 100644 --- a/src/platform_impl/apple/appkit/event_loop.rs +++ b/src/platform_impl/apple/appkit/event_loop.rs @@ -28,7 +28,7 @@ use super::event::dummy_event; use super::monitor::{self, MonitorHandle}; use super::observer::setup_control_flow_observers; use crate::application::ApplicationHandler; -use crate::error::EventLoopError; +use crate::error::{EventLoopError, ExternalError}; use crate::event_loop::{ActiveEventLoop as RootWindowTarget, ControlFlow, DeviceEvents}; use crate::platform::macos::ActivationPolicy; use crate::platform::pump_events::PumpStatus; @@ -85,8 +85,11 @@ impl ActiveEventLoop { &self.delegate } - pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor { - RootCustomCursor { inner: CustomCursor::new(source.inner) } + pub fn create_custom_cursor( + &self, + source: CustomCursorSource, + ) -> Result { + Ok(RootCustomCursor { inner: CustomCursor::new(source.inner)? }) } #[inline] diff --git a/src/platform_impl/apple/uikit/event_loop.rs b/src/platform_impl/apple/uikit/event_loop.rs index 91f6a51627..d96d90a74b 100644 --- a/src/platform_impl/apple/uikit/event_loop.rs +++ b/src/platform_impl/apple/uikit/event_loop.rs @@ -21,7 +21,7 @@ use super::app_delegate::AppDelegate; use super::app_state::{AppState, EventLoopHandler}; use super::{app_state, monitor, MonitorHandle}; use crate::application::ApplicationHandler; -use crate::error::EventLoopError; +use crate::error::{EventLoopError, ExternalError, NotSupportedError}; use crate::event::Event; use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents}; use crate::window::{CustomCursor, CustomCursorSource}; @@ -36,9 +36,11 @@ impl ActiveEventLoop { EventLoopProxy::new(AppState::get_mut(self.mtm).proxy_wake_up()) } - pub fn create_custom_cursor(&self, source: CustomCursorSource) -> CustomCursor { - let _ = source.inner; - CustomCursor { inner: super::PlatformCustomCursor } + pub fn create_custom_cursor( + &self, + _source: CustomCursorSource, + ) -> Result { + Err(ExternalError::NotSupported(NotSupportedError::new())) } pub fn available_monitors(&self) -> VecDeque { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index dd4d4c20d6..0991889cc1 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -852,7 +852,10 @@ impl ActiveEventLoop { } } - pub fn create_custom_cursor(&self, cursor: CustomCursorSource) -> CustomCursor { + pub fn create_custom_cursor( + &self, + cursor: CustomCursorSource, + ) -> Result { x11_or_wayland!(match self; ActiveEventLoop(evlp) => evlp.create_custom_cursor(cursor)) } diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index e93e47939a..4fba4bde64 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -16,7 +16,7 @@ use sctk::reexports::client::{globals, Connection, QueueHandle}; use crate::application::ApplicationHandler; use crate::cursor::OnlyCursorImage; use crate::dpi::LogicalSize; -use crate::error::{EventLoopError, OsError as RootOsError}; +use crate::error::{EventLoopError, ExternalError, OsError as RootOsError}; use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent}; use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents}; use crate::platform::pump_events::PumpStatus; @@ -644,10 +644,13 @@ impl ActiveEventLoop { #[inline] pub fn listen_device_events(&self, _allowed: DeviceEvents) {} - pub(crate) fn create_custom_cursor(&self, cursor: CustomCursorSource) -> RootCustomCursor { - RootCustomCursor { + pub(crate) fn create_custom_cursor( + &self, + cursor: CustomCursorSource, + ) -> Result { + Ok(RootCustomCursor { inner: PlatformCustomCursor::Wayland(OnlyCursorImage(Arc::from(cursor.inner.0))), - } + }) } #[cfg(feature = "rwh_05")] diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 6b95e45cc5..0609375a32 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -25,7 +25,7 @@ use x11rb::x11_utils::X11Error as LogicalError; use x11rb::xcb_ffi::ReplyOrIdError; use crate::application::ApplicationHandler; -use crate::error::{EventLoopError, OsError as RootOsError}; +use crate::error::{EventLoopError, ExternalError, OsError as RootOsError}; use crate::event::{Event, StartCause, WindowEvent}; use crate::event_loop::{ActiveEventLoop as RootAEL, ControlFlow, DeviceEvents}; use crate::platform::pump_events::PumpStatus; @@ -643,8 +643,13 @@ impl ActiveEventLoop { self.xconn.primary_monitor().ok() } - pub(crate) fn create_custom_cursor(&self, cursor: CustomCursorSource) -> RootCustomCursor { - RootCustomCursor { inner: PlatformCustomCursor::X(CustomCursor::new(self, cursor.inner)) } + pub(crate) fn create_custom_cursor( + &self, + cursor: CustomCursorSource, + ) -> Result { + Ok(RootCustomCursor { + inner: PlatformCustomCursor::X(CustomCursor::new(self, cursor.inner)?), + }) } pub fn listen_device_events(&self, allowed: DeviceEvents) { diff --git a/src/platform_impl/linux/x11/util/cursor.rs b/src/platform_impl/linux/x11/util/cursor.rs index c9522a5fb2..717217a8eb 100644 --- a/src/platform_impl/linux/x11/util/cursor.rs +++ b/src/platform_impl/linux/x11/util/cursor.rs @@ -7,7 +7,8 @@ use x11rb::connection::Connection; use super::super::ActiveEventLoop; use super::*; -use crate::platform_impl::PlatformCustomCursorSource; +use crate::error::ExternalError; +use crate::platform_impl::{OsError, PlatformCustomCursorSource}; use crate::window::CursorIcon; impl XConnection { @@ -123,14 +124,16 @@ impl CustomCursor { pub(crate) fn new( event_loop: &ActiveEventLoop, cursor: PlatformCustomCursorSource, - ) -> CustomCursor { + ) -> Result { unsafe { let ximage = (event_loop.xconn.xcursor.XcursorImageCreate)( cursor.0.width as i32, cursor.0.height as i32, ); if ximage.is_null() { - panic!("failed to allocate cursor image"); + return Err(ExternalError::Os(os_error!(OsError::Misc( + "`XcursorImageCreate` failed" + )))); } (*ximage).xhot = cursor.0.hotspot_x as u32; (*ximage).yhot = cursor.0.hotspot_y as u32; @@ -147,7 +150,9 @@ impl CustomCursor { let cursor = (event_loop.xconn.xcursor.XcursorImageLoadCursor)(event_loop.xconn.display, ximage); (event_loop.xconn.xcursor.XcursorImageDestroy)(ximage); - Self { inner: Arc::new(CustomCursorInner { xconn: event_loop.xconn.clone(), cursor }) } + Ok(Self { + inner: Arc::new(CustomCursorInner { xconn: event_loop.xconn.clone(), cursor }), + }) } } } diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index b322190501..96b01df674 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -17,7 +17,7 @@ use super::{ RedoxSocket, TimeSocket, WindowId, WindowProperties, }; use crate::application::ApplicationHandler; -use crate::error::EventLoopError; +use crate::error::{EventLoopError, ExternalError, NotSupportedError}; use crate::event::{self, Ime, Modifiers, StartCause}; use crate::event_loop::{self, ControlFlow, DeviceEvents}; use crate::keyboard::{ @@ -729,9 +729,11 @@ impl ActiveEventLoop { } } - pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor { - let _ = source.inner; - RootCustomCursor { inner: super::PlatformCustomCursor } + pub fn create_custom_cursor( + &self, + _source: CustomCursorSource, + ) -> Result { + Err(ExternalError::NotSupported(NotSupportedError::new())) } pub fn primary_monitor(&self) -> Option { diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index 823e040335..ebb341dc10 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::device::DeviceId; use super::runner::{EventWrapper, WeakShared}; use super::window::WindowId; use super::{backend, runner, EventLoopProxy}; -use crate::error::NotSupportedError; +use crate::error::{ExternalError, NotSupportedError}; use crate::event::{ DeviceId as RootDeviceId, ElementState, Event, KeyEvent, Touch, TouchPhase, WindowEvent, }; @@ -71,8 +71,11 @@ impl ActiveEventLoop { EventLoopProxy::new(self.waker()) } - pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor { - RootCustomCursor { inner: CustomCursor::new(self, source.inner) } + pub fn create_custom_cursor( + &self, + source: CustomCursorSource, + ) -> Result { + Ok(RootCustomCursor { inner: CustomCursor::new(self, source.inner) }) } pub fn create_custom_cursor_async(&self, source: CustomCursorSource) -> CustomCursorFuture { diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index c17c620779..2e339a02b7 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -59,7 +59,7 @@ use super::window::set_skip_taskbar; use super::SelectedCursor; use crate::application::ApplicationHandler; use crate::dpi::{PhysicalPosition, PhysicalSize}; -use crate::error::EventLoopError; +use crate::error::{EventLoopError, ExternalError}; use crate::event::{ DeviceEvent, Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase, WindowEvent, }; @@ -484,16 +484,11 @@ impl ActiveEventLoop { EventLoopThreadExecutor { thread_id: self.thread_id, target_window: self.thread_msg_target } } - pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor { - let inner = match WinCursor::new(&source.inner.0) { - Ok(cursor) => cursor, - Err(err) => { - tracing::warn!("Failed to create custom cursor: {err}"); - WinCursor::Failed - }, - }; - - RootCustomCursor { inner } + pub fn create_custom_cursor( + &self, + source: CustomCursorSource, + ) -> Result { + Ok(RootCustomCursor { inner: WinCursor::new(&source.inner.0)? }) } // TODO: Investigate opportunities for caching diff --git a/src/platform_impl/windows/icon.rs b/src/platform_impl/windows/icon.rs index 19d7b69ca8..a90d04d131 100644 --- a/src/platform_impl/windows/icon.rs +++ b/src/platform_impl/windows/icon.rs @@ -17,6 +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::icon::*; impl Pixel { @@ -175,13 +176,10 @@ impl Default for SelectedCursor { } #[derive(Clone, Debug, Hash, Eq, PartialEq)] -pub enum WinCursor { - Cursor(Arc), - Failed, -} +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)); @@ -191,16 +189,16 @@ impl WinCursor { unsafe { let hdc_screen = GetDC(0); if hdc_screen == 0 { - return Err(io::Error::last_os_error()); + return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); } let hbm_color = CreateCompatibleBitmap(hdc_screen, w, h); ReleaseDC(0, hdc_screen); if hbm_color == 0 { - return Err(io::Error::last_os_error()); + return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); } if SetBitmapBits(hbm_color, bgra.len() as u32, bgra.as_ptr() as *const c_void) == 0 { DeleteObject(hbm_color); - return Err(io::Error::last_os_error()); + return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); }; // Mask created according to https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createbitmap#parameters @@ -208,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(io::Error::last_os_error()); + return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); } let icon_info = ICONINFO { @@ -223,10 +221,10 @@ impl WinCursor { DeleteObject(hbm_color); DeleteObject(hbm_mask); if handle == 0 { - return Err(io::Error::last_os_error()); + return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); } - Ok(Self::Cursor(Arc::new(RaiiCursor { handle }))) + Ok(Self(Arc::new(RaiiCursor { handle }))) } } } diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 3bcafc3e5d..b41d3e9b59 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -59,7 +59,7 @@ use crate::platform_impl::platform::dpi::{ }; use crate::platform_impl::platform::drop_handler::FileDropHandler; use crate::platform_impl::platform::event_loop::{self, ActiveEventLoop, DESTROY_MSG_ID}; -use crate::platform_impl::platform::icon::{self, IconType, WinCursor}; +use crate::platform_impl::platform::icon::{self, IconType}; use crate::platform_impl::platform::ime::ImeContext; use crate::platform_impl::platform::keyboard::KeyEventBuilder; use crate::platform_impl::platform::monitor::{self, MonitorHandle}; @@ -409,17 +409,10 @@ impl Window { }); }, Cursor::Custom(cursor) => { - let new_cursor = match cursor.inner { - WinCursor::Cursor(cursor) => cursor, - WinCursor::Failed => { - warn!("Requested to apply failed cursor"); - return; - }, - }; self.window_state_lock().mouse.selected_cursor = - SelectedCursor::Custom(new_cursor.clone()); + SelectedCursor::Custom(cursor.inner.0.clone()); self.thread_executor.execute_in_thread(move || unsafe { - SetCursor(new_cursor.as_raw_handle()); + SetCursor(cursor.inner.0.as_raw_handle()); }); }, }