Custom Cursors and Pointer Sizes in GNOME Shell
This article explores how GNOME Shell manages cursor themes and pointer sizing across the Linux desktop environment. It covers the directory hierarchy for cursor installations, the GSettings schemas used by Mutter and GTK, how GNOME Shell synchronizes pointer adjustments across legacy X11 and modern Wayland sessions, and the technical mechanics behind cursor scaling.
Cursor Theme Directory Structure and Discovery
GNOME Shell relies on standard freedesktop.org icon theme specifications to discover custom cursors. When searching for cursor themes, the compositor and its underlying toolkits look inside specific file system directories in a defined hierarchy:
- Local user installations:
~/.local/share/icons/and legacy~/.icons/ - System-wide installations:
/usr/share/icons/and/usr/local/share/icons/
For a cursor package to be recognized, it must contain a valid
layout. The root of the theme folder requires an
index.theme file containing the theme metadata (such as the
name and inherited themes) and a dedicated cursors/
subdirectory housing the binary cursor images.
Applying Themes via GSettings
GNOME Shell does not directly manage theme settings via static
configuration files; instead, it uses the dconf
configuration system. The cursor theme selection is tracked by the
org.gnome.desktop.interface schema.
To view the active cursor theme:
gsettings get org.gnome.desktop.interface cursor-themeTo assign a new cursor theme manually:
gsettings set org.gnome.desktop.interface cursor-theme 'Custom-Theme-Name'Utility applications like GNOME Tweaks modify this same key under the
hood. When this value updates, the GNOME Settings Daemon
(gsd-xsettings) broadcast the change to active graphical
applications.
Adjusting Pointer Size
GNOME Shell provides built-in accessibility options to scale the cursor size. In the GNOME Control Center, users can select predefined sizes via Accessibility > Seeing > Cursor Size.
For arbitrary sizes, GNOME uses the integer-based
cursor-size key in the same interface schema. The standard
default is 24 pixels.
To read the current pointer size:
gsettings get org.gnome.desktop.interface cursor-sizeTo set a custom size (such as 32, 48, or 64 pixels):
gsettings set org.gnome.desktop.interface cursor-size 32When this value is updated, the window manager and applications query the active theme for matching cursor bitmaps. If a theme does not supply pre-rendered assets at the requested pixel dimension, the rendering engine scales the closest available bitmap, which can occasionally lead to visual artifacts or blurriness if vector formats are not supported by the asset pack.
Wayland vs. X11 Pointer Management
The implementation of cursor rendering differs significantly depending on the display server protocol in use.
Wayland Sessions
In a Wayland session, Mutter (GNOME's compositor) handles the cursor display directly on the hardware plane or software composition layer.
- Over the desktop shell, top bar, and compositor surfaces, Mutter
renders the cursor based on the
org.gnome.desktop.interfacesettings. - Inside client windows, Wayland clients are technically responsible
for drawing their own pointer surfaces using the
wl_pointerinterface. - To maintain visual consistency, GTK and Qt runtimes automatically pull the cursor theme and size configurations from GSettings, ensuring the pointer matches when moving between the desktop shell and individual application windows.
X11 Sessions
In legacy X11 sessions, the X server itself maintains cursor state.
GNOME Shell sets the root cursor via xsetroot and updates
the XCURSOR_THEME and XCURSOR_SIZE environment
variables through the session startup scripts.
Additionally, the GNOME Settings Daemon mirrors the settings to the
~/.Xresources database or XSettings registry, allowing
non-GTK toolkits (like Qt or legacy Athena widgets) to honor the size
and theme configurations without desynchronizing from GNOME Shell's
native chrome.
Display Scaling and HiDPI Interactions
When system fractional scaling or integer scaling (200%) is enabled in GNOME Display Settings, cursor scaling behavior adapts:
- Under Wayland, Mutter automatically multiplies the base
cursor-sizeby the integer scale factor of the monitor the pointer currently occupies. When crossing between monitors of differing pixel densities, Mutter dynamically swaps the cursor buffer size to match the target display's scale factor. - Under X11, global scaling scales the base cursor globally, which can sometimes lead to oversized pointers on secondary monitors with lower DPI.