Create your own mouse cursor theme


  • Create a PNG file of the cursor you want. Preferrably at least in size 32x32 but you can also create multiple resolutions and bundle those into one cursor file. Save this as $(filename).png (e.g. default.png for a regular cursor).
  • Determine the pixel where the hotspot should sit. The hotspot of a cursor is the point where “the click occurs”. (If you have multiple resolutions for your new cursor, you have to do this step for each of them). It’s necessary to use graphic editing software capable of determining the exact pixel for the hotspot. KDE’s own Krita is well suited for this task but of course other software works just as well.
  • Create a $(filename).cursor file with the following content: $(resolution) $(hotspot-x) $(hotspot-y) $(filename) in one line (e.g. 32 10 5 default.png).
  • Open a terminal in the working directory and run xcursorgen $(filename).cursor $(filename) (e.g. xcursorgen default.cursor default).[1]
  • Repeat steps 1-4 for all the different cursors you want to create.
  • Copy the newly created set of X11 cursors to a fresh subdirectory cursors/ inside a directory that you name after your new cursor theme $(themename)/ (e.g. KoolKursors/cursors/).
  • Create symlinks for all the aliases of the cursors ln -s $(filename).png $(alias).png (e.g. ln -s default.png left_ptr.png). [2] See /usr/include/X11/cursorfont.h for a list of cursors.
  • Create a index.theme file in themename/ (Note: not in cursors/ but in its parent directory) and fill it with the necessary information like theme name, description and possibly a fallback cursor theme.[3] An exemplary index.theme file might look like this:
[Icon Theme]
Comment=My very own cursor theme
  • Place the whole themename/ folder and its freshly created content in ~/.icons.
  • Select your new cursor theme in the system settings of your OS.

Done. Enjoy your new KoolKursors theme.

  1. If you want to create animated cursors (like wait) the procedure is a bit different. You need one PNG for each animation frame ($(filename)_#.png). Then add all of these as a list to the $(filename).cursor file with the following content: $(resolution) $(hotspot-x) $(hotspot-y) $(filename) $(animationtime) (e.g. 32 16 16 wait_1.png 50 16 16 wait_2.png 50 each of them in a separate line).
  2. This task can/should be scripted, provided that you have a complete list of regular cursor names and their irregular aliases. Note that this step might cause some frustration regarding incomplete lists of cursor name aliases.
  3. If you want to add translations for multiple languages, you can do so by using language tags like [en], [de], [fr], etc. for each language (e.g. Comment[en]=My very own cursor theme). Put each of them in a separate line within the index.theme file.

This page was last edited on 29 April 2021, at 14:12. Content is available under Creative Commons License SA 4.0 unless otherwise noted.