josh@mit-vax.LCS.MIT.EDU (Joshua Marantz) (12/30/88)
I sent this to xbugs and got no reply, and I'm curious to see if anyone else
has had a problem with this. The bug report follows.
-Joshua Marantz
Viewlogic Systems, Inc.
----------------
X Window System Bug Report
xbugs@expo.lcs.mit.edu
VERSION:
R3
CLIENT MACHINE and OPERATING SYSTEM:
Sun 3/60 running SunOS 3.4.
DISPLAY:
Sun 3/60, SunOS 3.4, Sun CG4.
WINDOW MANAGER:
uwm
AREA:
server
SYNOPSIS:
MotionNotifyHints do not work when the cursor is grabbed in a ConfineTo
window.
DESCRIPTION:
R2 servers (running on Sun 3/60/SunOS 3.4/CG4 and uVAXII/VMS/GPX) do
this correctly. The code creates an InputOnly limiting window, and
does an XGrabPointer with the ConfineTo window set to the limiting
window. The event mask (MotionNotify | PointerMotionMask) is
selected. The server responds to the first mouse movement with a
MotionNotify event. XQueryPointer routine is then called to reset
the hint mechanism. In R3, the server will not send another
MotionNotify event until a button is pressed or the mouse leaves
the window. In R2, the server will send a new MotionNotify event
each time the mouse is moved after an intervening XQueryPointer,
as expected.
REPEAT BY:
I have modified xev.c to demonstrate the problem. The context diffs
follow, but all I did was to call XQueryEvent each time a MotionNotify
event was received, and to toggle grabbing (confining) the pointer each
time the mouse button is pressed.
*** /usr/local/X11/clients/xev/xev.c Sun Oct 9 15:43:32 1988
--- xev.c Mon Dec 12 19:44:41 1988
***************
*** 95,108 ****
{
char *displayname = NULL;
char *geom = NULL;
! int i;
XSizeHints hints;
int borderwidth = 2;
! Window w, subw;
! XSetWindowAttributes attr;
! unsigned long mask = 0L;
! int done;
!
ProgramName = argv[0];
for (i = 1; i < argc; i++) {
char *arg = argv[i];
--- 95,108 ----
{
char *displayname = NULL;
char *geom = NULL;
! int i, root_x, root_y, query_x, query_y;
XSizeHints hints;
int borderwidth = 2;
! Window w, subw, query_root, query_child, limit_window;
! XSetWindowAttributes attr, limit_attr;
! unsigned long mask = 0L, query_mask;
! int done, limited = 0;
!
ProgramName = argv[0];
for (i = 1; i < argc; i++) {
char *arg = argv[i];
***************
*** 205,210 ****
--- 205,238 ----
do_KeyRelease (&event);
break;
case ButtonPress:
+
+ /* If the cursor is confined to the window, let it rome free! */
+ if (limited) {
+ XUngrabPointer (dpy, CurrentTime);
+ XDestroyWindow (dpy, limit_window);
+ limited = 0;
+ }
+
+ /* If the cursor was free, confine it to the window */
+ else {
+ limited = 1;
+ limit_window = XCreateWindow (dpy, w,
+ 0, 0, hints.width, hints.height,
+ 0, 0,
+ InputOnly,
+ (Visual *) CopyFromParent,
+ 0, &limit_attr);
+
+ XMapWindow (dpy, limit_window);
+ XGrabPointer (dpy, w,
+ True,
+ ButtonPressMask | PointerMotionMask,
+ GrabModeAsync, /* pointer mode */
+ GrabModeAsync, /* kbd mode */
+ limit_window, /* confine-to window */
+ None,
+ CurrentTime);
+ }
prologue (&event, "ButtonPress");
do_ButtonPress (&event);
break;
***************
*** 214,219 ****
--- 242,249 ----
break;
case MotionNotify:
prologue (&event, "MotionNotify");
+ XQueryPointer (dpy, w, &query_root, &query_child,
+ &root_x, &root_y, &query_x, &query_y, &query_mask);
do_MotionNotify (&event);
break;
case EnterNotify:rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (12/30/88)
Yes, there is a server bug here, having to do with your switching
from having Hint set in the normal mask to not having Hint set in
the grab mask. If both were equal it would work OK. Since you
want hints, you should continue to ask for them in the grab, and
all will be well:
XGrabPointer (dpy, w,
True,
! ButtonPressMask | PointerMotionMask
! | PointerMotionHintMask,
GrabModeAsync, /* pointer mode */
GrabModeAsync, /* kbd mode */
limit_window, /* confine-to window */
None,
CurrentTime);