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.
352 lines
13 KiB
JSON
352 lines
13 KiB
JSON
{
|
|
"theme": {
|
|
"id": "default",
|
|
"name": "Default"
|
|
},
|
|
|
|
"fonts": {
|
|
"sora": {
|
|
"name": "Sora",
|
|
"fallbacks": ["system-ui", "sans-serif"],
|
|
"sources": [
|
|
{ "weight": 300, "path": "/usr/share/fonts/opentype/sora/Sora-Light.otf" },
|
|
{ "weight": 400, "path": "/usr/share/fonts/opentype/sora/Sora-Regular.otf" },
|
|
{ "weight": 600, "path": "/usr/share/fonts/opentype/sora/Sora-SemiBold.otf" },
|
|
{ "weight": 700, "path": "/usr/share/fonts/opentype/sora/Sora-Bold.otf" }
|
|
]
|
|
}
|
|
},
|
|
|
|
"colors": {
|
|
"navy": "#0A032E",
|
|
"indigo": "#221A5A",
|
|
"midnight": "#181045",
|
|
"window-bar-dark": "#2B2838",
|
|
"white": "#FFFFFF",
|
|
"off-white": "#EAE9EB",
|
|
"sky": "#2AA7F7",
|
|
"sky-mist": "#E6F0FB",
|
|
"cyan": "#04D9FE",
|
|
"cyan-soft": "#02CFFF",
|
|
"teal": "#00CEB1",
|
|
"teal-deep": "#006073",
|
|
"danger": "#E5484D",
|
|
"slate": "#5F5F68",
|
|
"silver": "#D8D7DE",
|
|
"glass-hi": "#555555",
|
|
"glass-elev": "#212121",
|
|
"ink": "#000000",
|
|
"cyan-deep": "#0091AD",
|
|
"teal-fill-end": "#00687C",
|
|
"green": "#00D344",
|
|
"green-deep": "#00B41A",
|
|
"yellow": "#FFD400",
|
|
"orange": "#FF8156",
|
|
"orange-deep": "#BD6403",
|
|
"pink": "#EF15FA",
|
|
"pink-soft": "#FFD7FF",
|
|
"sky-deep": "#1E8FD9",
|
|
"error": "#F00013",
|
|
"error-soft": "#FF6B6B",
|
|
"neutral-tertiary": "#807E88"
|
|
},
|
|
|
|
"gradients": {
|
|
"fill-cyan-slider": {
|
|
"type": "linear",
|
|
"angle_deg": 0,
|
|
"space": "linear-rgb",
|
|
"stops": [
|
|
{ "pos": 0, "color": "@teal-fill-end" },
|
|
{ "pos": 1, "color": "@cyan" }
|
|
]
|
|
},
|
|
"fill-cyan-toggle": {
|
|
"type": "linear",
|
|
"angle_deg": 0,
|
|
"space": "linear-rgb",
|
|
"stops": [
|
|
{ "pos": 0, "color": "@cyan" },
|
|
{ "pos": 1, "color": "@cyan-deep" }
|
|
]
|
|
},
|
|
"track-glass-light": {
|
|
"type": "linear",
|
|
"angle_deg": 180,
|
|
"space": "linear-rgb",
|
|
"stops": [
|
|
{ "pos": 0, "color": "@white/80" },
|
|
{ "pos": 1.1781, "color": "@off-white/80" }
|
|
]
|
|
},
|
|
"surface-glass-dark": {
|
|
"type": "linear",
|
|
"angle_deg": 180,
|
|
"space": "linear-rgb",
|
|
"stops": [
|
|
{ "pos": 0, "color": "@sky/80" },
|
|
{ "pos": 1.1781, "color": "@navy/80" }
|
|
]
|
|
}
|
|
},
|
|
|
|
"inset_stacks": {
|
|
"glass-insets": [
|
|
{ "offset": [ 0, 1 ], "blur": 4, "color": "@ink/0F", "blend": "normal" }
|
|
],
|
|
"glass-insets-rich": [
|
|
{ "offset": [-3.6, -3.6], "blur": 13.5, "color": "@white", "blend": "normal" },
|
|
{ "offset": [ 1.8, 1.8], "blur": 1.8, "color": "@white", "blend": "normal" },
|
|
{ "offset": [ 1.8, 1.8], "blur": 7.2, "color": "@ink/26", "blend": "normal" }
|
|
]
|
|
},
|
|
|
|
"modes": {
|
|
"light": {
|
|
"launcher": { "background": "@white/E6", "border_radius": 24.0 },
|
|
"window_controls": {
|
|
"bar_bg": "@off-white",
|
|
"icon": "@slate",
|
|
"hover_bg": "@navy/14",
|
|
"pressed_bg": "@navy/24",
|
|
"close_hover_bg": "@danger",
|
|
"close_icon": "@white",
|
|
"focus_ring": "@teal"
|
|
},
|
|
"slots": {
|
|
"bg-page": { "type": "color", "value": "@sky-mist", "meta": { "semantic": "palette/bg" } },
|
|
"surface": { "type": "color", "value": "@white/EE", "meta": { "semantic": "palette/surface" } },
|
|
"surface-alt": { "type": "color", "value": "@white/D9", "meta": { "semantic": "palette/surface_alt" } },
|
|
"text-primary": { "type": "color", "value": "@navy", "meta": { "semantic": "palette/text_primary" } },
|
|
"text-secondary": { "type": "color", "value": "@navy/99", "meta": { "semantic": "palette/text_secondary" } },
|
|
"accent": { "type": "color", "value": "@cyan", "meta": { "semantic": "palette/accent" } },
|
|
"divider": { "type": "color", "value": "@navy/14", "meta": { "semantic": "palette/divider" } },
|
|
"icon": { "type": "color", "value": "@navy", "meta": { "semantic": "palette/icon" } },
|
|
"danger": { "type": "color", "value": "@error", "meta": { "semantic": "palette/danger" } },
|
|
"text-tertiary": { "type": "color", "value": "@neutral-tertiary", "meta": { "semantic": "palette/text_tertiary" } },
|
|
"accept": { "type": "color", "value": "@green-deep", "meta": { "semantic": "status/accept" } },
|
|
"chip": { "type": "color", "value": "@off-white", "meta": { "semantic": "palette/chip" } },
|
|
"chip-active": { "type": "color", "value": "@navy", "meta": { "semantic": "palette/chip_active" } },
|
|
"chip-active-fg": { "type": "color", "value": "@white", "meta": { "semantic": "palette/chip_active_fg" } },
|
|
"avatar-1": { "type": "color", "value": "@sky", "meta": { "semantic": "avatar/1" } },
|
|
"avatar-2": { "type": "color", "value": "@green", "meta": { "semantic": "avatar/2" } },
|
|
"avatar-3": { "type": "color", "value": "@orange", "meta": { "semantic": "avatar/3" } },
|
|
"avatar-4": { "type": "color", "value": "@pink", "meta": { "semantic": "avatar/4" } },
|
|
"avatar-5": { "type": "color", "value": "@yellow", "meta": { "semantic": "avatar/5" } },
|
|
"avatar-6": { "type": "color", "value": "@sky-deep", "meta": { "semantic": "avatar/6" } },
|
|
"avatar-7": { "type": "color", "value": "@cyan", "meta": { "semantic": "avatar/7" } },
|
|
"avatar-8": { "type": "color", "value": "@green-deep", "meta": { "semantic": "avatar/8" } },
|
|
"avatar-9": { "type": "color", "value": "@orange-deep", "meta": { "semantic": "avatar/9" } },
|
|
|
|
"shadows-glass": {
|
|
"type": "shadows",
|
|
"shadows": [
|
|
{ "offset": [0, 0], "blur": 9, "color": "@glass-elev/40" }
|
|
],
|
|
"meta": { "semantic": "effect/glass/elevation" }
|
|
},
|
|
|
|
"surface-slider-track": {
|
|
"type": "surface",
|
|
"fill": "@track-glass-light",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/slider-track" }
|
|
},
|
|
|
|
"surface-slider-fill": {
|
|
"type": "surface",
|
|
"fill": "@fill-cyan-slider",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/slider-fill" }
|
|
},
|
|
|
|
"surface-card": {
|
|
"type": "surface",
|
|
"fill": {
|
|
"type": "linear",
|
|
"angle_deg": 180,
|
|
"space": "linear-rgb",
|
|
"stops": [
|
|
{ "pos": 0, "color": "@white/80" },
|
|
{ "pos": 1, "color": "@off-white/80" }
|
|
]
|
|
},
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/card" }
|
|
},
|
|
|
|
"surface-panel": {
|
|
"type": "surface",
|
|
"fill": { "type": "solid", "color": "@white/40" },
|
|
"meta": { "semantic": "effect/glass/panel" }
|
|
},
|
|
|
|
"surface-card-flat": {
|
|
"type": "surface",
|
|
"fill": {
|
|
"type": "linear",
|
|
"angle_deg": 180,
|
|
"space": "linear-rgb",
|
|
"stops": [
|
|
{ "pos": 0, "color": "@white/B3" },
|
|
{ "pos": 1, "color": "@off-white/B3" }
|
|
]
|
|
},
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/card-flat" }
|
|
},
|
|
|
|
"surface-toggle-active": {
|
|
"type": "surface",
|
|
"fill": "@fill-cyan-toggle",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": [
|
|
{ "offset": [0, 0], "blur": 0, "spread": 0.6, "color": "@teal-deep", "blend": "normal" }
|
|
],
|
|
"meta": { "semantic": "effect/toggle/active" }
|
|
},
|
|
|
|
"surface-slider-track-flat": {
|
|
"type": "surface",
|
|
"fill": "@track-glass-light",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets-rich",
|
|
"meta": { "semantic": "effect/glass/slider-track-flat" }
|
|
},
|
|
|
|
"surface-slider-fill-flat": {
|
|
"type": "surface",
|
|
"fill": "@fill-cyan-slider",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": [
|
|
{ "offset": [ 0, 1 ], "blur": 4, "color": "@ink/0F", "blend": "normal" },
|
|
{ "offset": [ 0, 0 ], "blur": 0, "spread": 0.6, "color": "@teal-deep", "blend": "normal" }
|
|
],
|
|
"meta": { "semantic": "effect/glass/slider-fill-flat" }
|
|
}
|
|
}
|
|
},
|
|
|
|
"dark": {
|
|
"launcher": { "background": "@indigo/E6", "border_radius": 24.0 },
|
|
"window_controls": {
|
|
"bar_bg": "@window-bar-dark",
|
|
"icon": "@silver",
|
|
"hover_bg": "@white/18",
|
|
"pressed_bg": "@white/26",
|
|
"close_hover_bg": "@danger",
|
|
"close_icon": "@white",
|
|
"focus_ring": "@teal"
|
|
},
|
|
"slots": {
|
|
"bg-page": { "type": "color", "value": "@navy", "meta": { "semantic": "palette/bg" } },
|
|
"surface": { "type": "color", "value": "@navy", "meta": { "semantic": "palette/surface" } },
|
|
"surface-alt": { "type": "color", "value": "@navy/99", "meta": { "semantic": "palette/surface_alt" } },
|
|
"text-primary": { "type": "color", "value": "@white/EE", "meta": { "semantic": "palette/text_primary" } },
|
|
"text-secondary": { "type": "color", "value": "@white/D9", "meta": { "semantic": "palette/text_secondary" } },
|
|
"accent": { "type": "color", "value": "@cyan", "meta": { "semantic": "palette/accent" } },
|
|
"divider": { "type": "color", "value": "@white/14", "meta": { "semantic": "palette/divider" } },
|
|
"icon": { "type": "color", "value": "@white", "meta": { "semantic": "palette/icon" } },
|
|
"danger": { "type": "color", "value": "@error-soft", "meta": { "semantic": "palette/danger" } },
|
|
"text-tertiary": { "type": "color", "value": "@white/80", "meta": { "semantic": "palette/text_tertiary" } },
|
|
"accept": { "type": "color", "value": "@green", "meta": { "semantic": "status/accept" } },
|
|
"chip": { "type": "color", "value": "@white/14", "meta": { "semantic": "palette/chip" } },
|
|
"chip-active": { "type": "color", "value": "@cyan", "meta": { "semantic": "palette/chip_active" } },
|
|
"chip-active-fg": { "type": "color", "value": "@navy", "meta": { "semantic": "palette/chip_active_fg" } },
|
|
"avatar-1": { "type": "color", "value": "@sky", "meta": { "semantic": "avatar/1" } },
|
|
"avatar-2": { "type": "color", "value": "@green", "meta": { "semantic": "avatar/2" } },
|
|
"avatar-3": { "type": "color", "value": "@orange", "meta": { "semantic": "avatar/3" } },
|
|
"avatar-4": { "type": "color", "value": "@pink", "meta": { "semantic": "avatar/4" } },
|
|
"avatar-5": { "type": "color", "value": "@yellow", "meta": { "semantic": "avatar/5" } },
|
|
"avatar-6": { "type": "color", "value": "@sky-deep", "meta": { "semantic": "avatar/6" } },
|
|
"avatar-7": { "type": "color", "value": "@cyan", "meta": { "semantic": "avatar/7" } },
|
|
"avatar-8": { "type": "color", "value": "@green-deep", "meta": { "semantic": "avatar/8" } },
|
|
"avatar-9": { "type": "color", "value": "@orange-deep", "meta": { "semantic": "avatar/9" } },
|
|
|
|
"shadows-glass": {
|
|
"type": "shadows",
|
|
"shadows": [
|
|
{ "offset": [0, 0], "blur": 9, "color": "@glass-elev/40" }
|
|
],
|
|
"meta": { "semantic": "effect/glass/elevation" }
|
|
},
|
|
|
|
"surface-slider-track": {
|
|
"type": "surface",
|
|
"fill": "@surface-glass-dark",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/slider-track" }
|
|
},
|
|
|
|
"surface-slider-fill": {
|
|
"type": "surface",
|
|
"fill": "@fill-cyan-slider",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/slider-fill" }
|
|
},
|
|
|
|
"surface-card": {
|
|
"type": "surface",
|
|
"fill": "@surface-glass-dark",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/card" }
|
|
},
|
|
|
|
"surface-panel": {
|
|
"type": "surface",
|
|
"fill": { "type": "solid", "color": "@navy/40" },
|
|
"meta": { "semantic": "effect/glass/panel" }
|
|
},
|
|
|
|
"surface-card-flat": {
|
|
"type": "surface",
|
|
"fill": "@surface-glass-dark",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/card-flat" }
|
|
},
|
|
|
|
"surface-toggle-active": {
|
|
"type": "surface",
|
|
"fill": "@fill-cyan-toggle",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": [
|
|
{ "offset": [-3.6, -3.6], "blur": 13.5, "color": "@glass-hi", "blend": "plus-lighter" },
|
|
{ "offset": [ 1.8, 1.8], "blur": 1.8, "color": "@glass-hi", "blend": "plus-lighter" },
|
|
{ "offset": [ 0.45, 0.45], "blur": 0.9, "color": "@ink", "blend": "overlay" },
|
|
{ "offset": [ 1.8, 1.8], "blur": 7.2, "color": "@ink/26", "blend": "normal" },
|
|
{ "offset": [0, 0], "blur": 0, "spread": 0.6, "color": "@cyan", "blend": "normal" }
|
|
],
|
|
"meta": { "semantic": "effect/toggle/active" }
|
|
},
|
|
|
|
"surface-slider-track-flat": {
|
|
"type": "surface",
|
|
"fill": "@surface-glass-dark",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": "@glass-insets",
|
|
"meta": { "semantic": "effect/glass/slider-track-flat" }
|
|
},
|
|
|
|
"surface-slider-fill-flat": {
|
|
"type": "surface",
|
|
"fill": "@fill-cyan-slider",
|
|
"shadows": "shadows-glass",
|
|
"inset_shadows": [
|
|
{ "offset": [ 0, 1 ], "blur": 4, "color": "@ink/0F", "blend": "normal" },
|
|
{ "offset": [ 0, 0 ], "blur": 0, "spread": 0.6, "color": "@teal-deep", "blend": "normal" }
|
|
],
|
|
"meta": { "semantic": "effect/glass/slider-fill-flat" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|