[WIP] Cursor visibility (#170)

* Cursor visibility

* Implement cursor visiblity for X11 and Wayland

* Implement cursor visibility for Windows

* Implement cursor visibility on Redox

* Implement cursor visiblity for OSX

* Semicolons

* Wrong method

* Missing argument

Co-authored-by: Antonino Siena <a.siena@gmx.de>
This commit is contained in:
Antonino Siena 2020-04-21 15:13:12 +02:00 committed by GitHub
parent f769fe60ca
commit b4adefd9d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 125 additions and 1 deletions

View file

@ -383,6 +383,15 @@ impl Window {
.set_background_color(((r << 16) | (g << 8) | b) as u32); .set_background_color(((r << 16) | (g << 8) | b) as u32);
} }
///
/// Changes whether or not the cursor image should be shown or if the cursor image
/// should be invisible inside the window
/// When creating a new window the default is 'false'
#[inline]
pub fn set_cursor_visibility(&mut self, visibility: bool) {
self.0.set_cursor_visibility(visibility);
}
/// ///
/// Limits the update rate of polling for new events in order to reduce CPU usage. /// Limits the update rate of polling for new events in order to reduce CPU usage.
/// The problem of having a tight loop that does something like this /// The problem of having a tight loop that does something like this

View file

@ -423,6 +423,16 @@ void mfb_set_title(void* window, const char* title)
[win setTitle: ns_title]; [win setTitle: ns_title];
} }
void mfb_set_cursor_visibility(void *window, bool visibility)
{
if (visibility){
[NSCursor unhide];
}
else{
[NSCursor hide];
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mfb_close(void* win) void mfb_close(void* win)

View file

@ -182,6 +182,7 @@ extern "C" {
); );
fn mfb_set_mouse_data(window_handle: *mut c_void, shared_data: *mut SharedData); fn mfb_set_mouse_data(window_handle: *mut c_void, shared_data: *mut SharedData);
fn mfb_set_cursor_style(window: *mut c_void, cursor: u32); fn mfb_set_cursor_style(window: *mut c_void, cursor: u32);
fn mfb_set_cursor_visibility(window: *mut c_void, visibility: bool);
fn mfb_should_close(window: *mut c_void) -> i32; fn mfb_should_close(window: *mut c_void) -> i32;
fn mfb_get_screen_size() -> u32; fn mfb_get_screen_size() -> u32;
fn mfb_is_active(window: *mut c_void) -> u32; fn mfb_is_active(window: *mut c_void) -> u32;
@ -351,6 +352,13 @@ impl Window {
self.shared_data.bg_color = color; self.shared_data.bg_color = color;
} }
#[inline]
pub fn set_cursor_visibility(&mut self, visibility: bool) {
unsafe {
mfb_set_cursor_visibility(self.window_handle, visibility);
}
}
pub fn update_with_buffer_stride( pub fn update_with_buffer_stride(
&mut self, &mut self,
buffer: &[u32], buffer: &[u32],

View file

@ -184,6 +184,10 @@ impl Window {
// Orbital doesn't support cursor styles yet // Orbital doesn't support cursor styles yet
} }
pub fn set_cursor_visibility(&mut self, visibility: bool) {
self.window.set_mouse_cursor(visibility);
}
pub fn get_keys(&self) -> Option<Vec<Key>> { pub fn get_keys(&self) -> Option<Vec<Key>> {
self.key_handler.get_keys() self.key_handler.get_keys()
} }

View file

@ -112,6 +112,15 @@ impl Window {
} }
} }
pub fn set_cursor_visibility(&mut self, visibility: bool) {
match *self {
#[cfg(feature = "x11")]
Window::X11(ref mut w) => w.set_cursor_visibility(visibility),
#[cfg(feature = "wayland")]
Window::Wayland(ref mut w) => w.set_cursor_visibility(visibility),
}
}
pub fn set_position(&mut self, x: isize, y: isize) { pub fn set_position(&mut self, x: isize, y: isize) {
match *self { match *self {
#[cfg(feature = "x11")] #[cfg(feature = "x11")]

View file

@ -501,6 +501,7 @@ pub struct Window {
buffer: Vec<u32>, buffer: Vec<u32>,
// Resolution, closed // Resolution, closed
toplevel_info: (ToplevelResolution, ToplevelClosed), toplevel_info: (ToplevelResolution, ToplevelClosed),
pointer_visibility: bool,
} }
impl Window { impl Window {
@ -562,6 +563,7 @@ impl Window {
resizable: opts.resize, resizable: opts.resize,
buffer: Vec::with_capacity(width * height * scale as usize * scale as usize), buffer: Vec::with_capacity(width * height * scale as usize * scale as usize),
toplevel_info: (resolution, closed), toplevel_info: (resolution, closed),
pointer_visibility: false,
}) })
} }
@ -573,6 +575,10 @@ impl Window {
self.bg_color = bg_color; self.bg_color = bg_color;
} }
pub fn set_cursor_visibility(&mut self, visibility: bool) {
self.pointer_visibility = visibility;
}
pub fn is_open(&self) -> bool { pub fn is_open(&self) -> bool {
!self.should_close !self.should_close
} }
@ -785,6 +791,17 @@ impl Window {
self.display self.display
.update_cursor(Self::decode_cursor(self.prev_cursor)) .update_cursor(Self::decode_cursor(self.prev_cursor))
.unwrap(); .unwrap();
if self.pointer_visibility {
self.input.get_pointer().set_cursor(
serial,
Some(&self.display.cursor_surface),
0,
0,
);
} else {
self.input.get_pointer().set_cursor(serial, None, 0, 0);
}
} }
Event::Motion { Event::Motion {
surface_x, surface_x,
@ -794,7 +811,12 @@ impl Window {
self.mouse_x = surface_x as f32; self.mouse_x = surface_x as f32;
self.mouse_y = surface_y as f32; self.mouse_y = surface_y as f32;
} }
Event::Button { button, state, .. } => { Event::Button {
button,
state,
serial,
..
} => {
use wayland_client::protocol::wl_pointer::ButtonState; use wayland_client::protocol::wl_pointer::ButtonState;
let pressed = state == ButtonState::Pressed; let pressed = state == ButtonState::Pressed;
@ -811,6 +833,17 @@ impl Window {
// the Linux kernel) // the Linux kernel)
} }
} }
if self.pointer_visibility {
self.input.get_pointer().set_cursor(
serial,
Some(&self.display.cursor_surface),
0,
0,
);
} else {
self.input.get_pointer().set_cursor(serial, None, 0, 0);
}
} }
Event::Axis { axis, value, .. } => { Event::Axis { axis, value, .. } => {
use wayland_client::protocol::wl_pointer::Axis; use wayland_client::protocol::wl_pointer::Axis;
@ -841,6 +874,18 @@ impl Window {
let _ = (axis, discrete); let _ = (axis, discrete);
// TODO // TODO
} }
Event::Leave { serial, .. } => {
if self.pointer_visibility {
self.input.get_pointer().set_cursor(
serial,
Some(&self.display.cursor_surface),
0,
0,
);
} else {
self.input.get_pointer().set_cursor(serial, None, 0, 0);
}
}
_ => {} _ => {}
} }
} }

