Files
ltk/themes/default/cursors/README.md
Pedro M. de Echanove Pasquin 9ca3b60f3a
Some checks failed
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled
ltk: responsive padding/spacing and scrolling, expanded theme palette, and bundled Adwaita cursors
A mixed pass over the default theme and the layout/input core, plus the toolkit's own cursor set. Grouped by area below.
== Responsive sizing ==
Add `Length::dp( px )` — a "design pixel". It interprets `px` against a configurable reference vmin (default 412 px, the eydos mobile reference width) and returns `Vmin( px / reference * 100 ).clamp( px * 0.7, px * 1.5 )`, so a value authored against a mock-up scales with the surface without collapsing on tiny screens or ballooning on a 4K desktop. The reference is process-global, set via `set_design_reference()` and read via `design_reference()` (stored as f32 bits in an AtomicU32); both are re-exported from `lib.rs`.
Make container and grid insets relative. `Container`'s four padding fields become `Length` instead of `f32`; every setter (`padding`, `padding_h`, `padding_v`, `padding_top`/`right`/`bottom`/`left`) now takes `impl Into<Length>`, so existing `f32` call sites keep compiling via the `From<f32>` shim. The values are resolved against the viewport in `Container::preferred_size` and in the container draw path (`draw/layout.rs`). `WrapGrid`'s `spacing_x`, `spacing_y` and `padding` get the same treatment, with a `resolved( canvas )` helper funnelling the per-frame resolution and `grid()` seeding `Length::px` defaults. Container tests now compare against `Length::px( … )`.
== Scrolling ==
`Scroll::preferred_size` is now axis-aware. A horizontal-only scroll reports its child's natural height rather than claiming all remaining vertical space, so it no longer steals Y from its siblings when it sits inside a `Column`; vertical and both-axis scrolls keep the spacer-like `( max_width, 0.0 )`. `Column`'s space-distribution correspondingly treats a `Scroll` as a vertical space-claimer only when its axis allows Y.
Disambiguate nested scroll viewports by direction. On press the gesture state now collects every scroll viewport under the point (`scroll_candidates`, innermost first) instead of committing to one; on the first 8 px of motion it locks onto the candidate whose axis matches the dominant direction (`scroll_locked`), so a horizontal scroller nested inside a vertical list no longer grabs the wrong axis. The pointer scroll hit test is aligned to the same innermost-first ordering.
== Theme palette ==
`themes/default/theme.json` gains named colours (green / green-deep, yellow, orange / orange-deep, pink / pink-soft, sky-deep, error / error-soft, neutral-tertiary) and new semantic slots in both light and dark modes: `danger`, `text-tertiary`, `accept`, `chip` / `chip-active` / `chip-active-fg`, and `avatar-1` … `avatar-9`.
== Cursors ==
Bundle GNOME's Adwaita cursor theme — the cursors GNOME Shell uses — into `themes/default/cursors/` so a Wayland compositor can draw consistent, complete pointers for ltk applications without the toolkit rasterising cursors itself and without depending on adwaita-icon-theme being installed on the target. The cursors are copied verbatim in XCursor binary format: 35 image files, one per CSS/freedesktop cursor name (default, text, pointer, *-resize, …), plus 27 customary X11 alias symlinks (arrow → default, hand2 → pointer, …); a sibling `cursor.theme` makes the tree a valid XCursor theme. The existing `ltk-theme-default.install` copies `themes/default` recursively, so the directory ships with no packaging change. Applications keep declaring a `CursorShape` per widget over `wp_cursor_shape_v1`; the compositor resolves it against the active theme's `cursors/` directory by name, and the set covers all 34 `CursorShape` variants.
Document the set in `themes/default/cursors/README.md` (what it is, the XCursor layout, the full shape list, how the compositor consumes it, guidance for forks) and `themes/default/cursors/LICENSE.md` (attribution and licence options, modelled on the icons catalogue LICENSE). `lib.rs` lists the cursors in its third-party-assets section.
Close out licensing in `debian/copyright`: a `Files: themes/default/cursors/*` paragraph records the upstream dual offer (CC-BY-SA-3.0 or LGPL-3, and CC-BY-SA-4.0 for the newer assets) attributed to the GNOME Project, with standalone CC-BY-SA-3.0, CC-BY-SA-4.0 and LGPL-3 paragraphs (summary-plus-canonical-URL for the CC licences, matching the existing CC-BY-4.0 entry; LGPL-3 referencing /usr/share/common-licenses/LGPL-3). The files are unmodified from upstream, so there is nothing to declare under the ShareAlike "indicate if changes were made" clause.
Add `tests/cursor_assets.rs`: every `CursorShape` name resolves to a valid XCursor file (Xcur magic, following symlinks), `cursor.theme` is present, no entry is a dangling symlink, and the expected-name list stays in sync with the enum's 34 variants.
2026-05-28 23:11:14 +02:00

3.1 KiB
Raw Permalink Blame History

Default theme cursors

This directory holds the pointer cursors for the ltk default theme. They are GNOME's Adwaita cursors (what GNOME Shell uses), bundled verbatim so the theme is self-contained and does not depend on adwaita-icon-theme being installed on the target system.

Licence and attribution are documented separately in LICENSE.md.

Layout

Standard XCursor theme layout:

themes/default/
├── cursor.theme            # XCursor theme manifest (Name=Default)
└── cursors/
    ├── default             # one binary XCursor file per CSS cursor name
    ├── text
    ├── pointer
    ├── ew-resize
    ├── …
    ├── arrow -> default    # customary X11 alias symlinks
    └── hand2 -> pointer
  • Each regular file is a binary XCursor image set (magic Xcur), carrying one or more nominal sizes and, for the busy cursors, several animation frames.
  • The file name is the CSS / freedesktop cursor name (default, text, pointer, not-allowed, ns-resize, …), which is exactly the name a wp_cursor_shape_v1 shape resolves to. The alias symlinks (arrow, hand2, bottom_left_corner, …) are the legacy X11 names; they are not required by the cursor-shape protocol but are kept so the tree also works as a plain XCursor theme (e.g. for XWayland).

Cursor set

The theme provides a file for every shape ltk can request — the 34 variants of ltk::CursorShape, which mirror cursor_icon::CursorIcon 1:1:

default, context-menu, help, pointer, progress, wait, cell, crosshair, text, vertical-text, alias, copy, move, no-drop, not-allowed, grab, grabbing, e-resize, n-resize, ne-resize, nw-resize, s-resize, se-resize, sw-resize, w-resize, ew-resize, ns-resize, nesw-resize, nwse-resize, col-resize, row-resize, all-scroll, zoom-in, zoom-out.

wait and progress are animated (multiple frames with per-frame delays). The tests/cursor_assets.rs integration test enforces that every name above resolves to a valid XCursor file.

How they are used

ltk does not rasterise cursors itself; as a Wayland client it declares a shape per widget through wp_cursor_shape_v1 and the compositor draws it. The Liberux compositor (forge) resolves the requested shape against the active theme's cursors/ directory by CSS name, picks the image whose nominal size is closest to 24px × output scale, and uploads it at the cursor's hotspot — so these files are what the user actually sees under forge. A compositor that does not advertise wp_cursor_shape_v1, or that uses a different cursor theme, will ignore this directory.

Forking / overriding

To ship different cursors in a derived theme, drop replacement XCursor files (same CSS names) into the fork's cursors/ directory. Keep cursor.theme so the tree stays a valid XCursor theme, and update the Files: themes/default/cursors/* paragraph in debian/copyright plus this directory's LICENSE.md to match the new source and licence.