Windows: cache custom cursors (#3293)
This commit is contained in:
parent
37b6243289
commit
787b2d7362
3 changed files with 35 additions and 25 deletions
|
|
@ -17,9 +17,12 @@ use windows_sys::{
|
|||
};
|
||||
|
||||
use crate::icon::*;
|
||||
use crate::{cursor::CursorImage, dpi::PhysicalSize};
|
||||
use crate::{
|
||||
cursor::{CursorImage, OnlyCursorImageBuilder},
|
||||
dpi::PhysicalSize,
|
||||
};
|
||||
|
||||
use super::util;
|
||||
use super::{util, EventLoopWindowTarget};
|
||||
|
||||
impl Pixel {
|
||||
fn convert_to_bgra(&mut self) {
|
||||
|
|
@ -169,7 +172,7 @@ pub fn unset_for_window(hwnd: HWND, icon_type: IconType) {
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum SelectedCursor {
|
||||
Named(CursorIcon),
|
||||
Custom(WinCursor),
|
||||
Custom(Arc<RaiiCursor>),
|
||||
}
|
||||
|
||||
impl Default for SelectedCursor {
|
||||
|
|
@ -178,23 +181,14 @@ impl Default for SelectedCursor {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WinCursor {
|
||||
inner: Arc<RaiiCursor>,
|
||||
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
|
||||
pub enum WinCursor {
|
||||
Cursor(Arc<RaiiCursor>),
|
||||
Failed,
|
||||
}
|
||||
|
||||
impl WinCursor {
|
||||
pub fn as_raw_handle(&self) -> HICON {
|
||||
self.inner.handle
|
||||
}
|
||||
|
||||
fn from_handle(handle: HCURSOR) -> Self {
|
||||
Self {
|
||||
inner: Arc::new(RaiiCursor { handle }),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn new(image: &CursorImage) -> Result<Self, io::Error> {
|
||||
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));
|
||||
|
||||
|
|
@ -239,13 +233,23 @@ impl WinCursor {
|
|||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
||||
Ok(Self::from_handle(handle))
|
||||
Ok(Self::Cursor(Arc::new(RaiiCursor { handle })))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn build<T>(cursor: OnlyCursorImageBuilder, _: &EventLoopWindowTarget<T>) -> Self {
|
||||
match Self::new(&cursor.0) {
|
||||
Ok(cursor) => cursor,
|
||||
Err(err) => {
|
||||
log::warn!("Failed to create custom cursor: {err}");
|
||||
Self::Failed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RaiiCursor {
|
||||
#[derive(Debug, Hash, Eq, PartialEq)]
|
||||
pub struct RaiiCursor {
|
||||
handle: HCURSOR,
|
||||
}
|
||||
|
||||
|
|
@ -254,3 +258,9 @@ impl Drop for RaiiCursor {
|
|||
unsafe { DestroyCursor(self.handle) };
|
||||
}
|
||||
}
|
||||
|
||||
impl RaiiCursor {
|
||||
pub fn as_raw_handle(&self) -> HICON {
|
||||
self.handle
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ pub(crate) use self::{
|
|||
window::Window,
|
||||
};
|
||||
|
||||
pub(crate) use self::icon::WinCursor as PlatformCustomCursor;
|
||||
pub use self::icon::WinIcon as PlatformIcon;
|
||||
pub(crate) use crate::cursor::OnlyCursorImage as PlatformCustomCursor;
|
||||
pub(crate) use crate::cursor::OnlyCursorImageBuilder as PlatformCustomCursorBuilder;
|
||||
use crate::platform_impl::Fullscreen;
|
||||
|
||||
|
|
|
|||
|
|
@ -407,10 +407,10 @@ impl Window {
|
|||
});
|
||||
}
|
||||
Cursor::Custom(cursor) => {
|
||||
let new_cursor = match WinCursor::new(&cursor.inner.0) {
|
||||
Ok(cursor) => cursor,
|
||||
Err(err) => {
|
||||
warn!("Failed to create custom cursor: {err}");
|
||||
let new_cursor = match cursor.inner {
|
||||
WinCursor::Cursor(cursor) => cursor,
|
||||
WinCursor::Failed => {
|
||||
warn!("Requested to apply failed cursor");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue