New `adw` feature (gated separately from `gtk`, since AdwApplicationWindow
isn't compatible with gtk4-layer-shell — the five panel/launcher apps stay
on plain `gtk`, only breadman/breadhelp-style plain-window apps want this):
preferences_group/toggle_row/spin_row/action_row/preferences_page, wrapping
libadwaita's PreferencesGroup/SwitchRow/SpinRow/ActionRow/PreferencesPage.
adw::init() also forces dark color-scheme, since bread-theme's whole design
is a fixed dark base regardless of system GTK preference.
These directly target defects a design critique found: hand-rolled
switch+label rows with no intrinsic width (breadman/settings' ~1400px
stretched toggles) and spinners stranded far from their label — both just
don't happen when the row is a real AdwSwitchRow/AdwSpinRow instead of a
box assembled from scratch.
Also, two shared-stylesheet fixes usable by every app immediately, gtk
feature only:
- `scale` (slider) had no rule at all, so every volume/brightness slider
showed GTK's own default blue instead of the palette accent — the same
critique flagged breadbar's control-panel sliders contradicting its own
on-brand OSD fill two clicks away.
- A new `chip()`/`set_chip_active()` helper in gtk.rs uses the existing
(already-tokenized, already-defined) `.chip`/`.pill` stylesheet rule
instead of each app hand-rolling its own filter-chip CSS — which is how
breadclip/breadpad/breadman ended up with three different, mutually
disagreeing pill fills for what's supposed to be one shared component.
The stylesheet is written with write-tmp-then-rename (atomic), which replaces the
inode. A monitor on the file itself caught the first replace then went deaf
(inotify reports DELETE_SELF and never re-arms), so `bread-theme reload` updated
the file but no running GUI ever recoloured. Monitor the parent directory and
filter for the stylesheet filename instead — that fires on every reload. Verified
against a real atomic-rename write (event arrives as Renamed with the new name in
other_file, so match both file and other_file).
Readability: pywal can emit a light value in any palette slot, and the shared
sheet assumed dark backgrounds (white text), so text vanished on light surfaces/
accents. Add ink_on() — a WCAG-luminance pick of near-black/near-white per
background — exposed as @on-bg/@on-surface/@on-accent/@on-red/@on-overlay. The
component sheet now sets colour on containers and lets labels inherit (de-emphasis
via opacity), dropping the blanket `label { color }` rule that overrode
coloured-background text. pywal hues are untouched.
Hot reload: add gtk::apply_app_css(closure) — applies an app's own CSS now and
re-runs the closure whenever the shared theme file is rewritten, so apps recolour
in place. New `bread-theme reload` verb rewrites the file (atomic rename trips
every running GUI's monitor) — the command to run after changing pywal colours.
Adds the single source of truth for bread GUI styling so the apps stop
each re-implementing (and drifting on) component CSS:
- stylesheet(&Palette): full component sheet (buttons, entries, switches,
dropdowns, lists/rows/sidebars, cards, chips, scrollbars, headings) built
from the design tokens + a canonical @define-color block (surface=color0,
overlay=color7, accent=color4).
- render() / shared_css_path() / write_shared_css(): render for the current
pywal palette and write to $XDG_RUNTIME_DIR/bread/theme.css.
- gtk::apply_shared(): load that file (or a rendered fallback) at APPLICATION
priority and watch it, so every app recolours live with no rebuild.
- new `bread-theme` CLI (generate|path|print) — gtk-free, light. Run at
session start and on palette change; apps pick it up via the file watch.
The contract is a CSS *file*, so apps stay decoupled from this crate's gtk4
version. Tests cover the stylesheet, path, and render helpers.