Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 30 additions & 20 deletions src/platform_impl/windows/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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));

Expand Down Expand Up @@ -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,
}

Expand All @@ -254,3 +258,9 @@ impl Drop for RaiiCursor {
unsafe { DestroyCursor(self.handle) };
}
}

impl RaiiCursor {
pub fn as_raw_handle(&self) -> HICON {
self.handle
}
}
2 changes: 1 addition & 1 deletion src/platform_impl/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
8 changes: 4 additions & 4 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
};
Expand Down