[PATCH v9 6/8] winex11.drv: Implement native mouse-movement raw-input using RawMotion.

Rémi Bernon rbernon at codeweavers.com
Thu Aug 1 07:58:20 CDT 2019


On 8/1/19 8:34 AM, Derek Lesho wrote:
> I just tested disabling normal input from RawMotion in oblivion, which
> uses dinput, which does not use rawinput.  Without it, I can not move
> the mouse outside of the confines of the clip even when the pointer is
> invisible / locked.  I think that relative MOUSEMOVE events are still
> supposed to be sent when the cursor is pushing up against the clip,
> which would mean we need to keep the __wine_send_input extra stuff.  I
> have the rest of the changes you requested completed and will submit
> them tomorrow as it's getting late here.
> 
> 
> On Wed, Jul 31, 2019 at 4:04 AM Rémi Bernon <rbernon at codeweavers.com> wrote:
>>
>> On 7/31/19 12:41 AM, Derek Lesho wrote:
>>>> AFAIU the existing RawMotion event handler was sending INPUT messages to
>>>> the server for the sole purpose of emulating and sending raw input
>>>> messages.
>>>
>>> It was my impression that MotionNotify events are ignored when the the
>>> cursor is clipped, due to some bug or problem it.  I went searching to
>>> see whether the case, and I found this:
>>> https://github.com/wine-mirror/wine/commit/0e2b4f99a9f5d97f8da0189037b7516cf1585d45#diff-c78b8a343abe990b307f178fe51c8931R332
>>>
>>> This commit came around the time they were adding raw-input, and it
>>> seems to indicate that there is a problem w/ MotionNotify on a clipped
>>> cursor, but the ignore case isn't there anymore so maybe things have
>>> changed.  Some other reasons I'm skeptical that the RawMotion code
>>> currently in place is only for rawinput events are that
>>>
>>> 1) The input is also sent as WM_MOUSEMOVE by the server, as there was
>>> no previous infrastructure to send raw-input separately and
>>
>> This commit is about warping the cursor, then ignoring the MotionNotify
>> event induced by the warp itself.
>>
>> I can see that the a pre-existing ignore case for MotionNotify events
>> while clipping is active, comes from
>> https://github.com/wine-mirror/wine/commit/8e9b4e0a5c6bee5f72ca2314db26233638f0e1d2
>> and
>> https://github.com/wine-mirror/wine/commit/da9922b40da5bc581815a4357340f3f128e8c5cb,
>> then reverted in
>> https://github.com/wine-mirror/wine/commit/9716d1c8619e5fe68d1ad3ab9a18b106499b3fac.
>>
>> About these commits, I believe that while xinput2 events are received,
>> and because they were translated as both raw input messages and normal
>> input messages, it was maybe redundant to listen to MotionNotify as
>> well. Also, the oldest commit makes me think that there could be some
>> back-and-forth movement issues if MotionNotify events are processed
>> while RawMotion events were delayed.
>>
>> Now regarding the interactions between MotionNotify and RawMotion events
>> while clipping the cursor, AFAICS MotionNotify events are still received
>> when the cursor moves but is blocked by the X11 confine window, with its
>> current position in x,y fields.
>>
>> This means that regardless if the cursor is clipped or not, both
>> MotionNotify and RawMotion events will currently get translated to raw
>> and normal input messages, the raw message position being compared to
>> the current position and converted to relative position, and the normal
>> input message position being clamped with the clipping window and not
>> sent if it is the same as the last known position (see
>> queue_hardware_message in server/queue.c and
>> https://github.com/wine-mirror/wine/commit/3909f51122ffc0f6150fa9758ba47c70dcf6b00e).
>>
>> So with the current code:
>>
>> * If the cursor moved (inside a clipping window), you get a normal input
>> message from either MotionNotify or RawMotion (which ever came first),
>> then two raw input message, one with the corresponding relative
>> movement, and another with 0x0 relative movement. The second normal
>> input message is discarded because the cursor didn't move.
>>
>> * If the cursor is clipped and blocked by confine window, Wine receives
>> (order may vary as well):
>>
>>     * a MotionNotify event with identical position, which is translated
>> to raw input message with 0x0 relative movement, but does not get
>> translated to normal input message because the cursor didn't move.
>>
>>     * a RawMotion event with some relative movement, which is translated
>> to the corresponding raw input message with relative movement, and is
>> added to current position, then clamped, and then ignored w.r.t. normal
>> input message because the clamped position is the same as the last.
>>
>> Currently if the clipping window is disabled, then no RawMotion events
>> are received anyway.
>>
>>>
>>> 2) When somebody tested warframe with my patch before I re-added
>>> mouse-movements, they had issues that were fixed by rebasing
>>> mouse-movements on my commit, and warframe does not use raw-input for
>>> the mouse.
>>
>> There could be some subtleties I may be overlooking, I will do some
>> tests. Thanks for mentioning it.
>> --
>> Rémi Bernon <rbernon at codeweavers.com>

After doing some more investigation, I indeed missed the "low level" 
mouse messages (WH_MOUSE_LL hook) that can also be used to get mouse 
movement messages. These are received even if the cursor is blocked by 
the clipping rectangle, on the contrary to WM_MOUSEMOVE messages which 
aren't, and they carry the cursor position before clamping it to the 
clipping rectangle.

This is also used (incorrectly, see note below) in Wine for the dinput 
implementation to update the mouse positions.

So I guess that means RawMotion events should still send normal input 
messages.

We can yet get some simplification by using MotionNotify events XOR 
RawMotion events depending if xinput2 is available, as we will now 
always be listening to them, but that may be for later.

Note: During my tests I could see that dinput reports motion values that 
do not follow mouse speed, so implementing it with WH_MOUSE_LL seems 
wrong. It looks also that dinput and raw input are mutually exclusive, 
and as soon as dinput mouse is acquired, the application stops receiving 
WM_INPUT messages, but that may be my sample app that doesn't do it right.
-- 
Rémi Bernon <rbernon at codeweavers.com>



More information about the wine-devel mailing list