View file

@ -567,6 +567,39 @@ impl Window {
self.bg_color = bg_color; self.bg_color = bg_color;
} }
#[inline]
pub fn set_cursor_visibility(&mut self, visibility: bool) {
unsafe {
if visibility {
(self.d.lib.XDefineCursor)(
self.d.display,
self.handle,
self.d.cursors[self.prev_cursor as usize],
);
} else {
static empty: [c_char; 8] = [0; 8];
let mut color = std::mem::zeroed();
let pixmap = (self.d.lib.XCreateBitmapFromData)(
self.d.display,
self.handle,
empty.as_ptr(),
8,
8,
);
let cursor = (self.d.lib.XCreatePixmapCursor)(
self.d.display,
pixmap,
pixmap,
&mut color as *mut _,
&mut color as *mut _,
0,
0,
);
(self.d.lib.XDefineCursor)(self.d.display, self.handle, cursor);
}
}
}
#[inline] #[inline]
pub fn set_position(&mut self, x: isize, y: isize) { pub fn set_position(&mut self, x: isize, y: isize) {
unsafe { unsafe {

View file

@ -797,6 +797,12 @@ impl Window {
} }
} }
pub fn set_cursor_visibility(&mut self, visibility: bool) {
unsafe {
winuser::ShowCursor(visibility as i32);
}
}
pub fn update_with_buffer_stride( pub fn update_with_buffer_stride(
&mut self, &mut self,
buffer: &[u32], buffer: &[u32],