Subject: FVWM: fvwm misses mouse-release sometimes

From: Avery Pennarun <[email-masked]>
Date: Wed, 3 Jan 1996 02:51:20 -0500 (EST)

Has anyone else noticed that if you hold down the mouse button for exactly
the right amount of time on say a title bar, and then release the button,
and then move the mouse, fvwm will drag the window anyway and not release
the drag until you click again?

The timing is very important for this, unfortunately I seem to be physically
tuned to do it exactly right quite often.  It seems to be that clicking very
quickly avoids the problem, and it doesn't happen once the mouse has turned
into the four-way-move pointer, but if I release the mouse button JUST
BEFORE the circle changes to a four-way-move the problem shows up.

This has really annoyed me, particularly since I use a single-click to
deiconify windows and quite often end up dragging the icons around by
accident instead.

This has been around from at least 2.0.36 (first 2.0 version I tried) to my
current version, 2.0.39.  It didn't happen to me in fvwm 1.24r (and still
doesn't).  It's the only thing preventing my full enjoyment of fvwm2 :)

Other interesting information: Linux 1.3.52 (also tried many other versions
including the "stable" 1.2.13), XFree86 3.1.2 (X11R6) with Mach64, S3, and
SVGA servers.  Not using emulate3buttons or chordmiddle.  In other programs,
including fvwm1, my mouse buttons all work fine.  Tried on a 486-33, 486-40,
Pentium-75, and Pentium-133 running fvwm both across the network and on the
local machine with the same effects.

Any ideas?

Avery
--
To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
message to [email-masked].
To report problems, send mail to [email-masked].

---

From: [email-masked] (Robert Nation 885-9815)
Date: Wed, 3 Jan 96 10:07:37 EST

>the drag until you click again?

I've noticed this before, but never debugged it. It is annoying. I believe 
that I have finally located the problem. Its in complex.c. Routine IsClick()
checks to see if we have a mouse move or a click:

Bool IsClick(int x,int y,unsigned EndMask, XEvent *d)
{
  int xcurrent,ycurrent,total = 0;
  Time t0;
  extern Time lastTimestamp;

  xcurrent = x;
  ycurrent = y;
  t0 = lastTimestamp;

  while((total < Scr.ClickTime)&&
        (x - xcurrent < 3)&&(x - xcurrent > -3)&&
        (y - ycurrent < 3)&&(y - ycurrent > -3))
    {
      sleep_a_little(10000);
      total+=10;
      if(XCheckMaskEvent (dpy,EndMask, d))
        {
          StashEventTime(d);
          if((lastTimestamp - t0) < Scr.ClickTime)
            return True;
          else
            return False;
        }
      if(XCheckMaskEvent (dpy,ButtonMotionMask|PointerMotionMask, d))
        {
          xcurrent = d->xmotion.x_root;
          ycurrent = d->xmotion.y_root;
          StashEventTime(d);
        }
    }
  return False;
}

When we get a Button Release, we pass the test:
      if(XCheckMaskEvent (dpy,EndMask, d))
and then check:
          if((lastTimestamp - t0) < Scr.ClickTime)
If we fail the second test, then we discard the button release! (Oops)

This error can be triggered by releasing the mouse just before ClickTime 
expires.

Solutions? One would be to make the click-move decision based on pointer motion
only. Perhaps better would be a re-write from
  while((total < Scr.ClickTime)&&
        (x - xcurrent < 3)&&(x - xcurrent > -3)&&
        (y - ycurrent < 3)&&(y - ycurrent > -3))

to something like:
  while((total < Scr.ClickTime)&&
        (x - xcurrent < 3)&&(x - xcurrent > -3)&&
        (y - ycurrent < 3)&&(y - ycurrent > -3)&&
	(lastTimestamp - t0) < Scr.ClickTime))
and remove the test for expiration time which occurs later:
          if((lastTimestamp - t0) < Scr.ClickTime)

This second solution would probably allow infinite click-times if the
mouse is never moved.

Perhaps the best solution is to try to peek in the event queue without
removing the button release. I think the function XPeekIfEvent might
allow this.

Rob