Not receiving XI_RawMotion events while mouse button is pressed.
Peter Hutterer
peter.hutterer at who-t.net
Wed May 11 16:55:10 PDT 2011
On Wed, May 11, 2011 at 01:08:45PM -0500, Roger Cruz wrote:
> Thanks for answering. I think your suspicion about the implicit pointer
> grab is probably correctly. Here is what I found out.
>
> The problem only occurred when my application was run on a system with two
> monitors. Our code creates an X window/screen for each monitor (both
> screens are within the same frame buffer). When I added the XI raw motion
> code, I only enabled raw motion events for the primary window and not for
> the secondary window. I had to do this because I was receiving the same
> raw event twice (one for each window). I used these pointer movements for
> an emulated mouse and having them delivered twice caused unnecessary
> "acceleration".
>
> The problem is that another application in our code warps the pointer to
> the secondary screen unbeknownst to me. This didn't appear to have any
> side effects and I still got the raw motions events until the user
> performed a click and drag operation. In this case we didn't get the raw
> motion movements from the secondary window anymore.
>
> Based on what you described below, it appears (please correct me if wrong)
> that when the user clicks on the secondary screen, the pointer is
> implicitly grabbed and all the raw motion events are not delivered to the
> root window. It is my understanding that raw motion events only work with
> the root window so if you look at my code below, when we register for the
> raw motion events, we do so at for the root window. The root window
> should contain both the X screens mentioned above.
>
> Now, I can't change the code that warps the pointer to the secondary
> screen so I have to be able to fix this problem entirely within my mouse
> code. I have re-enabled the code so that both X windows call the code
> below to register for raw motion. This fixes my click and drag problem
> but now I have the problem double events being delivered to my
> application. Any suggestions on how to prevent that from occurring?
Raw events are delivered to all root windows, regardless which window the
pointer is on. so you don't need to select on both root windows, the first
one is enough.
I'm not sure how you'd fix the click-and-drag problem though. once you
deliver the ButtonPress event anywhere (unless it's an XI_ButtonPress
event), you lose the ability to receive raw events. at least that's how the
server is currently written, or so I thought.
but tbh, you're mixing window and screen terminologies here so I'm not sure
what your setup is and why the above would work in your case.
> Thanks
>
> Roger R. Cruz
>
>
> static void
> enable_or_disable_xi_rawmotion_events(xstate_t *xs, xi_enable_disable state)
> {
> unsigned char mask[3] = { 0, 0, 0 };
I recommend using XIMaskLen(XI_RawMotion) here for the array length.
though admittedly that was buggy for a while...
> XIEventMask *eventmask;
>
> /*
> * This routine is commented out due a bug in X11's XI extension
> * which leaves the display lock taken. It is fixed in version
> * 1.3.1 so when we upgrade to that version or newer, we can
> * re-enable the code.
> * eventmask = XIGetSelectedEvents(xs->dpy, xs->w, &num);
> */
>
> eventmask = NULL;
> if (!eventmask) {
> eventmask = (XIEventMask *)xmalloc(sizeof(*eventmask));
xmalloc? that's a server-internal function (that has now been removed). just
using normal calloc will do.
Cheers,
Peter
>
> eventmask->mask_len = sizeof(mask);
> eventmask->mask = mask;
> }
>
> eventmask->deviceid = XIAllMasterDevices;
>
> if (state == XI_ENABLE_RAWMOTION)
> /* Register for pointer motion events in raw form */
> XISetMask(eventmask->mask, XI_RawMotion);
> else
> /* Unregister for pointer motion events in raw form */
> XIClearMask(eventmask->mask, XI_RawMotion);
>
> XISelectEvents(xs->dpy, DefaultRootWindow(xs->dpy), eventmask, 1);
> free(eventmask);
> }
>
>
> -----Original Message-----
> From: Peter Hutterer [mailto:peter.hutterer at who-t.net]
> Sent: Tue 5/10/2011 7:13 PM
> To: Roger Cruz
> Cc: xorg-devel at lists.x.org
> Subject: Re: Not receiving XI_RawMotion events while mouse button is pressed.
>
> On Tue, May 10, 2011 at 01:56:19PM -0500, Roger Cruz wrote:
> > I have integrated libxi2's capability to provide raw motion pointer values
> > into my application which was originally using (and still uses) xinput
> > events. The application currently registers for the old xinput events
> > using XSelectInput.
> >
> > XSelectInput(xs->dpy, xs->w, event_mask);
> >
> > where the event mask is
> >
> > event_mask = (OwnerGrabButtonMask << 1) - 1; /* all events */
> >
> > event_mask &= ~PointerMotionHintMask;
> > event_mask &= ~PropertyChangeMask;
> > event_mask &= ~ColormapChangeMask;
> > event_mask &= ~SubstructureNotifyMask;
> >
> >
> > I added an additional xinput2 registration to only capture the raw motion events which I needed.
> >
> > XISetMask(eventmask->mask, XI_RawMotion);
> > XISelectEvents(xs->dpy, DefaultRootWindow(xs->dpy), eventmask, 1);
> >
> > This appears to be working fine. I get raw motion and mouse button press
> > and releases when done independently. However, when I click to drag, I
> > only get the button press event but not the raw motion events. Is this
> > expected behavior for the current implementation of libxi? I need to be
> > able to get raw motion events even when the button is pressed. I don't
> > believe anyone else is grabbing the pointer.
>
> If the button press event is delivered somewhere, this activated an implicit
> grab in the server and the device is now grabbed by that client that
> received the button press event. I suspect this is the cause here too.
>
> Furthermore, XI and XI2 grabs are handled separately, so if you get a XI1
> grab, it does not carry the XI2 event mask. Your raw event is thus not
> delivered once you have an XI grab.
>
> Cheers,
> Peter
>
> No virus found in this incoming message.
> Checked by AVG - www.avg.com
> Version: 9.0.900 / Virus Database: 271.1.1/3617 - Release Date: 05/10/11 14:34:00
>
More information about the xorg-devel
mailing list