Not receiving XI_RawMotion events while mouse button is pressed.

Roger Cruz roger.cruz at virtualcomputer.com
Wed May 11 11:08:45 PDT 2011


Hi Peter,

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? 

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 };
	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));
		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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.x.org/archives/xorg-devel/attachments/20110511/729b6f4d/attachment-0001.htm>


More information about the xorg-devel mailing list