Updated 2012-04-03 11:55:50 by RLE

ulis, 2004-01-29. No, Tcl nor Tk can move your mouse or your hand. But Tk (with the help of Tcl) can move the mouse cursor on your screen. The trick is to use the -warp option of the event generate command. (This trick comes from Kroc).

A little script to illustrate this:
  pack [button .b -text Ok -width 4 -command exit]
  bind . <Key> { set ::stop 1 }
  set stop 0
  set x -20; set y -10; set incrx 1; set incry 0.5
  proc move {} \
    if {$::stop} { return }
    set ::x [expr {$::x + $::incrx}]
    set ::y [expr {$::y + $::incry}]
    if {$::x < 20} \
      event generate .b <Motion> -warp 1 -x $::x -y $::y
      after 100 move 
    } \
    else \
      event generate .b <ButtonPress-1>
      after 100 event generate .b <ButtonRelease-1>
  focus -f .
  raise .

See also

  • This is covered in warp
  • An alternative on Windows NT and above is the move_mouse command that is part of TWAPI

APN The above script didn't seem to do anything as far as I could tell on my Win2K box. Also, is warping restricted to Tk windows only or can the mouse be moved anywhere on the screen (for automation tests for example). An alternative on Windows NT and above is the move_mouse command that is part of TWAPI.

ulis Very surprising: I tested it on a W2k box. Maybe Tk version matters: I used 8.4.

The x & y coords are computed for the Tk widget (.b here) and the cursor can go outside the widget.

Under good conditions the script move the cursor mouse from outside the widget to the center of the button.

LV as a user, just let me say how much I hate the fact that right now, the GNOME metacity window manager moves the mouse around to windows that it thinks should get focus. There I will be, typing away, when all of a sudden the mouse warps over to Netscape or some other window, and my keystrokes, at best, are ignored, and at worst, cause things like screens to lock, or forms to be submitted, or whatever.


Don't do that has more discussion.

JPT Using the DLL extension under Windows, one can move and click the mouse with a proc like this one:

  proc MouseClick {x y} {
    ::dll::call user32 SetCursorPos i "i $x" "i $y"
    ::dll::call user32 mouse_event i "i $::MOUSEEVENTF_LEFTDOWN" {i 0} {i 0} {i 0} {i 0}
    ::dll::call user32 mouse_event i "i $::MOUSEEVENTF_LEFTUP" {i 0} {i 0} {i 0} {i 0}

SeS - 2012-04-03 10:42:08 The information in this page inspired me to implement a little proc into tG² v1.06.0.34 when layout forms/toplevels are opened by the user (and thus willingly wants to change focus of the pointer to the layout toplevel), to set the position of the mouse pointer to the center of the layout-toplevel. And yes, as LV already mentioned, use it wisely. In the end, the GUI one is developing should be helpful and not annoy users, or at least make it settable.
proc centerMouse2 {w {wmgeo ""}} {
  if {$wmgeo==""} {set wmgeo [winfo geom $w]}
  set t [split [split $wmgeo x] +]
  event generate $w <Motion> -warp 1 -x [expr [lindex $t 0 0]/2] -y [expr [lindex $t 0 1]/2]

  centerMouse2 <toplevel path> ?geometry of the toplevel?