Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!mit-vax!josh From: josh@mit-vax.LCS.MIT.EDU (Joshua Marantz) Newsgroups: comp.windows.x Subject: Motion hints and pointer grabbing Message-ID: <5389@mit-vax.LCS.MIT.EDU> Date: 29 Dec 88 21:00:27 GMT Organization: MIT LCS, Cambridge, MA Lines: 129 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: