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::icon::*;
|
||||||
use crate::{cursor::CursorImage, dpi::PhysicalSize};
|
use crate::{
|
||||||
|
cursor::{CursorImage, OnlyCursorImageBuilder},
|
||||||
|
dpi::PhysicalSize,
|
||||||
|
};
|
||||||
|
|
||||||
use super::util;
|
use super::{util, EventLoopWindowTarget};
|
||||||
|
|
||||||
impl Pixel {
|
impl Pixel {
|
||||||
fn convert_to_bgra(&mut self) {
|
fn convert_to_bgra(&mut self) {
|
||||||
|
|
@ -169,7 +172,7 @@ pub fn unset_for_window(hwnd: HWND, icon_type: IconType) {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum SelectedCursor {
|
pub enum SelectedCursor {
|
||||||
Named(CursorIcon),
|
Named(CursorIcon),
|
||||||
Custom(WinCursor),
|
Custom(Arc<RaiiCursor>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SelectedCursor {
|
impl Default for SelectedCursor {
|
||||||
|
|
@ -178,23 +181,14 @@ impl Default for SelectedCursor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
pub struct WinCursor {
|
pub enum WinCursor {
|
||||||
inner: Arc<RaiiCursor>,
|
Cursor(Arc<RaiiCursor>),
|
||||||
|
Failed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WinCursor {
|
impl WinCursor {
|
||||||
pub fn as_raw_handle(&self) -> HICON {
|
fn new(image: &CursorImage) -> Result<Self, io::Error> {
|
||||||
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> {
|
|
||||||
let mut bgra = image.rgba.clone();
|
let mut bgra = image.rgba.clone();
|
||||||
bgra.chunks_exact_mut(4).for_each(|chunk| chunk.swap(0, 2));
|
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());
|
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)]
|
#[derive(Debug, Hash, Eq, PartialEq)]
|
||||||
struct RaiiCursor {
|
pub struct RaiiCursor {
|
||||||
handle: HCURSOR,
|
handle: HCURSOR,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -254,3 +258,9 @@ impl Drop for RaiiCursor {
|
||||||
unsafe { DestroyCursor(self.handle) };
|
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,
|
window::Window,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub(crate) use self::icon::WinCursor as PlatformCustomCursor;
|
||||||
pub use self::icon::WinIcon as PlatformIcon;
|
pub use self::icon::WinIcon as PlatformIcon;
|
||||||
pub(crate) use crate::cursor::OnlyCursorImage as PlatformCustomCursor;
|
|
||||||
pub(crate) use crate::cursor::OnlyCursorImageBuilder as PlatformCustomCursorBuilder;
|
pub(crate) use crate::cursor::OnlyCursorImageBuilder as PlatformCustomCursorBuilder;
|
||||||
use crate::platform_impl::Fullscreen;
|
use crate::platform_impl::Fullscreen;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -407,10 +407,10 @@ impl Window {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Cursor::Custom(cursor) => {
|
Cursor::Custom(cursor) => {
|
||||||
let new_cursor = match WinCursor::new(&cursor.inner.0) {
|
let new_cursor = match cursor.inner {
|
||||||
Ok(cursor) => cursor,
|
WinCursor::Cursor(cursor) => cursor,
|
||||||
Err(err) => {
|
WinCursor::Failed => {
|
||||||
warn!("Failed to create custom cursor: {err}");
|
warn!("Requested to apply failed cursor");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue