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:
Francesca Frangipane 2018-06-18 12:32:18 -04:00 committed by GitHub
parent 042f5fe4b3
commit fb7528c239
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 326 additions and 313 deletions

View file

@ -27,7 +27,6 @@ use objc::declare::ClassDecl;
use {
CreationError,
CursorState,
Event,
LogicalPosition,
LogicalSize,
@ -527,6 +526,7 @@ pub struct Window2 {
pub window: IdRef,
pub delegate: WindowDelegate,
pub input_context: IdRef,
cursor_hidden: Cell<bool>,
}
unsafe impl Send for Window2 {}
@ -674,6 +674,7 @@ impl Window2 {
window: window,
delegate: WindowDelegate::new(delegate_state),
input_context,
cursor_hidden: Default::default(),
};
// Set fullscreen mode after we setup everything
@ -980,7 +981,7 @@ impl Window2 {
MouseCursor::SeResize | MouseCursor::SwResize |
MouseCursor::NwseResize | MouseCursor::NeswResize |
MouseCursor::Cell | MouseCursor::NoneCursor |
MouseCursor::Cell |
MouseCursor::Wait | MouseCursor::Progress | MouseCursor::Help |
MouseCursor::Move | MouseCursor::AllScroll | MouseCursor::ZoomIn |
MouseCursor::ZoomOut => "arrowCursor",
@ -994,25 +995,25 @@ impl Window2 {
}
}
pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
let cls = Class::get("NSCursor").unwrap();
#[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
// TODO: Do this for real https://stackoverflow.com/a/40922095/5435443
CGDisplay::associate_mouse_and_mouse_cursor_position(!grab)
.map_err(|status| format!("Failed to grab cursor: `CGError` {:?}", status))
}
// TODO: Check for errors.
match state {
CursorState::Normal => {
let _: () = unsafe { msg_send![cls, unhide] };
let _ = CGDisplay::associate_mouse_and_mouse_cursor_position(true);
Ok(())
},
CursorState::Hide => {
let _: () = unsafe { msg_send![cls, hide] };
Ok(())
},
CursorState::Grab => {
let _: () = unsafe { msg_send![cls, hide] };
let _ = CGDisplay::associate_mouse_and_mouse_cursor_position(false);
Ok(())
#[inline]
pub fn hide_cursor(&self, hide: bool) {
let cursor_class = Class::get("NSCursor").unwrap();
// macOS uses a "hide counter" like Windows does, so we avoid incrementing it more than once.
// (otherwise, `hide_cursor(false)` would need to be called n times!)
if hide != self.cursor_hidden.get() {
if hide {
let _: () = unsafe { msg_send![cursor_class, hide] };
} else {
let _: () = unsafe { msg_send![cursor_class, unhide] };
}
self.cursor_hidden.replace(hide);
}
}