Thank you so much for your help, I'll make the relevant changes as soon as I get home.
On Tue, 2019-07-23 at 09:26 +0200, Rémi Bernon wrote:
> On Mon, 2019-07-22 at 22:16 -0400, Derek Lesho wrote:
> > Thank you for looking into this, would the solution to this problem be to
> > preserve the event from the slave pointer in merge_raw_events?
> >
> > On Mon, Jul 22, 2019 at 10:06 AM Rémi Bernon <rbernon@codeweavers.com>
> > wrote:
> >
> > > It looks like that if the cursor isn't clipped by the application (or
> > > by wine in fullscreen), then both master and slave XI2 device events
> > > are received (on the contrary, when the cursor is clipped then for some
> > > unclear reason only the slave device events are received).
> > >
> > > In this case, one of the events is then discarded by
> > > merge_raw_motion_events in dlls/winex11.drv/event.c and as
> > > X11DRV_RawMotion is designed to track only slave devices (one per
> > > thread with the xi2_current_slave field AFAICS?), depending on which
> > > comes first, the event might not be processed and no raw input be sent.
> > > --
> > > Rémi Bernon <rbernon@codeweavers.com>
> > >
>
> I'm still not sure how everything works in winex11.drv, but I believe
> raw input implementation could use some cleanup. For instance, I don't
> understand why a single slave device is selected rather than listening
> to the master device events, I find it a bit unreliable that the first
> slave device that sends events is selected over the others.
>From http://who-t.blogspot.com/2009/06/xi2-recipes-part-3.html it looks
like every time the user starts using a different slave device, there's
a DeviceChanged event being sent, so I guess it explains why.
> I would say that, for simplicity, only the master device events should
> be translated, but that would require to make it send events even when
> the cursor is clipped, and first understand why it doesn't (AFAICS with
> some Xlib test app, there's no differences before and after calling
> XGrabPointer so there's something else going on).
>
> If that's not possible, or for a "better" implementation, then all and
> only slave devices should be listened to, and their inputs translated
> to the corresponding Windows raw input messages. Also, it may be useful
> to implement WM_INPUT_DEVICE_CHANGE messages on the corresponding
> XInput2 events (but that may be done later and only if deemed useful).
Reading the series of posts about XInput2 linked above makes me think
that listening to master devices is the correct way to proceed. It will
also simplify the code, as we could even simplify the event mask by
using XIAllMasterDevices instead of having to filter the events.
Regarding why master device events aren't sent once XGrabPointer is
active only, the reason looks to be that wine advertises to support
XInput 2.0 client API only. Calling XIQueryVersion with major = 2 and
minor >= 1 in X11DRV_XInput2_Enable fixes the issue.
With all that, I believe that you should be able to make every window
thread listen to XInput2 events without worrying anymore about
duplicates, and the wineserver will dispatch the events to the right
windows. You could maybe decide to report the raw inputs only to the
foreground window in wineserver, or implement the RIDEV_INPUTSINK flag
/ RIM_INPUTSINK wParam for background raw input.
--
Rémi Bernon <rbernon@codeweavers.com>