Version 1 of hidden cursor

Updated 2003-07-29 04:59:18

Sometimes you need to hide the cursor. E.g., a presentation application in which the cursor only shows up when you move it to highlight something, then disappears. From reading the discussion on c.l.t, the following should work in Linux:

 proc show_cursor {} { .c conf -cursor "" }
 proc hide_cursor {} { .c conf -cursor { gumby blue red } }

However, this does not work under Windows:

 Error: bad cursor spec " gumby blue red "

Nor does the documented "no" cursor.

You can instead use a custom cursor which is invisible. You will have to find one for yourself on the net. E.g., a google search for invisible.cur. The cursor file must be on a system path, not in a VFS path.

 proc show_cursor {} { .c conf -cursor "" }
 proc hide_cursor {} { .c conf -cursor "@path_to_cursor/invisible.cur" }

You can also simulate a hidden cursor with pointer warping, moving the cursor to the corner of the screen on hide, and restoring its position on show. This works reasonably well if the canvas covers the entire screen, as shown in the following example:

 # full screen canvas
 pack [canvas .c -width [winfo screenwidth .] -height [winfo screenheight .]]
 wm overrideredirect . 1

 set hidden {} ;# last cursor coordinates
 set hiding 0 ;# hiding, so don't try to unhide
 proc show_cursor {} {
     # suppress the motion event that occurs when warping
     if $::hiding return
     if [llength $::hidden] {
         foreach {x y} $::hidden break
         set ::hidden {}
         event generate .c <Motion> -warp 1 -x $x -y $y
     }
 }
 proc hide_cursor {} {
     if [llength $::hidden] return
     set ::hidden [winfo pointerxy .c]
     set ::hiding 1
     # almost to the corner --- if you go to the corner, 
     # you will miss half the motion events
     event generate .c <Motion> -warp 1 -x [expr {[winfo screenwidth .]-1}] -y 1
     update
     set ::hiding 0
 }

 # escape by clicking mouse
 bind all <1> exit

 # make the cursor appear when the mouse moves
 bind .c <Motion> {
     show_cursor
     # reschedule hide
     after cancel hide_cursor
     after 1000 hide_cursor
 }

 # start with the cursor hidden
 after 1000 hide_cursor