This tool is a small Python native extension which allows managing custom ARGB/animated cursors (Xcursor) under X.org server. The package can be used for all tcl/tk and Python versions (not only for latest).

On this moment tcl/tk doesn't provide ability to set such cursors for they widgets. You can use XBM monochrome (1-bit) custom cursors only. But several years ago X.org has got ARGB/animated cursor feature with the same properties as implemented under win32 platform. So we have developed this small package to fill this gap.

For small desktop applications such feature is not important because they can use standard system cursors. But for sK1 canvas we need providing a lot of custom mouse pointers to reflect canvas state and editing mode. XBM cursors are ugly and non compatible with win32 cursors (at least they requires additional convert to have CUR file). Whereas source png files can be converted as in Xcursors and in win32 cursors without any problems.

The picture illustrates difference between these cursor types:

Difference between ARGB and monochrome cursors

RGBA graphics support does not mean that you need using colored and always animated cursors. Usually this feature is used to provide more informative and expressive subpixel structured image.

Funny that between large FOSS graphical applications custom ARGB cursors are supported in GIMP only. Inkscape, Krita, Scribus etc. use old fashion XBM cursors. Perhaps it's due to lack of Xcursor library documentation. So our tkXcursor extension can serves as a code example for other teams because actually there are 2 important lines of C code for feature implementation. The rest of code is just a Python/tk related wrapper.

How it works

tkXcursor package contains only 3 functions:

is_xcursor_supported(any_widget)
load_cursor(any_widget, filename)
set_cursor(target_widget, cursor_id)

That's all you need to manage Xcursors. There are some important details. Two first functions accept as argument any tk widget. It's just for extracting on native side some general tk values. And last function should receive target widget of course.

After Xcursor resource file loading load_cursor() returns cursor id. On native side it's a XID (i.e. long value) but on Python side there is no necessity to create special object for XID. So cursor id is just a Python integer value which can be used any times and anywhere for custom cursor setting by set_cursor() function.

Last important issue deal with a moment for cursor changing. Often in simple applications all values are set before mainloop(). For custom Xcursors it's unacceptable. You can load cursors before mainloop() using root reference because tk creates root window immediately. But cursor setting should be deferred up to first target widget <Visibility> event when the widget will be created. Otherwise you can get Segmentation fault error on native side in runtime and your application will be terminated.