Skip to content

Commit

Permalink
Use separate cursor and icon types to use correct win functions
Browse files Browse the repository at this point in the history
  • Loading branch information
eero-lehtinen committed Nov 17, 2023
1 parent 3e0b7c2 commit ff11721
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 26 deletions.
75 changes: 52 additions & 23 deletions src/platform_impl/windows/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use windows_sys::{
Foundation::HWND,
Graphics::Gdi::{CreateBitmap, CreateCompatibleBitmap, GetDC, ReleaseDC, SetBitmapBits},
UI::WindowsAndMessaging::{
CreateIcon, CreateIconIndirect, DestroyIcon, LoadImageW, SendMessageW, HICON, ICONINFO,
ICON_BIG, ICON_SMALL, IMAGE_ICON, LR_DEFAULTSIZE, LR_LOADFROMFILE, WM_SETICON,
CreateIcon, CreateIconIndirect, DestroyCursor, DestroyIcon, LoadImageW, SendMessageW,
HCURSOR, HICON, ICONINFO, ICON_BIG, ICON_SMALL, IMAGE_ICON, LR_DEFAULTSIZE,
LR_LOADFROMFILE, WM_SETICON,
},
},
};
Expand Down Expand Up @@ -138,11 +139,51 @@ impl WinIcon {
}
}

pub fn from_handle(handle: HICON) -> Self {
fn from_handle(handle: HICON) -> Self {
Self {
inner: Arc::new(RaiiIcon { handle }),
}
}
}

impl Drop for RaiiIcon {
fn drop(&mut self) {
unsafe { DestroyIcon(self.handle) };
}
}

impl fmt::Debug for WinIcon {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
(*self.inner).fmt(formatter)
}
}

pub fn unset_for_window(hwnd: HWND, icon_type: IconType) {
unsafe {
SendMessageW(hwnd, WM_SETICON, icon_type as usize, 0);
}
}

#[derive(Debug)]
struct RaiiCursor {
handle: HCURSOR,
}

#[derive(Clone, Debug)]
pub struct WinCursor {
inner: Arc<RaiiCursor>,
}

impl WinCursor {
pub fn as_raw_handle(&self) -> HICON {
self.inner.handle
}

pub fn from_handle(handle: HCURSOR) -> Self {
Self {
inner: Arc::new(RaiiCursor { handle }),
}
}

pub fn new_cursor(image: &CursorImage) -> Self {
let mut bgra = image.rgba.clone();
Expand Down Expand Up @@ -192,36 +233,24 @@ impl WinIcon {
panic!("Failed to create icon");
}

WinIcon::from_handle(handle)
Self::from_handle(handle)
}
}

impl Drop for RaiiCursor {
fn drop(&mut self) {
unsafe { DestroyCursor(self.handle) };
}
}

#[derive(Debug, Clone)]
pub enum SelectedCursor {
Named(CursorIcon),
Custom(WinIcon),
Custom(WinCursor),
}

impl Default for SelectedCursor {
fn default() -> Self {
Self::Named(Default::default())
}
}

impl Drop for RaiiIcon {
fn drop(&mut self) {
unsafe { DestroyIcon(self.handle) };
}
}

impl fmt::Debug for WinIcon {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
(*self.inner).fmt(formatter)
}
}

pub fn unset_for_window(hwnd: HWND, icon_type: IconType) {
unsafe {
SendMessageW(hwnd, WM_SETICON, icon_type as usize, 0);
}
}
6 changes: 3 additions & 3 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ use crate::{
dpi::{dpi_to_scale_factor, enable_non_client_dpi_scaling, hwnd_dpi},
drop_handler::FileDropHandler,
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID},
icon::{self, IconType},
icon::{self, IconType, WinCursor},
ime::ImeContext,
keyboard::KeyEventBuilder,
monitor::{self, MonitorHandle},
util,
window_state::{CursorFlags, SavedWindow, WindowFlags, WindowState},
Fullscreen, PlatformSpecificWindowBuilderAttributes, SelectedCursor, WinIcon, WindowId,
Fullscreen, PlatformSpecificWindowBuilderAttributes, SelectedCursor, WindowId,
},
window::{
CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
Expand Down Expand Up @@ -406,7 +406,7 @@ impl Window {

#[inline]
pub fn set_custom_cursor(&self, cursor: CustomCursor) {
let new_cursor = WinIcon::new_cursor(&cursor.inner);
let new_cursor = WinCursor::new_cursor(&cursor.inner);
let handle = new_cursor.as_raw_handle();
self.window_state_lock().mouse.selected_cursor = SelectedCursor::Custom(new_cursor);
self.thread_executor.execute_in_thread(move || unsafe {
Expand Down

0 comments on commit ff11721

Please sign in to comment.