Custom cursor improvements (#3292)
This commit is contained in:
parent
37946e0a3a
commit
e5310ade08
18 changed files with 152 additions and 101 deletions
|
|
@ -46,25 +46,12 @@ const PIXEL_SIZE: usize = 4;
|
|||
/// let window = Window::new(&event_loop).unwrap();
|
||||
/// window.set_custom_cursor(&custom_cursor);
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct CustomCursor {
|
||||
pub(crate) inner: Arc<PlatformCustomCursor>,
|
||||
/// Platforms should make sure this is cheap to clone.
|
||||
pub(crate) inner: PlatformCustomCursor,
|
||||
}
|
||||
|
||||
impl Hash for CustomCursor {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
Arc::as_ptr(&self.inner).hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for CustomCursor {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
Arc::ptr_eq(&self.inner, &other.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for CustomCursor {}
|
||||
|
||||
impl CustomCursor {
|
||||
/// Creates a new cursor from an rgba buffer.
|
||||
///
|
||||
|
|
@ -80,7 +67,7 @@ impl CustomCursor {
|
|||
hotspot_y: u16,
|
||||
) -> Result<CustomCursorBuilder, BadImage> {
|
||||
Ok(CustomCursorBuilder {
|
||||
inner: PlatformCustomCursor::from_rgba(
|
||||
inner: PlatformCustomCursorBuilder::from_rgba(
|
||||
rgba.into(),
|
||||
width,
|
||||
height,
|
||||
|
|
@ -102,7 +89,7 @@ pub struct CustomCursorBuilder {
|
|||
impl CustomCursorBuilder {
|
||||
pub fn build<T>(self, window_target: &EventLoopWindowTarget<T>) -> CustomCursor {
|
||||
CustomCursor {
|
||||
inner: self.inner.build(&window_target.p),
|
||||
inner: PlatformCustomCursor::build(self.inner, &window_target.p),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -165,9 +152,54 @@ impl fmt::Display for BadImage {
|
|||
|
||||
impl Error for BadImage {}
|
||||
|
||||
/// Platforms export this directly as `PlatformCustomCursor` if they need to only work with images.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct CursorImage {
|
||||
/// Platforms export this directly as `PlatformCustomCursorBuilder` if they need to only work with images.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct OnlyCursorImageBuilder(pub(crate) CursorImage);
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl OnlyCursorImageBuilder {
|
||||
pub(crate) fn from_rgba(
|
||||
rgba: Vec<u8>,
|
||||
width: u16,
|
||||
height: u16,
|
||||
hotspot_x: u16,
|
||||
hotspot_y: u16,
|
||||
) -> Result<Self, BadImage> {
|
||||
CursorImage::from_rgba(rgba, width, height, hotspot_x, hotspot_y).map(Self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Platforms export this directly as `PlatformCustomCursor` if they don't implement caching.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct OnlyCursorImage(pub(crate) Arc<CursorImage>);
|
||||
|
||||
impl Hash for OnlyCursorImage {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
Arc::as_ptr(&self.0).hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for OnlyCursorImage {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
Arc::ptr_eq(&self.0, &other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for OnlyCursorImage {}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl OnlyCursorImage {
|
||||
fn build<T>(
|
||||
builder: OnlyCursorImageBuilder,
|
||||
_: &platform_impl::EventLoopWindowTarget<T>,
|
||||
) -> Self {
|
||||
Self(Arc::new(builder.0))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) struct CursorImage {
|
||||
pub(crate) rgba: Vec<u8>,
|
||||
pub(crate) width: u16,
|
||||
pub(crate) height: u16,
|
||||
|
|
@ -175,9 +207,8 @@ pub struct CursorImage {
|
|||
pub(crate) hotspot_y: u16,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl CursorImage {
|
||||
pub fn from_rgba(
|
||||
pub(crate) fn from_rgba(
|
||||
rgba: Vec<u8>,
|
||||
width: u16,
|
||||
height: u16,
|
||||
|
|
@ -222,19 +253,15 @@ impl CursorImage {
|
|||
hotspot_y,
|
||||
})
|
||||
}
|
||||
|
||||
fn build<T>(self, _: &platform_impl::EventLoopWindowTarget<T>) -> Arc<CursorImage> {
|
||||
Arc::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
// Platforms that don't support cursors will export this as `PlatformCustomCursor`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub(crate) struct NoCustomCursor;
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl NoCustomCursor {
|
||||
pub fn from_rgba(
|
||||
pub(crate) fn from_rgba(
|
||||
rgba: Vec<u8>,
|
||||
width: u16,
|
||||
height: u16,
|
||||
|
|
@ -245,7 +272,7 @@ impl NoCustomCursor {
|
|||
Ok(Self)
|
||||
}
|
||||
|
||||
fn build<T>(self, _: &platform_impl::EventLoopWindowTarget<T>) -> Arc<NoCustomCursor> {
|
||||
Arc::new(self)
|
||||
fn build<T>(self, _: &platform_impl::EventLoopWindowTarget<T>) -> NoCustomCursor {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -906,7 +906,7 @@ impl Window {
|
|||
|
||||
pub fn set_cursor_icon(&self, _: window::CursorIcon) {}
|
||||
|
||||
pub(crate) fn set_custom_cursor(&self, _: Arc<PlatformCustomCursor>) {}
|
||||
pub(crate) fn set_custom_cursor(&self, _: PlatformCustomCursor) {}
|
||||
|
||||
pub fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#![allow(clippy::unnecessary_cast)]
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::Arc;
|
||||
|
||||
use icrate::Foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadBound, MainThreadMarker};
|
||||
use objc2::rc::Id;
|
||||
|
|
@ -178,7 +177,7 @@ impl Inner {
|
|||
debug!("`Window::set_cursor_icon` ignored on iOS")
|
||||
}
|
||||
|
||||
pub(crate) fn set_custom_cursor(&self, _: Arc<PlatformCustomCursor>) {
|
||||
pub(crate) fn set_custom_cursor(&self, _: PlatformCustomCursor) {
|
||||
debug!("`Window::set_custom_cursor` ignored on iOS")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ pub use x11::XNotSupported;
|
|||
#[cfg(x11_platform)]
|
||||
use x11::{util::WindowType as XWindowType, X11Error, XConnection, XError};
|
||||
|
||||
pub(crate) use crate::cursor::CursorImage as PlatformCustomCursorBuilder;
|
||||
pub(crate) use crate::cursor::CursorImage as PlatformCustomCursor;
|
||||
pub(crate) use crate::cursor::OnlyCursorImage as PlatformCustomCursor;
|
||||
pub(crate) use crate::cursor::OnlyCursorImageBuilder as PlatformCustomCursorBuilder;
|
||||
pub(crate) use crate::icon::RgbaIcon as PlatformIcon;
|
||||
pub(crate) use crate::platform_impl::Fullscreen;
|
||||
|
||||
|
|
@ -427,7 +427,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: Arc<PlatformCustomCursor>) {
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: PlatformCustomCursor) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_custom_cursor(cursor))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ pub struct CustomCursor {
|
|||
}
|
||||
|
||||
impl CustomCursor {
|
||||
pub fn new(pool: &mut SlotPool, image: &CursorImage) -> Self {
|
||||
pub(crate) fn new(pool: &mut SlotPool, image: &CursorImage) -> Self {
|
||||
let (buffer, canvas) = pool
|
||||
.create_buffer(
|
||||
image.width as i32,
|
||||
|
|
|
|||
|
|
@ -507,8 +507,11 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: Arc<PlatformCustomCursor>) {
|
||||
self.window_state.lock().unwrap().set_custom_cursor(&cursor);
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: PlatformCustomCursor) {
|
||||
self.window_state
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_custom_cursor(&cursor.0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -726,7 +726,7 @@ impl WindowState {
|
|||
}
|
||||
|
||||
/// Set the custom cursor icon.
|
||||
pub fn set_custom_cursor(&mut self, cursor: &CursorImage) {
|
||||
pub(crate) fn set_custom_cursor(&mut self, cursor: &CursorImage) {
|
||||
let cursor = {
|
||||
let mut pool = self.custom_cursor_pool.lock().unwrap();
|
||||
CustomCursor::new(&mut pool, cursor)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ impl XConnection {
|
|||
.expect("Failed to set cursor");
|
||||
}
|
||||
|
||||
pub fn set_custom_cursor(&self, window: xproto::Window, cursor: &CustomCursor) {
|
||||
pub(crate) fn set_custom_cursor(&self, window: xproto::Window, cursor: &CustomCursor) {
|
||||
self.update_cursor(window, cursor.inner.cursor)
|
||||
.expect("Failed to set cursor");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1550,8 +1550,8 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: Arc<PlatformCustomCursor>) {
|
||||
let new_cursor = unsafe { CustomCursor::new(&self.xconn, &cursor) };
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: PlatformCustomCursor) {
|
||||
let new_cursor = unsafe { CustomCursor::new(&self.xconn, &cursor.0) };
|
||||
|
||||
#[allow(clippy::mutex_atomic)]
|
||||
if *self.cursor_visible.lock().unwrap() {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ pub(crate) use self::{
|
|||
use crate::event::DeviceId as RootDeviceId;
|
||||
|
||||
pub(crate) use self::window::Window;
|
||||
pub(crate) use crate::cursor::CursorImage as PlatformCustomCursor;
|
||||
pub(crate) use crate::cursor::CursorImage as PlatformCustomCursorBuilder;
|
||||
pub(crate) use crate::cursor::OnlyCursorImage as PlatformCustomCursor;
|
||||
pub(crate) use crate::cursor::OnlyCursorImageBuilder as PlatformCustomCursorBuilder;
|
||||
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
||||
pub(crate) use crate::platform_impl::Fullscreen;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ use std::f64;
|
|||
use std::ops;
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -848,9 +847,9 @@ impl WinitWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: Arc<PlatformCustomCursor>) {
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: PlatformCustomCursor) {
|
||||
let view = self.view();
|
||||
view.set_cursor_icon(NSCursor::from_image(&cursor));
|
||||
view.set_cursor_icon(NSCursor::from_image(&cursor.0));
|
||||
self.invalidateCursorRectsForView(&view);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_cursor_icon(&self, _: window::CursorIcon) {}
|
||||
|
||||
pub(crate) fn set_custom_cursor(&self, _: Arc<PlatformCustomCursor>) {}
|
||||
pub(crate) fn set_custom_cursor(&self, _: PlatformCustomCursor) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use std::{
|
||||
cell::RefCell,
|
||||
future, mem,
|
||||
future,
|
||||
hash::{Hash, Hasher},
|
||||
mem,
|
||||
ops::DerefMut,
|
||||
rc::{self, Rc},
|
||||
sync::{self, Arc},
|
||||
|
|
@ -25,7 +27,7 @@ use self::thread_safe::ThreadSafe;
|
|||
use super::{backend::Style, r#async::AsyncSender, EventLoopWindowTarget};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CustomCursorBuilder {
|
||||
pub(crate) enum CustomCursorBuilder {
|
||||
Image(CursorImage),
|
||||
Url {
|
||||
url: String,
|
||||
|
|
@ -35,35 +37,6 @@ pub enum CustomCursorBuilder {
|
|||
}
|
||||
|
||||
impl CustomCursorBuilder {
|
||||
pub fn build<T>(self, window_target: &EventLoopWindowTarget<T>) -> Arc<CustomCursor> {
|
||||
Lazy::force(&DROP_HANDLER);
|
||||
|
||||
match self {
|
||||
Self::Image(image) => ImageState::from_rgba(
|
||||
window_target.runner.window(),
|
||||
window_target.runner.document().clone(),
|
||||
&image,
|
||||
),
|
||||
Self::Url {
|
||||
url,
|
||||
hotspot_x,
|
||||
hotspot_y,
|
||||
} => ImageState::from_url(url, hotspot_x, hotspot_y),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CustomCursor(Option<ThreadSafe<RefCell<ImageState>>>);
|
||||
|
||||
static DROP_HANDLER: Lazy<AsyncSender<ThreadSafe<RefCell<ImageState>>>> = Lazy::new(|| {
|
||||
let (sender, receiver) = r#async::channel();
|
||||
wasm_bindgen_futures::spawn_local(async move { while receiver.next().await.is_ok() {} });
|
||||
|
||||
sender
|
||||
});
|
||||
|
||||
impl CustomCursor {
|
||||
pub fn from_rgba(
|
||||
rgba: Vec<u8>,
|
||||
width: u16,
|
||||
|
|
@ -75,9 +48,60 @@ impl CustomCursor {
|
|||
rgba, width, height, hotspot_x, hotspot_y,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CustomCursor(Arc<Inner>);
|
||||
|
||||
impl Hash for CustomCursor {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
Arc::as_ptr(&self.0).hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for CustomCursor {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
Arc::ptr_eq(&self.0, &other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for CustomCursor {}
|
||||
|
||||
impl CustomCursor {
|
||||
pub(crate) fn build<T>(
|
||||
builder: CustomCursorBuilder,
|
||||
window_target: &EventLoopWindowTarget<T>,
|
||||
) -> Self {
|
||||
Lazy::force(&DROP_HANDLER);
|
||||
|
||||
Self(match builder {
|
||||
CustomCursorBuilder::Image(image) => ImageState::from_rgba(
|
||||
window_target.runner.window(),
|
||||
window_target.runner.document().clone(),
|
||||
&image,
|
||||
),
|
||||
CustomCursorBuilder::Url {
|
||||
url,
|
||||
hotspot_x,
|
||||
hotspot_y,
|
||||
} => ImageState::from_url(url, hotspot_x, hotspot_y),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Inner(Option<ThreadSafe<RefCell<ImageState>>>);
|
||||
|
||||
static DROP_HANDLER: Lazy<AsyncSender<ThreadSafe<RefCell<ImageState>>>> = Lazy::new(|| {
|
||||
let (sender, receiver) = r#async::channel();
|
||||
wasm_bindgen_futures::spawn_local(async move { while receiver.next().await.is_ok() {} });
|
||||
|
||||
sender
|
||||
});
|
||||
|
||||
impl Inner {
|
||||
fn new() -> Arc<Self> {
|
||||
Arc::new(Self(Some(ThreadSafe::new(RefCell::new(
|
||||
Arc::new(Inner(Some(ThreadSafe::new(RefCell::new(
|
||||
ImageState::Loading(None),
|
||||
)))))
|
||||
}
|
||||
|
|
@ -90,7 +114,7 @@ impl CustomCursor {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for CustomCursor {
|
||||
impl Drop for Inner {
|
||||
fn drop(&mut self) {
|
||||
let value = self
|
||||
.0
|
||||
|
|
@ -130,13 +154,13 @@ impl CursorState {
|
|||
this.set_style();
|
||||
}
|
||||
|
||||
pub fn set_custom_cursor(&self, cursor: Arc<CustomCursor>) {
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: CustomCursor) {
|
||||
let mut this = self.0.borrow_mut();
|
||||
|
||||
match cursor.get().borrow_mut().deref_mut() {
|
||||
match cursor.0.get().borrow_mut().deref_mut() {
|
||||
ImageState::Loading(state) => {
|
||||
this.cursor = SelectedCursor::ImageLoading {
|
||||
state: cursor.clone(),
|
||||
state: cursor.0.clone(),
|
||||
previous: mem::take(&mut this.cursor).into(),
|
||||
};
|
||||
*state = Some(Rc::downgrade(&self.0));
|
||||
|
|
@ -187,7 +211,7 @@ impl State {
|
|||
enum SelectedCursor {
|
||||
Named(CursorIcon),
|
||||
ImageLoading {
|
||||
state: Arc<CustomCursor>,
|
||||
state: Arc<Inner>,
|
||||
previous: Previous,
|
||||
},
|
||||
ImageReady(Rc<Image>),
|
||||
|
|
@ -241,7 +265,7 @@ enum ImageState {
|
|||
}
|
||||
|
||||
impl ImageState {
|
||||
fn from_rgba(window: &Window, document: Document, image: &CursorImage) -> Arc<CustomCursor> {
|
||||
fn from_rgba(window: &Window, document: Document, image: &CursorImage) -> Arc<Inner> {
|
||||
// 1. Create an `ImageData` from the RGBA data.
|
||||
// 2. Create an `ImageBitmap` from the `ImageData`.
|
||||
// 3. Draw `ImageBitmap` on an `HTMLCanvasElement`.
|
||||
|
|
@ -293,7 +317,7 @@ impl ImageState {
|
|||
.expect("unexpected exception in `createImageBitmap()`"),
|
||||
);
|
||||
|
||||
let this = CustomCursor::new();
|
||||
let this = Inner::new();
|
||||
|
||||
wasm_bindgen_futures::spawn_local({
|
||||
let weak = Arc::downgrade(&this);
|
||||
|
|
@ -406,8 +430,8 @@ impl ImageState {
|
|||
this
|
||||
}
|
||||
|
||||
fn from_url(url: String, hotspot_x: u16, hotspot_y: u16) -> Arc<CustomCursor> {
|
||||
let this = CustomCursor::new();
|
||||
fn from_url(url: String, hotspot_x: u16, hotspot_y: u16) -> Arc<Inner> {
|
||||
let this = Inner::new();
|
||||
wasm_bindgen_futures::spawn_local(Self::decode(
|
||||
Arc::downgrade(&this),
|
||||
url,
|
||||
|
|
@ -420,7 +444,7 @@ impl ImageState {
|
|||
}
|
||||
|
||||
async fn decode(
|
||||
weak: sync::Weak<CustomCursor>,
|
||||
weak: sync::Weak<Inner>,
|
||||
url: String,
|
||||
object: bool,
|
||||
hotspot_x: u16,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ use web_sys::HtmlCanvasElement;
|
|||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct Window {
|
||||
inner: Dispatcher<Inner>,
|
||||
|
|
@ -218,7 +217,7 @@ impl Inner {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: Arc<PlatformCustomCursor>) {
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: PlatformCustomCursor) {
|
||||
self.cursor.set_custom_cursor(cursor)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ impl WinCursor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new(image: &CursorImage) -> Result<Self, io::Error> {
|
||||
pub(crate) fn new(image: &CursorImage) -> Result<Self, io::Error> {
|
||||
let mut bgra = image.rgba.clone();
|
||||
bgra.chunks_exact_mut(4).for_each(|chunk| chunk.swap(0, 2));
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ pub(crate) use self::{
|
|||
};
|
||||
|
||||
pub use self::icon::WinIcon as PlatformIcon;
|
||||
pub(crate) use crate::cursor::CursorImage as PlatformCustomCursor;
|
||||
pub(crate) use crate::cursor::CursorImage as PlatformCustomCursorBuilder;
|
||||
pub(crate) use crate::cursor::OnlyCursorImage as PlatformCustomCursor;
|
||||
pub(crate) use crate::cursor::OnlyCursorImageBuilder as PlatformCustomCursorBuilder;
|
||||
use crate::platform_impl::Fullscreen;
|
||||
|
||||
use crate::event::DeviceId as RootDeviceId;
|
||||
|
|
|
|||
|
|
@ -405,8 +405,8 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: Arc<PlatformCustomCursor>) {
|
||||
let new_cursor = match WinCursor::new(&cursor) {
|
||||
pub(crate) fn set_custom_cursor(&self, cursor: PlatformCustomCursor) {
|
||||
let new_cursor = match WinCursor::new(&cursor.0) {
|
||||
Ok(cursor) => cursor,
|
||||
Err(err) => {
|
||||
warn!("Failed to create custom cursor: {err}");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! The [`Window`] struct and associated types.
|
||||
use std::{fmt, sync::Arc};
|
||||
use std::fmt;
|
||||
|
||||
use crate::{
|
||||
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
|
||||
|
|
@ -1355,7 +1355,7 @@ impl Window {
|
|||
/// - **iOS / Android / Orbital:** Unsupported.
|
||||
#[inline]
|
||||
pub fn set_custom_cursor(&self, cursor: &CustomCursor) {
|
||||
let cursor = Arc::clone(&cursor.inner);
|
||||
let cursor = cursor.inner.clone();
|
||||
self.window
|
||||
.maybe_queue_on_main(move |w| w.set_custom_cursor(cursor))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue