https://bugs.winehq.org/show_bug.cgi?id=56208
--- Comment #1 from Sandor korbel00@gmail.com --- I let the problem sink in and reread what I wrote, and I think I need to make some corrections.
there cannot be a new motion between calling GetCursorPos and SetCursorPos, and the next motion after SetCursorPos should be the center of the screen.
It's not necessary for the next motion after SetCursorPos to be the coordinates of the SetCursorPos call. What's important is that if the game calls GetCursorPos and SetCursorPos after each other, the positions must show up in the message queue after each other in the same order sometime in the future. I.e. GetCursorPos returns (X1,Y1) and then I call SetCursorPos (X2,Y2) immediately after, then I expect to receive an (X1,Y1) and a (X2,Y2) after each other using the PeekMessage call. But (X1,Y1) is not there right now.
GetCursorPos by default gives back the position from the wine server
This is incorrect but apparently it look like that in the logs. X11 does not take into account the output buffer, and sends back an "old" position (the last known position by the wine server) which is the cause of the whole issue. I think if we could somehow force X11 to send all buffered events to wine before returning the latest cursor position, there wouldn't be any ignored events after SetCursorPos and it would solve the issue. Maybe calling XSync(display, TRUE) before getting the actual cursor position would help? Not sure about that. After a quick try it didn't work out too well.
Putting this aside, I still think raw input events is the way to go and it does not make much sense to me to listen and process the X11DRV_MouseMotion events at the same time for the same events and sync the X11 position to the wine server regularly. X11DRV_MouseMotion messages should be filtered and the sync should happen in the other direction in this case.