mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +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 => {
|
CursorState::Normal => {
|
||||||
user32::SetCursor(user32::LoadCursorW(
|
user32::SetCursor(user32::LoadCursorW(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
winapi::IDC_ARROW));
|
window_state.cursor));
|
||||||
},
|
},
|
||||||
CursorState::Grab | CursorState::Hide => {
|
CursorState::Grab | CursorState::Hide => {
|
||||||
user32::SetCursor(ptr::null_mut());
|
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
|
// Creating a mutex to track the current window state
|
||||||
let window_state = Arc::new(Mutex::new(WindowState {
|
let window_state = Arc::new(Mutex::new(WindowState {
|
||||||
|
cursor: winapi::IDC_ARROW, // use arrow by default
|
||||||
cursor_state: CursorState::Normal,
|
cursor_state: CursorState::Normal,
|
||||||
attributes: window.clone()
|
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) };
|
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.
|
/// Contains information about states and the window for the callback.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WindowState {
|
pub struct WindowState {
|
||||||
|
pub cursor: Cursor,
|
||||||
pub cursor_state: CursorState,
|
pub cursor_state: CursorState,
|
||||||
pub attributes: WindowAttributes
|
pub attributes: WindowAttributes
|
||||||
}
|
}
|
||||||
|
@ -261,41 +265,55 @@ impl Window {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor(&self, _cursor: MouseCursor) {
|
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> {
|
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 foreground_thread_id = unsafe { user32::GetWindowThreadProcessId(self.window.0, ptr::null_mut()) };
|
||||||
let current_thread_id = unsafe { kernel32::GetCurrentThreadId() };
|
let current_thread_id = unsafe { kernel32::GetCurrentThreadId() };
|
||||||
|
|
||||||
unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 1) };
|
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::Normal, CursorState::Normal) => Ok(()),
|
||||||
(CursorState::Hide, CursorState::Hide) => Ok(()),
|
(CursorState::Hide, CursorState::Hide) => Ok(()),
|
||||||
(CursorState::Grab, CursorState::Grab) => Ok(()),
|
(CursorState::Grab, CursorState::Grab) => Ok(()),
|
||||||
|
|
||||||
(CursorState::Hide, CursorState::Normal) => {
|
(CursorState::Hide, CursorState::Normal) => {
|
||||||
unsafe {
|
current_state.cursor_state = CursorState::Hide;
|
||||||
user32::SetCursor(ptr::null_mut());
|
|
||||||
current_state = CursorState::Hide;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
(CursorState::Normal, CursorState::Hide) => {
|
(CursorState::Normal, CursorState::Hide) => {
|
||||||
unsafe {
|
current_state.cursor_state = CursorState::Normal;
|
||||||
user32::SetCursor(user32::LoadCursorW(ptr::null_mut(), winapi::IDC_ARROW));
|
|
||||||
current_state = CursorState::Normal;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
(CursorState::Grab, CursorState::Normal) => {
|
(CursorState::Grab, CursorState::Normal) | (CursorState::Grab, CursorState::Hide) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
user32::SetCursor(ptr::null_mut());
|
|
||||||
let mut rect = mem::uninitialized();
|
let mut rect = mem::uninitialized();
|
||||||
if user32::GetClientRect(self.window.0, &mut rect) == 0 {
|
if user32::GetClientRect(self.window.0, &mut rect) == 0 {
|
||||||
return Err(format!("GetWindowRect failed"));
|
return Err(format!("GetWindowRect failed"));
|
||||||
|
@ -305,18 +323,17 @@ impl Window {
|
||||||
if user32::ClipCursor(&rect) == 0 {
|
if user32::ClipCursor(&rect) == 0 {
|
||||||
return Err(format!("ClipCursor failed"));
|
return Err(format!("ClipCursor failed"));
|
||||||
}
|
}
|
||||||
current_state = CursorState::Grab;
|
current_state.cursor_state = CursorState::Grab;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
(CursorState::Normal, CursorState::Grab) => {
|
(CursorState::Normal, CursorState::Grab) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
user32::SetCursor(user32::LoadCursorW(ptr::null_mut(), winapi::IDC_ARROW));
|
|
||||||
if user32::ClipCursor(ptr::null()) == 0 {
|
if user32::ClipCursor(ptr::null()) == 0 {
|
||||||
return Err(format!("ClipCursor failed"));
|
return Err(format!("ClipCursor failed"));
|
||||||
}
|
}
|
||||||
current_state = CursorState::Normal;
|
current_state.cursor_state = CursorState::Normal;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue