Add cursor locking support for X11
As noted in https://github.com/rust-windowing/winit/issues/1677 locking the cursor (rather than just confining to the window) can be useful for cases like camera control. winit does not currently provide cursor locking for Windows and X11 but the information in that issue indicates that it should be possible for Windows and is maybe(?) possible for X11.
Hacking around it isn't too bad. This is what I've been using on a recent project of mine. Haven't tested windows yet but x11(XWayland) seems to work.
#[derive(Default)]
struct MouseGrabber {
last_pos: PhysicalPosition<f64>,
manual_lock: bool,
}
impl MouseGrabber {
// Call this on every WindowEvent::CursorMoved to update the last known position
fn cursor_moved(&mut self, window: &Window, pos: PhysicalPosition<f64>) {
if self.manual_lock {
window.set_cursor_position(self.last_pos).unwrap();
} else {
self.last_pos = pos;
}
}
// Call this with true to lock and false to unlock
fn grab(&mut self, window: &Window, grab: bool) {
if grab {
if window.set_cursor_grab(CursorGrabMode::Locked).is_err() {
window.set_cursor_grab(CursorGrabMode::Confined).unwrap();
self.manual_lock = true;
}
} else {
self.manual_lock = false;
window.set_cursor_grab(CursorGrabMode::None).unwrap();
}
window.set_cursor_visible(!grab);
}
}
This puts the mouse back to its last unlocked position, but it could probably be made simpler if you just wanted to lock to the center of the window.
@GiantBlargg thanks for sharing a workaround!
You can also submit this upstream, just saying. It's not like it'll be any different....
Is there any reason or hurdles to implementing cursor locking in winit itself, rather than using this workaround?
I'd also like to know if there is a reason why this is not implemented on Windows?
It seems very easy to implement by just taking the current cursor position and setting the cursor clipping window to just this position: https://github.com/dbartussek/winit/commit/dbd7cbdfc09252a7bfb1fda95e6607b2040c1ba7 Is there some hidden pitfall here I'm not seeing?
Windows part done.
When will the X11 part be implemented?
When someone implements it.