Open Imberflur opened 1 year ago
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?
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.