Change create_custom_cursor() to return Result (#3844)
This commit is contained in:
parent
29e1041987
commit
f5304815a1
17 changed files with 141 additions and 87 deletions
|
|
@ -58,7 +58,7 @@ use super::window::set_skip_taskbar;
|
|||
use super::SelectedCursor;
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use crate::error::EventLoopError;
|
||||
use crate::error::{EventLoopError, ExternalError};
|
||||
use crate::event::{
|
||||
Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase, WindowEvent,
|
||||
};
|
||||
|
|
@ -483,16 +483,11 @@ impl ActiveEventLoop {
|
|||
EventLoopThreadExecutor { thread_id: self.thread_id, target_window: self.thread_msg_target }
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor {
|
||||
let inner = match WinCursor::new(&source.inner.0) {
|
||||
Ok(cursor) => cursor,
|
||||
Err(err) => {
|
||||
tracing::warn!("Failed to create custom cursor: {err}");
|
||||
WinCursor::Failed
|
||||
},
|
||||
};
|
||||
|
||||
RootCustomCursor { inner }
|
||||
pub fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: WinCursor::new(&source.inner.0)? })
|
||||
}
|
||||
|
||||
// TODO: Investigate opportunities for caching
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{
|
|||
use super::util;
|
||||
use crate::cursor::CursorImage;
|
||||
use crate::dpi::PhysicalSize;
|
||||
use crate::error::ExternalError;
|
||||
use crate::icon::*;
|
||||
|
||||
impl Pixel {
|
||||
|
|
@ -175,13 +176,10 @@ impl Default for SelectedCursor {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
|
||||
pub enum WinCursor {
|
||||
Cursor(Arc<RaiiCursor>),
|
||||
Failed,
|
||||
}
|
||||
pub struct WinCursor(pub(super) Arc<RaiiCursor>);
|
||||
|
||||
impl WinCursor {
|
||||
pub(crate) fn new(image: &CursorImage) -> Result<Self, io::Error> {
|
||||
pub(crate) fn new(image: &CursorImage) -> Result<Self, ExternalError> {
|
||||
let mut bgra = image.rgba.clone();
|
||||
bgra.chunks_exact_mut(4).for_each(|chunk| chunk.swap(0, 2));
|
||||
|
||||
|
|
@ -191,16 +189,16 @@ impl WinCursor {
|
|||
unsafe {
|
||||
let hdc_screen = GetDC(0);
|
||||
if hdc_screen == 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||
}
|
||||
let hbm_color = CreateCompatibleBitmap(hdc_screen, w, h);
|
||||
ReleaseDC(0, hdc_screen);
|
||||
if hbm_color == 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||
}
|
||||
if SetBitmapBits(hbm_color, bgra.len() as u32, bgra.as_ptr() as *const c_void) == 0 {
|
||||
DeleteObject(hbm_color);
|
||||
return Err(io::Error::last_os_error());
|
||||
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||
};
|
||||
|
||||
// Mask created according to https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createbitmap#parameters
|
||||
|
|
@ -208,7 +206,7 @@ impl WinCursor {
|
|||
let hbm_mask = CreateBitmap(w, h, 1, 1, mask_bits.as_ptr() as *const _);
|
||||
if hbm_mask == 0 {
|
||||
DeleteObject(hbm_color);
|
||||
return Err(io::Error::last_os_error());
|
||||
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||
}
|
||||
|
||||
let icon_info = ICONINFO {
|
||||
|
|
@ -223,10 +221,10 @@ impl WinCursor {
|
|||
DeleteObject(hbm_color);
|
||||
DeleteObject(hbm_mask);
|
||||
if handle == 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||
}
|
||||
|
||||
Ok(Self::Cursor(Arc::new(RaiiCursor { handle })))
|
||||
Ok(Self(Arc::new(RaiiCursor { handle })))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ use crate::platform_impl::platform::dpi::{
|
|||
};
|
||||
use crate::platform_impl::platform::drop_handler::FileDropHandler;
|
||||
use crate::platform_impl::platform::event_loop::{self, ActiveEventLoop, DESTROY_MSG_ID};
|
||||
use crate::platform_impl::platform::icon::{self, IconType, WinCursor};
|
||||
use crate::platform_impl::platform::icon::{self, IconType};
|
||||
use crate::platform_impl::platform::ime::ImeContext;
|
||||
use crate::platform_impl::platform::keyboard::KeyEventBuilder;
|
||||
use crate::platform_impl::platform::monitor::{self, MonitorHandle};
|
||||
|
|
@ -383,17 +383,10 @@ impl Window {
|
|||
});
|
||||
},
|
||||
Cursor::Custom(cursor) => {
|
||||
let new_cursor = match cursor.inner {
|
||||
WinCursor::Cursor(cursor) => cursor,
|
||||
WinCursor::Failed => {
|
||||
warn!("Requested to apply failed cursor");
|
||||
return;
|
||||
},
|
||||
};
|
||||
self.window_state_lock().mouse.selected_cursor =
|
||||
SelectedCursor::Custom(new_cursor.clone());
|
||||
SelectedCursor::Custom(cursor.inner.0.clone());
|
||||
self.thread_executor.execute_in_thread(move || unsafe {
|
||||
SetCursor(new_cursor.as_raw_handle());
|
||||
SetCursor(cursor.inner.0.as_raw_handle());
|
||||
});
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue