grab_cursor and hide_cursor (#571)
* Windows: Use new cursor state API * X11: Use new cursor state API * macOS: Use new cursor state API * Android+iOS: Stubbed new cursor state API * Emscripten: Use new cursor state API * Prevent multiple inc/dec of display count on Windows * Fixed missing imports (no idea where those went) * Remove NoneCursor * Improved documentation * Fix Emscripten build * Windows: Re-grab before and after fullscreen
This commit is contained in:
parent
042f5fe4b3
commit
fb7528c239
15 changed files with 326 additions and 313 deletions
|
|
@ -150,7 +150,8 @@ impl EventsLoop {
|
|||
pub struct WindowId(usize);
|
||||
|
||||
pub struct Window2 {
|
||||
cursor_state: Mutex<::CursorState>,
|
||||
cursor_grabbed: Mutex<bool>,
|
||||
cursor_hidden: Mutex<bool>,
|
||||
is_fullscreen: bool,
|
||||
events: Box<Mutex<VecDeque<::Event>>>,
|
||||
}
|
||||
|
|
@ -374,7 +375,8 @@ impl Window {
|
|||
}
|
||||
|
||||
let w = Window2 {
|
||||
cursor_state: Default::default(),
|
||||
cursor_grabbed: Default::default(),
|
||||
cursor_hidden: Default::default(),
|
||||
events: Default::default(),
|
||||
is_fullscreen: attribs.fullscreen.is_some(),
|
||||
};
|
||||
|
|
@ -498,48 +500,57 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show(&self) {}
|
||||
#[inline]
|
||||
pub fn hide(&self) {}
|
||||
pub fn show(&self) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, _cursor: ::MouseCursor) {}
|
||||
pub fn hide(&self) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_state(&self, state: ::CursorState) -> Result<(), String> {
|
||||
pub fn set_cursor(&self, _cursor: ::MouseCursor) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
||||
let mut grabbed_lock = self.window.cursor_grabbed.lock().unwrap();
|
||||
if grab == *grabbed_lock { return Ok(()); }
|
||||
unsafe {
|
||||
use ::CursorState::*;
|
||||
|
||||
let mut old_state = self.window.cursor_state.lock().unwrap();
|
||||
if state == *old_state {
|
||||
return Ok(());
|
||||
if grab {
|
||||
em_try(ffi::emscripten_set_pointerlockchange_callback(
|
||||
ptr::null(),
|
||||
0 as *mut c_void,
|
||||
ffi::EM_FALSE,
|
||||
Some(pointerlockchange_callback),
|
||||
))?;
|
||||
em_try(ffi::emscripten_request_pointerlock(ptr::null(), ffi::EM_TRUE))?;
|
||||
} else {
|
||||
em_try(ffi::emscripten_set_pointerlockchange_callback(
|
||||
ptr::null(),
|
||||
0 as *mut c_void,
|
||||
ffi::EM_FALSE,
|
||||
None,
|
||||
))?;
|
||||
em_try(ffi::emscripten_exit_pointerlock())?;
|
||||
}
|
||||
|
||||
// Set or unset grab callback
|
||||
match state {
|
||||
Hide | Normal => em_try(ffi::emscripten_set_pointerlockchange_callback(ptr::null(), 0 as *mut c_void, ffi::EM_FALSE, None))?,
|
||||
Grab => em_try(ffi::emscripten_set_pointerlockchange_callback(ptr::null(), 0 as *mut c_void, ffi::EM_FALSE, Some(pointerlockchange_callback)))?,
|
||||
}
|
||||
|
||||
// Go back to normal cursor state
|
||||
match *old_state {
|
||||
Hide => show_mouse(),
|
||||
Grab => em_try(ffi::emscripten_exit_pointerlock())?,
|
||||
Normal => (),
|
||||
}
|
||||
|
||||
// Set cursor from normal cursor state
|
||||
match state {
|
||||
Hide => ffi::emscripten_hide_mouse(),
|
||||
Grab => em_try(ffi::emscripten_request_pointerlock(ptr::null(), ffi::EM_TRUE))?,
|
||||
Normal => (),
|
||||
}
|
||||
|
||||
// Update
|
||||
*old_state = state;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
*grabbed_lock = grab;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide_cursor(&self, hide: bool) {
|
||||
let mut hidden_lock = self.window.cursor_hidden.lock().unwrap();
|
||||
if hide == *hidden_lock { return; }
|
||||
if hide {
|
||||
unsafe { ffi::emscripten_hide_mouse() };
|
||||
} else {
|
||||
show_mouse();
|
||||
}
|
||||
*hidden_lock = hide;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -610,7 +621,8 @@ impl Drop for Window {
|
|||
|
||||
unsafe {
|
||||
// Return back to normal cursor state
|
||||
let _ = self.set_cursor_state(::CursorState::Normal);
|
||||
self.hide_cursor(false);
|
||||
self.grab_cursor(false);
|
||||
|
||||
// Exit fullscreen if on
|
||||
if self.window.is_fullscreen {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue