Version 10 of custom cursors

Updated 2004-01-25 21:54:50

TR The -cursor option of many Tk widgets not only allows you to choose from the builtin cursors but also to use your own creations.

Widgets can be configured with any of the following cursor definitions:

name ?fgColor? ?bgColor?

Name is the name of a cursor in the standard X cursor cursor, i.e., any of the names defined in cursorcursor.h, without the XC_. Some example values are X_cursor, hand2, or left_ptr. Appendix B of "The X Window System" by Scheifler & Gettys has illustrations showing what each of these cursors looks like. If fgColor and bgColor are both specified, they give the foreground and background colors to use for the cursor (any of the forms acceptable to Tk_GetColor may be used). If only fgColor is specified, then there will be no background color: the background will be transparent. If no colors are specified, then the cursor will use black for its foreground color and white for its background color.

The Macintosh version of Tk supports all of the X cursors and will also accept any of the standard Mac cursors including ibeam, crosshair, watch, plus, and arrow. In addition, Tk will load Macintosh cursor resources of the types crsr (color) and CURS (black and white) by the name of the of the resource. The application and all its open dynamic library's resource files will be searched for the named cursor. If there are conflicts color cursors will always be loaded in preference to black and white cursors.

@sourceName maskName fgColor bgColor

In this form, sourceName and maskName are the names of files describing cursors for the cursor's source bits and mask. Each file must be in standard X11 or X10 cursor format. FgColor and bgColor indicate the colors to use for the cursor, in any of the forms acceptable to Tk_GetColor. This form of the command will not work on Macintosh or Windows computers.

@sourceName fgColor

This form is similar to the one above, except that the source is used as mask also. This means that the cursor's background is transparent. This form of the command will not work on Macintosh or Windows computers.

@sourceName

This form only works on Windows, and will load a Windows system cursor (.ani or .cur) from the file specified in sourceName.


Windows uses a .cur files and unix uses .xbm files.

 set dir /path/to/cursor/files

 switch -- $tcl_platform(platform) {
   unix {
     set file [file join $dir cursorfile.xbm]
     set cursor [list @$file black]
   }
   windows {
     set file [file join $dir cursorfile.cur]
     set cursor [list @$file]
   }
 }
 $widget configure -cursor $cursor

To accomplish this, you must specify the file, where the cursor lives:

 # windows:
 $widget configure -cursor "@path/to/cursorfile.cur"
 # unix:
 $widget configure -cursor "@path/to/cursorfile.xbm black"

the cursor will be displayed in the size it was defined.


Here is a 16x16 pixel cursor named hand.xbm:

 #define hand_width 16
 #define hand_height 16
 #define hand_x_hot 6
 #define hand_y_hot 0
 static unsigned char panPointer_bits[] = {
    0x00, 0x00, 0x80, 0x01, 0x58, 0x0e, 0x64, 0x12, 0x64, 0x52, 0x48, 0xb2,
    0x48, 0x92, 0x16, 0x90, 0x19, 0x80, 0x11, 0x40, 0x02, 0x40, 0x04, 0x40,
    0x04, 0x20, 0x08, 0x20, 0x10, 0x10, 0x20, 0x10 };

This file has two extra lines compared to "normal" xbm files that define where the so-called "hot spot" is. This is the point in the bitmap where a click event appears to come from. The coordinates count from left to right (x) and from top to bottom (y), just like the canvas coordinate system.


On Windows you should always create your cursor files with a size of 32x32 pixels even if you do not need so much space. If you created a 16x16 pixel cursor (as with unix above) it would get enlarged by a factor of two when displayed. A windows cursor file can easily be created from a bmp or gif file by the free Windows program IconShop [L1 ] (yes, it can also create windows icons). The only problem is, you cannot specify your own hotspot. But since the cur file format is known, we can do that with Tcl. Thus:

 set cur [open myCursorFile.cur r+]
 fconfigure $cur -encoding binary -translation binary
 # this is the file position of the x coord of the hot spot:
 seek $cur 10
 # set x=6
 puts -nonewline $cur [binary format c 6]
 # dto. for the y coord of the hot spot:
 seek $cur 12
 # set y=0
 puts -nonewline $cur [binary format c 0]
 close $cur

Now you have a nice cursor for your Unix and Windows programs.


Who can tell what to do on MacOS?


Beware of an issue relating to many Windows OS's that have spaces in the path name of default installation locations. If a software package happens to be installed in such a place, the following will fail:

 set filename "C:/Program Files/MyApp/linkcursor.cur"
 . configure -cursor @$filename

As Jeff Hobbs pointed out in c.l.t. on 25-Jan-2004, the canonical mouse cursor specification is a proper Tcl list. Therefore, the following invocation must be used to succesfully load a mouse cursor from such places:

 set filename "C:/Program Files/MyApp/linkcursor.cur"
 . configure -cursor [list @$filename]

Tk syntax help