[comp.windows.x] X11R3: PointerMotionMask misbehaving

mouse@LARRY.MCRCIM.MCGILL.EDU (der Mouse) (03/28/89)

System: Sun-3, release 3.5.  X11R3.

A couple of things seem to be broken....

I set up a passive grab on a button:

 XGrabButton( disp,
	      Button2,
	      AnyModifier,
	      rootwin,
	      False,
	      ButtonPressMask | PointerMotionMask,
	      GrabModeSync,
	      GrabModeSync,
	      None,
	      None );

One problem is that I seem to need to explicitly XUngrabPointer when I
see a ButtonPress event, or else the grab seems to persist after the
button is released (contrary to the documentation I have, which says
that a passive grab will deactivate as soon as all buttons are
released).

The other problem is that under some conditions, I want to move a box
around, violating normal window boundaries, when I see this button
press come in (I'm writing a window manager).  I looked at how uwm does
its animation of boxes and wrote the following, which is called under
some circumstances when a ButtonPress event is seen:

XGrabServer(disp);
XAllowEvents(disp,AsyncPointer,CurrentTime);
XChangeActivePointerGrab( disp,
			  ButtonPressMask | PointerMotionMask,
			  None,
			  CurrentTime );
while (1)
 { ....
   XIfEvent(disp,&e,predicate,"");
   ....
   switch (e.type)
    { ....
      case ButtonPress:
      ....
      case MotionNotify:
      ....
    }
   ....
 }

where predicate is

Bool predicate(d,e,a)
Display *d;
XEvent *e;
char *a;
{
 return((e->type == ButtonPress) || (e->type == MotionNotify));
}

The problem is, I never see a MotionNotify event.  As if that weren't
enough, I never see more than one ButtonPress event!

Any idea what I'm doing wrong here?  (Yes, I do clean up, ungrabbing
things, but the problems strike before that.)  The
XChangeActivePointerGrab call was an attempt to make *certain* that
motion events would get through, but it didn't help any.

Uwm seems to get around this by doing a spin loop, calling
XQueryPointer and doing things when the returned values change.
However, that's insanely inefficient, or so it seems to me.  I can just
imagine what it would do to the network when uwm is not on the same
machine as the server.

Is the above supposed to work?  If so, any idea why it doesn't?  If
not, what's the proper way to do this?

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (03/28/89)

    One problem is that I seem to need to explicitly XUngrabPointer when I
    see a ButtonPress event, or else the grab seems to persist after the
    button is released (contrary to the documentation I have, which says
    that a passive grab will deactivate as soon as all buttons are
    released).

Do you mean after the button is physically released (in which case you are
confused), or after it is logically released (in which case there might be
a server bug)?  The grab should deactivate after you AllowEvents enough to
let the ButtonRelease event be processed by the server (it won't be processed
immediately because you asked for ModeSync).  If you really think there is
a server bug, then supplying complete working sample code and how to use it
is probably going to be necessary to track it down.

    The problem is, I never see a MotionNotify event.  As if that weren't
    enough, I never see more than one ButtonPress event!

Again, complete working code and instructions are probably going to be
required.

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (04/07/89)

    [using grabs]
    The problem is, I never see a MotionNotify event.

I took a look at the code you sent me, and discovered that you're calling
XGrabPointer with a confine-to window that has never been mapped.  That's
a no-no, and causes the grab to fail.  XGrabPointer returns status
GrabNotViewable, which you decided not to check (shame on you).  Since the
grab fails, it's attempt to ask for motion events also fails.

mouse@LARRY.MCRCIM.MCGILL.EDU (der Mouse) (04/07/89)

>> [using grabs]
>> The problem is, I never see a MotionNotify event.

> I took a look at the code you sent me, and discovered that you're
> calling XGrabPointer with a confine-to window that has never been
> mapped.  That's a no-no, and causes the grab to fail.  XGrabPointer
> returns status GrabNotViewable, which you decided not to check (shame
> on you).  Since the grab fails, it's attempt to ask for motion events
> also fails.

You got code in an interim state, I realize upon looking back.  Mapping
the confine-to window did make the problem disappear - both problems:
the XGrabPointer works, and the MotionNotify events start coming in.

As I recall, the same was true (ie, I wasn't seeing MotionNotify
events) before I started explicitly calling XGrabPointer at all, which
leaves the question of why this was happening when the passive grab
included PointerMotionMask in its event mask....  I'll write a test
program and see if I can get the behaviour I think I got before.  I'll
report back here when I've done this.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

ado@elsie.UUCP (Arthur David Olson) (04/08/89)

> XGrabPointer returns status GrabNotViewable, which you decided not to check
> (shame on you).

Script started on Fri Apr  7 16:42:18 1989
elsie$ sed -n 565,575p clients/xterm/menu.c
	 * press, and move the window there.  Then map the menu.
	 */
	if(!Move_Menu(menu, event) || !Map_Menu(menu))
		return(-1);

	in_window = TRUE;
	XGrabPointer(XtDisplay(xw), menu->menuWindow, FALSE,
	 ExposureMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask
	 | ButtonReleaseMask | ButtonPressMask,
	 GrabModeAsync, GrabModeAsync, None, menu->menuCursor, CurrentTime
	 );
elsie$ exit

script done on Fri Apr  7 16:42:32 1989
-- 
	Arthur David Olson    ado@ncifcrf.gov    ADO is a trademark of Ampex.