Continues reducing terminal-reliance for graphical system control. Five
new panels, plus three GUI apps shipped for things better served by an
existing dedicated tool than reimplemented in bos-settings
(gnome-disk-utility, gufw, mission-center).
- Power: battery status/health, brightness, charge-limit thresholds where
the hardware exposes them, TLP profile shown read-only by design (no
Balanced/Performance switcher — TLP auto-selects by power source, and
power-profiles-daemon isn't installed because it conflicts with tlp).
- Firewall: ufw enable/disable, add/remove rules, view active rules.
ufw's own status check requires root (confirmed against the installed
script — not just changes, reads too), so unlike every other panel this
one does NOT query state in build(): every view is constructed eagerly
at app launch, and an unconditional privileged read here would mean a
polkit prompt on every single bos-settings open. Starts blank with a
"Status not loaded" placeholder; state loads only on an explicit Refresh
click, with a guard so refresh's own set_active() doesn't loop back into
triggering ufw enable/disable.
- Users: add/remove accounts, change passwords. All through pkexec on a
background thread. Can't remove the account you're currently running as.
- AUR: search via yay. Installing deliberately opens a terminal instead of
a silent --noconfirm install — yay's interactive PKGBUILD diff review and
sudo prompt are the actual safety mechanism against a malicious AUR
package, not a formality worth automating away.
- Firmware: fwupd device list + updates, same stream-output-then-refresh
pattern as Packages.
packages.x86_64: gnome-disk-utility, gufw, mission-center for disk/firewall/
task-manager GUIs that don't need reinventing inside bos-settings.
New panels: About, Network (Wi-Fi/Ethernet via nmcli), Sound (PipeWire
volume/device via pactl), Date & Time (timedatectl), and Clipboard
(breadclip previously had no bos-settings presence at all despite running
its own daemon).
Layout: every panel now shares one scaffold (6 views were hand-rolling their
own, inconsistently) with a centered, width-capped content column instead of
rows stretching edge-to-edge on a wide window with the control stranded far
from its label. Rows render as individual cards. Sidebar got human labels +
icons + task-based grouping (System/Personalization/Maintenance/About)
instead of raw binary names under "Apps"/"System".
New capability: a shared service_control() widget gives every bread app
backed by a systemd --user daemon (breadd, breadbox-sync, breadcrumbs,
breadmill, breadclipd) live status plus Start/Stop/Restart/View logs —
previously these panels only ever edited a TOML file and hoped the running
process picked it up. breadbar (no systemd unit) gets an equivalent: Save
now actually sends the SIGHUP its own reload mechanism needs, instead of
just claiming to in the hint text.
Fixed two real bugs surfaced while building About: CPU model string kept a
stray leading tab+colon (trim_start_matches was missing '\t'), and GPU
showed "unknown" on hardware whose lspci entry says "Display controller"
instead of "VGA compatible controller".
Local CSS patches (bos-settings/src/theme.rs) for two upstream bread-theme
gaps: suggested/destructive buttons and scale widgets don't clear Adwaita's
default background-image, so flat colour overrides were invisible; and
destructive-action red must not be pywal-derived (it can land on gold
depending on the wallpaper, indistinguishable from a primary action).
Pulls the fix for panels turning brown/off-hue when pywal extracts a light
or muddy background from the wallpaper — background/surface now stay BOS's
fixed dark constants regardless of what the wallpaper looks like.
- breadbox panel edited [[contexts]] but breadbox reads [[context]]
(serde rename mismatch) — panel was always empty and Save appended
a dead array.
- Packages panel parsed installed.json as a flat map instead of
unwrapping {"packages": {...}} — always showed one bogus row.
- load_doc silently produced an empty document on any parse error,
so the next Save could clobber a config file with a syntax typo;
now backs it up first.
- Hyprland panel opened hyprland.conf/keybinds.conf (BOS ships
hyprland.lua) via $EDITOR with no terminal (dead click for any TUI
editor) and defaulted to foot (BOS ships kitty). Now opens
hyprland.lua and a keybinds cheat sheet via kitty -e $EDITOR.
- New breadsearch view: power (enabled/run-on-battery), compute
backend (cpu/npu/rocm), index/search settings.
- Move assets to assets/ directory (bread_white.svg, icons 256/512/1024px)
- Update Calamares branding + Plymouth theme logos
- Bake breadpaper (wallpaper manager + pywal) into /etc/skel alongside the
rest of the bread ecosystem — previously missing from the ISO build
- Bump bos-settings to 0.4.0
Pick up the directory-watch fix so bos-settings hot-reloads the shared stylesheet
on `bread-theme reload` like the rest of the desktop (its v0.2.6 build had the
broken file-watch). No code change — only the dependency + version bump.
The bread/breadpad/breadcrumbs/breadbox views wrote invented schemas
(e.g. top-level log_level, [[profile]] name/ssids) that did not match the
apps' real TOML, so they showed empty and — worse — clobbered the real
config on Save, since the old config::save serialized only the keys it
modelled.
Rework the config layer onto toml_edit: parse each file into a
DocumentMut, mutate only the specific keys a view exposes, and write it
back preserving comments and any unmodelled keys (calendar password,
saved-network passwords, model paths). Unit-tested.
Add ui/widgets.rs (switch/entry/password/dropdown/spin/float/csv rows +
view scaffold + save button) bound to the shared document, then rewrite
the four views against the real schemas with far more coverage:
- bread: [daemon], [lua], [modules], all five [adapters.*] with their
sub-options, [events], [notifications]
- breadpad: [settings], [model] + [model.ollama], [reminders], [calendar]
- breadcrumbs: [settings] (7 keys), [[networks]] editor, [profiles.*] editor
- breadbox: fixed to real [[contexts]] name/priority array editor
Goal: configure everything from the GUI rather than hand-editing TOML.