mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
Fixes cursor behavior with windows
This commit is contained in:
parent
f76aba3d37
commit
11e27889ae
|
@ -256,7 +256,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT,
|
|||
CursorState::Normal => {
|
||||
user32::SetCursor(user32::LoadCursorW(
|
||||
ptr::null_mut(),
|
||||
winapi::IDC_ARROW));
|
||||
window_state.cursor));
|
||||
},
|
||||
CursorState::Grab | CursorState::Hide => {
|
||||
user32::SetCursor(ptr::null_mut());
|
||||
|
|
|
@ -217,6 +217,7 @@ unsafe fn init(title: Vec<u16>, window: &WindowAttributes, pf_reqs: &PixelFormat
|
|||
|
||||
// Creating a mutex to track the current window state
|
||||
let window_state = Arc::new(Mutex::new(WindowState {
|
||||
cursor: winapi::IDC_ARROW, // use arrow by default
|
||||
cursor_state: CursorState::Normal,
|
||||
attributes: window.clone()
|
||||
}));
|
||||
|
|
|
@ -42,9 +42,13 @@ lazy_static! {
|
|||
static ref WAKEUP_MSG_ID: u32 = unsafe { user32::RegisterWindowMessageA("Glutin::EventID".as_ptr() as *const i8) };
|
||||
}
|
||||
|
||||
/// Cursor
|
||||
pub type Cursor = *const u16;
|
||||
|
||||
/// Contains information about states and the window for the callback.
|
||||
#[derive(Clone)]
|
||||
pub struct WindowState {
|
||||
pub cursor: Cursor,
|
||||
pub cursor_state: CursorState,
|
||||
pub attributes: WindowAttributes
|
||||
}
|
||||
|
@ -261,41 +265,55 @@ impl Window {
|
|||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, _cursor: MouseCursor) {
|
||||
unimplemented!()
|
||||
let cursor_id = match _cursor {
|
||||
MouseCursor::Arrow | MouseCursor::Default => winapi::IDC_ARROW,
|
||||
MouseCursor::Hand => winapi::IDC_HAND,
|
||||
MouseCursor::Crosshair => winapi::IDC_CROSS,
|
||||
MouseCursor::Text | MouseCursor::VerticalText => winapi::IDC_IBEAM,
|
||||
MouseCursor::NotAllowed | MouseCursor::NoDrop => winapi::IDC_NO,
|
||||
MouseCursor::EResize => winapi::IDC_SIZEWE,
|
||||
MouseCursor::NResize => winapi::IDC_SIZENS,
|
||||
MouseCursor::WResize => winapi::IDC_SIZEWE,
|
||||
MouseCursor::SResize => winapi::IDC_SIZENS,
|
||||
MouseCursor::EwResize | MouseCursor::ColResize => winapi::IDC_SIZEWE,
|
||||
MouseCursor::NsResize | MouseCursor::RowResize => winapi::IDC_SIZENS,
|
||||
MouseCursor::Wait | MouseCursor::Progress => winapi::IDC_WAIT,
|
||||
MouseCursor::Help => winapi::IDC_HELP,
|
||||
_ => winapi::IDC_ARROW, // use arrow for the missing cases.
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let mut cur = self.window_state.lock().unwrap();
|
||||
cur.cursor = mem::transmute(cursor_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
|
||||
let mut current_state = self.window_state.lock().unwrap().cursor_state;
|
||||
let mut current_state = self.window_state.lock().unwrap();
|
||||
|
||||
let foreground_thread_id = unsafe { user32::GetWindowThreadProcessId(self.window.0, ptr::null_mut()) };
|
||||
let current_thread_id = unsafe { kernel32::GetCurrentThreadId() };
|
||||
|
||||
unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 1) };
|
||||
|
||||
let res = match (state, current_state) {
|
||||
let res = match (state, current_state.cursor_state) {
|
||||
(CursorState::Normal, CursorState::Normal) => Ok(()),
|
||||
(CursorState::Hide, CursorState::Hide) => Ok(()),
|
||||
(CursorState::Grab, CursorState::Grab) => Ok(()),
|
||||
|
||||
(CursorState::Hide, CursorState::Normal) => {
|
||||
unsafe {
|
||||
user32::SetCursor(ptr::null_mut());
|
||||
current_state = CursorState::Hide;
|
||||
current_state.cursor_state = CursorState::Hide;
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
|
||||
(CursorState::Normal, CursorState::Hide) => {
|
||||
unsafe {
|
||||
user32::SetCursor(user32::LoadCursorW(ptr::null_mut(), winapi::IDC_ARROW));
|
||||
current_state = CursorState::Normal;
|
||||
current_state.cursor_state = CursorState::Normal;
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
|
||||
(CursorState::Grab, CursorState::Normal) => {
|
||||
(CursorState::Grab, CursorState::Normal) | (CursorState::Grab, CursorState::Hide) => {
|
||||
unsafe {
|
||||
user32::SetCursor(ptr::null_mut());
|
||||
let mut rect = mem::uninitialized();
|
||||
if user32::GetClientRect(self.window.0, &mut rect) == 0 {
|
||||
return Err(format!("GetWindowRect failed"));
|
||||
|
@ -305,18 +323,17 @@ impl Window {
|
|||
if user32::ClipCursor(&rect) == 0 {
|
||||
return Err(format!("ClipCursor failed"));
|
||||
}
|
||||
current_state = CursorState::Grab;
|
||||
current_state.cursor_state = CursorState::Grab;
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
|
||||
(CursorState::Normal, CursorState::Grab) => {
|
||||
unsafe {
|
||||
user32::SetCursor(user32::LoadCursorW(ptr::null_mut(), winapi::IDC_ARROW));
|
||||
if user32::ClipCursor(ptr::null()) == 0 {
|
||||
return Err(format!("ClipCursor failed"));
|
||||
}
|
||||
current_state = CursorState::Normal;
|
||||
current_state.cursor_state = CursorState::Normal;
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue