mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-26 23:21:30 +11:00
f6d26df64d
* Windows: CursorState improvements Fixes #523 Prior to changing the cursor state, we now check the current grab state, since it can be invalidated by alt-tabbing and other things. `CursorState::Hide` is also implemented now. The cursor name is now wrapped in a `Cursor` struct to allow multithreaded access. `Window::set_cursor_state` has been reworked to use `execute_in_thread`. Two unneeded `transmute` calls were also removed. The `WM_SETCURSOR` handler is much more readable now. `MonitorId::get_adapter_name` has been removed, since it's dead code and appears to be a relic from 4 years ago. * Windows: CursorState::Grab no longer hides cursor `MouseCursor::NoneCursor` has been implemented to allow for equivalent behavior to the older implementation. Windows and X11 now have consistent cursor grabbing behavior. macOS still needs to be updated. * Windows: Grabbing auto-hides again (for now) This API needs more work, so let's stick to a bug fix and some refactoring. However, it now hides using a different technique than it did originally, which applies instantly instead of after mouse movement.
83 lines
2.2 KiB
Rust
83 lines
2.2 KiB
Rust
use std::{self, mem, ptr};
|
|
use std::ops::BitAnd;
|
|
|
|
use winapi::ctypes::wchar_t;
|
|
use winapi::shared::minwindef::DWORD;
|
|
use winapi::shared::windef::RECT;
|
|
use winapi::um::errhandlingapi::GetLastError;
|
|
use winapi::um::winbase::{
|
|
FormatMessageW,
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
|
FORMAT_MESSAGE_FROM_SYSTEM,
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
lstrlenW,
|
|
LocalFree,
|
|
};
|
|
use winapi::um::winnt::{
|
|
LPCWSTR,
|
|
MAKELANGID,
|
|
LANG_NEUTRAL,
|
|
SUBLANG_DEFAULT,
|
|
};
|
|
|
|
pub fn has_flag<T>(bitset: T, flag: T) -> bool
|
|
where T:
|
|
Copy + PartialEq + BitAnd<T, Output = T>
|
|
{
|
|
bitset & flag == flag
|
|
}
|
|
|
|
pub fn wchar_to_string(wchar: &[wchar_t]) -> String {
|
|
String::from_utf16_lossy(wchar)
|
|
.trim_right_matches(0 as char)
|
|
.to_string()
|
|
}
|
|
|
|
// This won't be needed anymore if we just add a derive to winapi.
|
|
pub fn rect_eq(a: &RECT, b: &RECT) -> bool {
|
|
let left_eq = a.left == b.left;
|
|
let right_eq = a.right == b.right;
|
|
let top_eq = a.top == b.top;
|
|
let bottom_eq = a.bottom == b.bottom;
|
|
left_eq && right_eq && top_eq && bottom_eq
|
|
}
|
|
|
|
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
|
pub struct WinError(Option<String>);
|
|
|
|
impl WinError {
|
|
pub fn from_last_error() -> Self {
|
|
WinError(unsafe { get_last_error() })
|
|
}
|
|
}
|
|
|
|
pub unsafe fn get_last_error() -> Option<String> {
|
|
let err = GetLastError();
|
|
if err != 0 {
|
|
let buf_addr: LPCWSTR = {
|
|
let mut buf_addr: LPCWSTR = mem::uninitialized();
|
|
FormatMessageW(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
|
| FORMAT_MESSAGE_FROM_SYSTEM
|
|
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
ptr::null(),
|
|
err,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) as DWORD,
|
|
// This is a pointer to a pointer
|
|
&mut buf_addr as *mut LPCWSTR as *mut _,
|
|
0,
|
|
ptr::null_mut(),
|
|
);
|
|
buf_addr
|
|
};
|
|
if !buf_addr.is_null() {
|
|
let buf_len = lstrlenW(buf_addr) as usize;
|
|
let buf_slice = std::slice::from_raw_parts(buf_addr, buf_len);
|
|
let string = wchar_to_string(buf_slice);
|
|
LocalFree(buf_addr as *mut _);
|
|
return Some(string);
|
|
}
|
|
}
|
|
None
|
|
}
|