[comp.windows.x] GetWindowCursor

ebina@URBANA.MCD.MOT.COM (Eric Bina) (06/30/90)

How do I find the Cursor ID for the current cursor in a window?


Basically what a want is to have my cursor disappear if I havn't moved the
mouse for a while, and then reappear when I move the mouse.

I have written a program that I can run which follows mouse motion, and
when the mouse has been at rest for a while will make it disappear by finding
the current window you are in, and setting the cursor in that window
to be transparent with XDefineCursor().  However, when you move the mouse
again I want to restore the original cursor.  Currently I call
XUndefineCursor(), but that just sets the cursor to the X cursor.  I would like
to be able to get the Cursor ID of the cursor in the window the mouse is in
before I do the XDefineCursor() to transparent so I can then reset it properly
later.


Does anyone know of a way to do this?  The cursor ID does not seen to be in the
X Window Attributes structure, nor is it in any of the window hint structures.

Eric Bina
ebina@urbana.mcd.mot.com

mouse@LARRY.MCRCIM.MCGILL.EDU (der Mouse) (06/30/90)

> How do I find the Cursor ID for the current cursor in a window?

> Basically what a want is to have my cursor disappear if I havn't
> moved the mouse for a while, and then reappear when I move the mouse.

Instead of bashing on the cursor for the window the mouse is in, how
about when you see the mouse go idle, try grabbing the pointer with

grab_window = see note 1 below
owner_events = False
event_mask = PointerMotionMask | ButtonPressMask | ButtonReleaseMask
pointer_mode = GrabModeSync
keyboard_mode = GrabModeAsync
confine_to = None
cursor = an invisible cursor
time = see note 2 below

Then call XAllowEvents with mode SyncPointer and wait for an event.  If
the event is a ButtonPress or ButtonRelease, call XAllowEvents in mode
ReplayPointer (which releases your grab), and go back to waiting for
the mouse to go idle.  If the event is a MotionNotify,

- Grab the server.
- Freeze the pointer with XGrabPointer.
- Sync with the server with XSync.
- Scan the event queue for ButtonPress or ButtonRelease events.
  If there are none:
    - Release the pointer grab entirely with XUngrabPointer.
  If one is found:
    - Release the grab by using XAllowEvents in mode ReplayPointer.
- Ungrab the server.

Ideally, there should be something like XAllowEvents' SyncPointer mode,
but for motion events as well as ButtonPress and ButtonRelease events.
This would render the above kludge for the case of MotionNotify
unnecessary.

Note 1: about the grab_window for the initial grab.  I would make this
  a window created expressly for this purpose.  I would make it lie
  entirely outside the bounds of the root window (so the pointer cannot
  possibly actually be moved into it).  It should perhaps be an
  override-redirect window, so the window manager doesn't try to
  second-guess its somewhat unusual placement.

Note 2: about the time to pass to the initial grab.  I would probably
  use CurrentTime here, though I know that's not entirely correct.  The
  right way to do it would be to get a timestamp from the server with a
  zero-length append using XChangeProperty and use that (and of course
  if GrabInvalidTime is returned, get a fresh timestamp and try again).
  For timestamps for the other routines requiring them, pass either the
  time from the most recent event or the timestamp used for the first
  grab, whichever is applicable.

					der Mouse

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