Skip to content

Commit

Permalink
Change create_custom_error() to return Result
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Aug 2, 2024
1 parent e3fbfb8 commit 08a3734
Show file tree
Hide file tree
Showing 17 changed files with 141 additions and 87 deletions.
46 changes: 34 additions & 12 deletions examples/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -75,7 +76,7 @@ struct Application {
receiver: Receiver<Action>,
sender: Sender<Action>,
/// Custom cursors assets.
custom_cursors: Vec<CustomCursor>,
custom_cursors: Result<Vec<CustomCursor>, ExternalError>,
/// Application icon.
icon: Icon,
windows: HashMap<WindowId, WindowState>,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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)))]
Expand Down Expand Up @@ -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<dyn Error>> {
let cursor = event_loop.create_custom_cursor(url_custom_cursor())?;

self.window.set_cursor(cursor);

Ok(())
}

/// Custom cursor from a URL.
Expand All @@ -750,18 +770,20 @@ impl WindowState {
&mut self,
event_loop: &ActiveEventLoop,
custom_cursors: &[CustomCursor],
) {
) -> Result<(), Box<dyn Error>> {
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.
Expand Down
1 change: 1 addition & 0 deletions src/changelog/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_error()` now returns a `Result<CustomCursor, ExternalError>`.

### Removed

Expand Down
8 changes: 5 additions & 3 deletions src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ impl From<CustomCursor> 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)]
Expand Down Expand Up @@ -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,
}

Expand Down
20 changes: 17 additions & 3 deletions src/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<CustomCursor, ExternalError> {
self.event_loop.window_target().p.create_custom_cursor(custom_cursor)
}
}
Expand Down Expand Up @@ -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<CustomCursor, ExternalError> {
let _span = tracing::debug_span!("winit::ActiveEventLoop::create_custom_cursor",).entered();

self.p.create_custom_cursor(custom_cursor)
Expand Down
11 changes: 6 additions & 5 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<CustomCursor, ExternalError> {
Err(ExternalError::NotSupported(NotSupportedError::new()))
}

pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
Expand Down
14 changes: 8 additions & 6 deletions src/platform_impl/apple/appkit/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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<CustomCursor, ExternalError> {
cursor_from_image(&cursor.0).map(Self)
}
}

pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Retained<NSCursor> {
pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Result<Retained<NSCursor>, ExternalError> {
let width = cursor.width;
let height = cursor.height;

Expand All @@ -45,8 +47,8 @@ pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Retained<NSCursor> {
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);

Expand All @@ -57,7 +59,7 @@ pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Retained<NSCursor> {

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<NSCursor> {
Expand Down
9 changes: 6 additions & 3 deletions src/platform_impl/apple/appkit/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<RootCustomCursor, ExternalError> {
Ok(RootCustomCursor { inner: CustomCursor::new(source.inner)? })
}

#[inline]
Expand Down
10 changes: 6 additions & 4 deletions src/platform_impl/apple/uikit/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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<CustomCursor, ExternalError> {
Err(ExternalError::NotSupported(NotSupportedError::new()))
}

pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
Expand Down
5 changes: 4 additions & 1 deletion src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,10 @@ impl ActiveEventLoop {
}
}

pub fn create_custom_cursor(&self, cursor: CustomCursorSource) -> CustomCursor {
pub fn create_custom_cursor(
&self,
cursor: CustomCursorSource,
) -> Result<CustomCursor, ExternalError> {
x11_or_wayland!(match self; ActiveEventLoop(evlp) => evlp.create_custom_cursor(cursor))
}

Expand Down
11 changes: 7 additions & 4 deletions src/platform_impl/linux/wayland/event_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<RootCustomCursor, ExternalError> {
Ok(RootCustomCursor {
inner: PlatformCustomCursor::Wayland(OnlyCursorImage(Arc::from(cursor.inner.0))),
}
})
}

#[cfg(feature = "rwh_05")]
Expand Down
11 changes: 8 additions & 3 deletions src/platform_impl/linux/x11/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<RootCustomCursor, ExternalError> {
Ok(RootCustomCursor {
inner: PlatformCustomCursor::X(CustomCursor::new(self, cursor.inner)?),
})
}

pub fn listen_device_events(&self, allowed: DeviceEvents) {
Expand Down
Loading

0 comments on commit 08a3734

Please sign in to comment.