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