git.lucas.co / cce-icons
SVG icon set
git clone https://git.lucas.co/cce-icons.git

cursors/README.md (2.5K)

 1 # cce cursor theme
 2 
 3 A full XCursor theme in the cce language: **white fill, `#282a36` outline**, with
 4 a rounded **plus** as the default pointer rather than an arrow (it follows the
 5 earlier `crosshair-theme` experiment, and matches `svg/plus.svg` in the icon set).
 6 
 7 ```
 8 svg/        the sources — one SVG per distinct shape, 32x32 viewBox
 9 build.py    svg -> PNG (magick) -> XCursor binary + alias symlinks
10 dist/       build output (untracked)
11 ```
12 
13 ## Build
14 
15 ```sh
16 python3 build.py              # -> dist/cce
17 python3 build.py --install    # -> $XDG_DATA_HOME/icons/cce
18 python3 build.py --only text  # rebuild one cursor while iterating
19 ```
20 
21 `xcursorgen` is **not** required: `build.py` writes the XCursor container itself
22 (header, per-size TOC, premultiplied BGRA image chunks). Sizes are 24/32/48/64/96,
23 covering scale 1 through 4 at a 24px nominal cursor.
24 
25 ## Using it
26 
27 The theme installs to `~/.local/share/icons/cce` but nothing selects it. The
28 compositor asks for the theme literally named **`default`** — `Cursor::init`
29 passes a null theme name to `wlr_xcursor_manager_create`, which does *not* read
30 `$XCURSOR_THEME`. So point the `default` theme at this one:
31 
32 ```ini
33 # ~/.local/share/icons/default/index.theme
34 [Icon Theme]
35 Name=Default
36 Inherits=cce
37 ```
38 
39 That covers GTK and Qt apps too. (`ccectl` has no cursor-theme command; the other
40 route is the `cce-window-management` protocol's `set_xcursor_theme`, which reaches
41 `Cursor::set_theme`.)
42 
43 ## Adding or changing a cursor
44 
45 1. Drop a 32x32 SVG in `svg/`.
46 2. Add a row to `CURSORS` in `build.py`: `(name, svg stem, hotspot x, hotspot y, [aliases])`.
47    Hotspots are in **source viewBox units** and are scaled per size.
48 3. Rebuild.
49 
50 The alias lists are load-bearing, not decoration: GTK and Qt still request X11
51 legacy names (`xterm`, `fleur`, `sb_v_double_arrow`) and hashed names
52 (`00008160000006810000408080010102`). A missing alias is the usual reason a theme
53 looks half-applied in one toolkit.
54 
55 Cursors with a state badge (`copy`, `alias`, `help`, `context-menu`, `progress`)
56 use a compact plus in the upper-left with the badge lower-right, so their hotspot
57 is `(11,11)`, not the centre.
58 
59 ## Animation
60 
61 Every cursor here is single-frame. The compositor *can* drive animated cursors —
62 see `Cursor::advance_xcursor_frame` in cce-compositor, which walks XCursor's
63 per-frame delays — so an animated `wait`/`progress` only needs extra frames:
64 give `build.py` a list of SVGs per cursor and a delay, and emit one image chunk
65 per frame per size (the container already supports it; `xcursor()` takes a
66 `delay` field it currently always writes as 0).