Fixes cursor behavior with windows

This commit is contained in:
Rengierof 2015-12-26 16:38:00 +02:00
parent f76aba3d37
commit 11e27889ae
4 changed files with 41 additions and 23 deletions

View file

@ -11,15 +11,15 @@ mod support;
#[cfg(target_os = "android")]
android_start!(main);
fn main() {
fn main() {
let window = glutin::WindowBuilder::new().build().unwrap();
window.set_title("A fantastic window!");
window.set_title("A fantastic window!");
unsafe { window.make_current().unwrap() };
let context = support::load(&window);
let cursors = [MouseCursor::Default, MouseCursor::Crosshair, MouseCursor::Hand, MouseCursor::Arrow, MouseCursor::Move, MouseCursor::Text, MouseCursor::Wait, MouseCursor::Help, MouseCursor::Progress, MouseCursor::NotAllowed, MouseCursor::ContextMenu, MouseCursor::NoneCursor, MouseCursor::Cell, MouseCursor::VerticalText, MouseCursor::Alias, MouseCursor::Copy, MouseCursor::NoDrop, MouseCursor::Grab, MouseCursor::Grabbing, MouseCursor::AllScroll, MouseCursor::ZoomIn, MouseCursor::ZoomOut, MouseCursor::EResize, MouseCursor::NResize, MouseCursor::NeResize, MouseCursor::NwResize, MouseCursor::SResize, MouseCursor::SeResize, MouseCursor::SwResize, MouseCursor::WResize, MouseCursor::EwResize, MouseCursor::NsResize, MouseCursor::NeswResize, MouseCursor::NwseResize, MouseCursor::ColResize, MouseCursor::RowResize];
let mut cursor_idx = 0;
for event in window.wait_events() {
match event {
Event::KeyboardInput(ElementState::Pressed, _, _) => {

View file

@ -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());

View file

@ -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()
}));

View file

@ -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
}
@ -112,7 +116,7 @@ impl Window {
let opengl = opengl.clone().map_sharing(|sharing| {
match sharing.context {
Context::Wgl(ref c) => RawContext::Wgl(c.get_hglrc()),
Context::Egl(_) => unimplemented!(), // FIXME:
Context::Egl(_) => unimplemented!(), // FIXME:
}
});
@ -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;
Ok(())
}
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;
Ok(())
}
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(())
}
},