rust-windowing / winit

Window handling library in pure Rust
https://docs.rs/winit/
Apache License 2.0
4.79k stars 891 forks source link

set_cursor_position affects mouse event deltas [macos] #999

Open swiftcoder opened 5 years ago

swiftcoder commented 5 years ago

Calling set_cursor_position does not generate a DeviceEvent::MouseMotion event, but the change in position is added to the delta of the next MouseMotion event.

This is inconvenient to deal with in a client app, since I don't see a (straightforward) way to retrieve the cursor position (i.e. there isn't a simple get_cursor_position), and hence it's complicated to figure out the delta that needs to be subtracted from the next MouseMotion event.

Behaviour only noted on a Mac. Does not repro on Windows.

willdady commented 5 years ago

Maybe stating the obvious here but the implementation calls CGWarpMouseCursorPosition which according to the Apple docs

Moves the mouse cursor without generating events.

Perhaps CGDisplay::move_cursor_to_point should be used instead of CGDisplay::warp_mouse_cursor_position? (I haven't tried it).

willdady commented 5 years ago

Actually, CGDisplayMoveCursorToPoint also doesn't emit events.

No events are generated as a result of this move.

I can see why perhaps this is the way that it is. The user hasn't physically moved their mouse so no "mouse motion" has occurred.

If the goal of winit is to be 100% consistent cross platform perhaps it should dispatch a synthetic event when set_cursor_position is called. I imagine it would need to keep track of the last seen mouse position and create the delta from that and the position passed to set_cursor_position. Maintaining the state of the last mouse position would allow for a get_cursor_position method. But then again maybe that's not a good idea and winit should not add too many 'smarts' on top of the native APIs 🤔

swiftcoder commented 5 years ago

If the goal of winit is to be 100% consistent cross platform perhaps it should dispatch a synthetic event when set_cursor_position is called.

As I understand it, the current behaviour of not generating an event is correct (and matches the behaviour on Windows). But we also need to get rid of the delta movement it attaches to the next event (whenever that occurs).

Basically when set_cursor_position is called, it should pre-emptively subtract the movement from the next delta event.

ShadowElf37 commented 2 months ago

any updates?