Interactively convert Windows .ani animated cursors into a proper Linux XCursor theme.
ani2xcursor scans a folder for .ani files, guesses a sensible X11 cursor name for each one (which you can accept, change, or pick from a menu), asks what size you want the cursors rendered at, and builds a ready-to-use cursor theme complete with an index.theme and optional compatibility symlinks (default, pointer, xterm, …).
$ python3 ani2xcursor.py
============================================================
.ani -> Linux XCursor (interactive)
============================================================
Directory to scan for .ani files [.]:
Found 9 .ani file(s) in .:
1. Classic cursor Brushbuddy.ani
2. Diagonal resize1 Brushbuddy.ani
...
Which ones to convert? (comma-separated numbers, or 'all') [all]:
Classic cursor Brushbuddy.ani -> cursor name [left_ptr] (or 'l' for list):
...
Choose the final cursor size
1. 24x24 px
2. 32x32 px (default)
3. 48x48 px
4. 64x64 px
5. 96x96 px
6. 128x128 px
7. Custom size...
Choose the final cursor size [2]:
Theme name [MyCursors]:
Install cursors under which base directory? [/home/you/.local/share/icons]:
- 🔍 Auto-discovery of
.anifiles in a directory, or add files manually by path - 🧠 Smart name guessing from the filename (resize, move, link, wait, text, …), always overridable
- 📋 Standard cursor name picker — browse ~28 common X11 cursor names with descriptions
- 📏 Configurable output size (24–128px presets, or any custom size)
- 🎯 Correct hotspot scaling, computed from each cursor's actual native resolution (not assumed)
- 🎞️ Full animation support — multi-frame
.anifiles convert to animated XCursors with the original frame timing preserved - 🔗 Optional alias symlinks (
default,pointer,xterm,watch, …) for wider app compatibility - ✅ Dependency checks with install hints if
ImageMagickorxcursorgenare missing
- Python 3.8+
- ImageMagick (provides the
magickcommand) xcursorgen(fromxorg-xcursorgenon Arch,x11-appson Debian/Ubuntu)
Install on Arch Linux:
sudo pacman -S imagemagick xorg-xcursorgenInstall on Debian/Ubuntu:
sudo apt install imagemagick x11-appsgit clone https://github.com/AValzzzz/ani2xcursor.git
cd ani2xcursor
python3 ani2xcursor.pyAnswer the prompts:
- Which directory to scan (or add
.anifiles manually by path) - Which files to convert
- What X11 cursor name each one maps to
- The final pixel size
- The theme name and install location
The theme is written to <base directory>/<theme name>/, following the standard XCursor layout:
~/.local/share/icons/MyCursors/
├── index.theme
└── cursors/
├── left_ptr
├── hand1
├── wait
└── ...
GNOME:
gsettings set org.gnome.desktop.interface cursor-theme 'MyCursors'KDE Plasma / most other desktops: open System Settings → Appearance → Cursors and select the theme from the list.
You may need to log out and back in for every application to pick up the change.
.ani files are RIFF containers holding a sequence of standard Windows .cur frames plus timing metadata. The script:
- Parses the
anihheader to get frame count and frame delay (jifRate, in 1/60s units → converted to milliseconds) - Walks the RIFF/LIST chunk tree to pull out each embedded
icon(.cur) frame - Reads each frame's hotspot from the
.curheader and rescales it to match the requested output size - Uses ImageMagick to render each frame to a PNG at the target size
- Feeds the frames, hotspot, and delay into
xcursorgento produce a single XCursor binary per cursor name
Issues and pull requests are welcome — in particular, more filename keyword patterns for the auto-guesser, and additions to the standard cursor name list.