Add `window::Action::CursorGrab` and `mouse::Event::MouseMotion`
Together they allow you to confine or lock the cursor, and still recive mouse events.
Corresponds to winit::window::CursorGrabMode and winit::event::DeviceEvent::MouseMotion respectively.
Some use cases they allow are panning in viewports and inputs that can be dragged like sliders without a range, these can be implemented using the cursor position but lead to bad UX from the cursor exiting the window or hitting the edge of the monitor, making you have to stop the interaction and reposition the cursor. Blender is a good example of both of these behaviors.
Unfortunately, there are currently some pretty big limitations, stemming from winit (and potentially platform limitations):
winit::event::DeviceEvent::MouseMotionuses raw (unaccelerated) mouse input. This really hurts usability and the reason this is a draft PR. I'm looking into solving this in winit, probably by adding awinit::event::WindowEvent::MouseMotioncounterpart that is accelerated (and will also be specific to a window instead of being sent to all windows), this is very straight forward on wayland (the event is on a toplevel (window), and gives both accelerated and unaccelerated), but I'm not sure about other platforms.- Platform support is not great for
CursorGrab, it works out that there's exactly one mode that is guaranteed to work for each platform (on linuxCursorGrab::Confinedworks for both wayland and x11). - There's no ability to set a region in
CursorGrab::Confined, which happens to be particularly useful for GUIs.
I just needed this today, would be happy to see this finished and merged :)