skip to navigation skip to content

make your own linux cursor

posted on 04.26.26

foreward

did you know it's difficult to find a good guide to making your own linux mouse cursor? like, just one good one, i mean. i had to cross-reference many different threads and articles to make my newest one - and it was still pretty difficult to remember the steps LOL!

so i thought: why not write out my process somewhere people can reference it too? that way, i can link all my sources *and* do things in a straightforward manner! isn't that so niceys.

obviously YMMV. this guide is not made for windows or mac, and was tested solely on my linux mint 22.1 install. if something borks for you, i dunno how to fix it probably LOL. good luck my friend

the guide

step 1: make graphics

mouse cursors come in increments of 16, 32, or 48 pixels square. that means %n wide by %n tall. you can make them larger, certainly, but for most usecases you'll probably be using 32 or 48. (32 is the size on windows, generally.)

i used aseprite to create .png graphics for each state i anticipated myself needing/using regularly. don't feel like you have to do a "full set" unless you're doing this for the public; in any personal project, only go as far as you need to. overscoping brings pain.....

it is nigh impossible to find a real, comprehensive list of all the mouse states you can make. the ones i ended up using are:

all-scroll, cell, default, grab, grabbing, pointer (for hovering links mostly), ns/ew-resize, help, stop, text, wait, zoom in, and zoom out

this does not count the ones i aliased later, but don't worry about it yet.

i created all of my cursor files using aseprite. if you don't have that, you should try libresprite, which is an open-source fork of aseprite. otherwise, use whatever you use for pixel art normally.

step 2: setting up the folder

to create a system-wide cursor theme, you need to create a new folder in ~/usr/share/icons. i titled mine 'forestcursor' for this example.

inside this folder, you want to make a file called 'index.theme'. the inside of the text file should look like this:

[Icon Theme] Name=forestcursor Inherits=Breeze

note that the name needs to match the folder name, and 'inherits' is just what cursors it uses to fill in gaps in your customization, like a minecraft resource pack.

next, make a subfolder named 'cursors', navigate to it, and put all your graphics into it.

step 3: creating cursor files

now you need to create config files for each cursor. each should be titled .cursor and have the following input syntax:

size offsetx offsety filename.png

for example:

48 0 0 defaultmouse.png

you can also include animation frame data like so:

48 0 0 link1.png 500 48 0 0 link2.png 500

where '500' is '500ms', so each frame takes 500 milliseconds to display before moving to the next.

right click > open in terminal, so you're in the command prompt while in this folder. check to see if you have xcursorgen installed:

apt search xcursorgen

you should, in theory, because it's included in many distros by default (mine included), but it's good to make sure.

you will now type commands in this format:

xcursorgen cursorname.cursor cursorname

this creates a 'cursor' file named 'cursorname' based on your config file named 'cursorname.cursor'. for example, if i wanted to create one for my default cursor:

xcursorgen defaultcursor.cursor default

this creates a cursor file named 'default' using my defaultcursor config file.

you may find it easier to do this in a batch process rather than line by line. same goes for the next step in this process too. you'll want to generate each cursor like this.

step 4: symlinks

now, these filenames you gave are descriptive, but maybe not the ones the theme identifies as keywords for a cursor state. that's what symlinks are for!

this allows you to create an alias for a file. imagine it like a shortcut to the file. it takes less space than duplicating a file a billion times.

to create a symlink for your cursors, you'll do the following:

ln -s cursorname alias

for example:

ln -s default left_ptr

this takes my cursor file named 'default' and aliases it for 'left-ptr'.

there are a ton of cursor names to cover, and many of them are just ones that you'll want aliases for anyway.

a handy table of most* of the different values (taken from my folder directory of Bibata-Modern-Classic):

cursor namenotes
aliasicon used for symlink drag-n-drop, i think (citation needed)
all-scrolla two-axis cross-section with arrows on the ends
arrow
bd_double_arrow
bottom_left_corner
bottom_right_corner
bottom_side
bottom_tee
cella crosshair
center_ptr
circle
closedhanda closed hand.
defaulttake a guess
color-pickereyedropper tool
col-resizea horizontal double-ended arrow (like < -- > ); make sure its offset (anchor) is set correctly in the .cursor file before generating
context-menuusually has an 'i' for information next to a smaller cursor; used for context menus of course
copyusually a hand or cursor with a plus sign or two page symbol next to it
cross
crossed_circle
crosshairsee 'cell'
cross_reverse
defaultyour best friend
diamond_cross
dnd-askprompted when hovering over a field that asks for a drag-n-drop element
dnd-link
dnd-move
dnd_no_drop
dnd-none
dotbox
dot_box_mask
double_arrow
down-arrow
draft
draft_large
draft_small
draped_box
e-resize
ew-resizea horizontal double-ended arrow (like < -- > ); make sure its offset (anchor) is set correctly in the .cursor file before generating
fd_double_arrow
fleur
forbidden
grab
grabbingsee 'closedhand'
hand1see 'grab'
hand2see 'grabbing'
h_double_arrowsee 'ew-resize'
help
ibeam
icon
left-arrow
left_ptri usually just dupe my default icon for this
left_ptr_help
left_ptr_watch
left_side
left_tee
link
ll_angle
lr_angle
move
ne-resize
nesw-resizedouble-ended-arrow-line angled from north east to south west (forward slash)
no-drop
not-allowed
n-resize
ns-resizevertical line with arrows on the ends, check offset in your cursor file
nw-resize
nwse-resizedouble-ended-arrow-line angled from north west to south east (back slash)
openhandinverse of closedhand
pencil
pirateand why do we need a pirate cursor
plus
pointeri aliased my hyperlink hover icon for this one
pointer-move
pointing_hand
progresssee 'wait'
question_arrow
right-arrow
right_ptr
right_side
right_tee
row-resizesee ns-resize
sb_down_arrow
sb_h_double_arrow
sb_left_arrow
sb_right_arrow
sb_up_arrow
sb_v_double_arrow
se-resize
size_all
size_bdiagsee 'nwse-resize'
size_fdiagsee 'nesw-resize'
size-horsee 'ew-resize'
size_horsee 'size-hor'
size-versee 'ns-resize'
size_versee 'size-ver'
split_h
split_v
s-resize
sw-resize
target
tcross
texttextbox indicator
top_left_arrow
top_left_corner
top_right_corner
top_side
top_tee
ul_angle
up-arrow
ur_angle
v_double_arrow
vertical-text
wait
watch
wayland-cursor
whats_thisowo
w-resize
x-cursor
X_cursorand why is the x capitalized here
xtermvertical text indicator. you heard me.
zoom-in
zoom-out

please be sure to note differences between an underscore and a dash. they are wildly inconsistent, even in groups of the same variable (see: dnd).

* there are a portion of them that have some sort of hashcode name that i dont feel like figuring out or copying so do your own research if you know what they do and want them for some reason

step 4: profit

go to your system settings and open "themes". if it's not already, click 'advanced settings' to get to advanced view.

change 'mouse pointer' to your new cursor. if you don't see it, check to make sure that the name of the folder is the same as the name in index.theme.

and there ya go. now you have your own cursor. good job!!

sources

Xcursorgen - arch linux wiki

create your own mouse cursor - kde docs

xcursor theme tutorial - sole on github

there was another guide i used but i cannot find it for the life of me now, sorry!

tags... guide article