Drive bar/window geometry and CSS tokens from the shell theme manifest

breadbar no longer hardcodes BAR_HEIGHT/BAR_MARGIN_TOP/BAR_MARGIN_SIDES/
CHIP_HEIGHT/ICON_PX or the root window's layer-shell setup: it loads
bread_theme:🐚:ShellTheme once (theme::shell_theme(), cached in a
thread-local) and reads bar.window (anchors, margin, exclusive zone,
keyboard mode - now set explicitly instead of relying on the library
default) plus tokens.{icon_px,chip_height} from it everywhere those used
to be literals.

The four satellite surfaces (breadbar-osd, breadbar-notif, breadbar-panel,
breadbar-dismiss) now get their anchor/margin/width/layer from the
manifest's [surfaces.*] table via a small new surface::apply() helper,
narrowly scoped to the three anchor shapes those surfaces actually use.
The pre-existing 8px gap between the panel's top margin and the dismiss
scrim's is preserved exactly (and now commented) rather than "fixed".

theme.rs's load_css() keeps its ~250 lines of hand-written breadbar CSS
(notifications, wifi popover, control panel, media widget) but now reads
its five radius/pad locals and the two easing curves (spring vs
spring_settle - hover/settle transitions were previously miscategorized
as the overshoot curve in the constant audit; the actual code already
used the settle curve there, confirmed against src) from theme tokens
instead of hardcoding them.

Also wires bread_theme:🐚:watch() so editing the active theme's
theme.toml/extra.css hot-reloads CSS tokens without a restart, same as
a pywal palette change already does. Window-spec values still need a
restart per the plan (read once at window-construction time).

Verified pixel-identical: captured all 10 breadbar --screenshot views
(bar, control-panel, connectivity-wifi/bluetooth, media-popover,
notification/-critical, osd-volume/-brightness, wifi-add-dialog) via
bread-capture's isolated headless-Sway harness against both the
pre-change and post-change binaries; every view diffs byte-identical
at the decoded-pixel level.
This commit is contained in:
Breadway 2026-08-23 15:58:25 +08:00
parent 297207a7aa
commit bbb1a6c8d2
11 changed files with 278 additions and 99 deletions

View file

@ -5,7 +5,7 @@ use std::sync::{Arc, Mutex};
use std::time::{Duration, SystemTime};
use gtk4::prelude::*;
use gtk4_layer_shell::{Edge, KeyboardMode, Layer, LayerShell};
use gtk4_layer_shell::{KeyboardMode, LayerShell};
use serde::{Deserialize, Serialize};
use super::Urgency;
@ -176,11 +176,11 @@ pub fn build_window(store: Store) -> Ui {
window.add_css_class("breadbar-history");
window.init_layer_shell();
window.set_namespace(Some("breadbar-notif"));
window.set_layer(Layer::Overlay);
window.set_anchor(Edge::Top, true);
window.set_anchor(Edge::Right, true);
window.set_margin(Edge::Top, crate::BAR_MARGIN_TOP + crate::BAR_HEIGHT + 8);
window.set_margin(Edge::Right, crate::BAR_MARGIN_SIDES);
crate::surface::apply(&window, "breadbar-notif");
// Overrides `[surfaces."breadbar-notif"].width` (320px, the live-toast
// popup's width — see `surface::apply`'s doc comment): the history
// window genuinely wants a different width on the same namespace, and
// that isn't something the manifest schema models today.
window.set_default_width(360);
window.set_keyboard_mode(KeyboardMode::OnDemand);
crate::theme::bind_auto(&window);