Desktop: Custom cursor support (#3452)

custom cursors with caching
This commit is contained in:
Timon
2025-12-07 00:16:14 +00:00
committed by GitHub
parent 2e4481880e
commit a5cf62a90b
6 changed files with 68 additions and 16 deletions

View File

@@ -1,4 +1,6 @@
use std::collections::HashMap;
use std::sync::Arc;
use winit::cursor::{CursorIcon, CustomCursor, CustomCursorSource};
use winit::event_loop::ActiveEventLoop;
use winit::window::{Window as WinitWindow, WindowAttributes};
@@ -35,6 +37,7 @@ pub(crate) struct Window {
winit_window: Arc<dyn winit::window::Window>,
#[allow(dead_code)]
native_handle: native::NativeWindowImpl,
custom_cursors: HashMap<CustomCursorSource, CustomCursor>,
}
impl Window {
@@ -57,6 +60,7 @@ impl Window {
Self {
winit_window: winit_window.into(),
native_handle,
custom_cursors: HashMap::new(),
}
}
@@ -108,7 +112,24 @@ impl Window {
self.native_handle.show_all();
}
pub(crate) fn set_cursor(&self, cursor: winit::cursor::Cursor) {
pub(crate) fn set_cursor(&mut self, event_loop: &dyn ActiveEventLoop, cursor: Cursor) {
let cursor = match cursor {
Cursor::Icon(cursor_icon) => cursor_icon.into(),
Cursor::Custom(custom_cursor_source) => {
let custom_cursor = match self.custom_cursors.get(&custom_cursor_source).cloned() {
Some(cursor) => cursor,
None => {
let Ok(custom_cursor) = event_loop.create_custom_cursor(custom_cursor_source.clone()) else {
tracing::error!("Failed to create custom cursor");
return;
};
self.custom_cursors.insert(custom_cursor_source, custom_cursor.clone());
custom_cursor
}
};
custom_cursor.into()
}
};
self.winit_window.set_cursor(cursor);
}
@@ -116,3 +137,18 @@ impl Window {
self.native_handle.update_menu(entries);
}
}
pub(crate) enum Cursor {
Icon(CursorIcon),
Custom(CustomCursorSource),
}
impl From<CursorIcon> for Cursor {
fn from(icon: CursorIcon) -> Self {
Cursor::Icon(icon)
}
}
impl From<CustomCursorSource> for Cursor {
fn from(custom: CustomCursorSource) -> Self {
Cursor::Custom(custom)
}
}