bos/bos-settings/src/theme.rs
Breadway 489d472240 bos-settings: round-2 GUI review fixes (stable column width, service UX, switch styling)
Root cause of two panels rendering full-bleed instead of the 760px column
(breadsearch, breadclip): hint()'s long unwrapped text reported an
unbounded natural width, and CONTENT_MAX_WIDTH is a floor (set_size_request),
not a cap — nothing was actually capping width. hint() and empty_state()
now bound their labels with set_max_width_chars, which stabilizes every
panel's column at a consistent width and left edge for the first time.

service_control(): added a second status line (enabled-at-boot vs
just-running), a confirm dialog on Stop for critical units (breadd — the
whole desktop's event backbone was one accidental click from stopping,
styled identically to optional helpers), and a consistent "Save only
writes the file, Restart applies it" hint on panels that have both a
service and a config file (previously only breadsearch said this, in its
own inconsistent wording).

Consistency sweep: Network's Scan button and empty-state treatment now
match the rest of the app (was full-width where every other secondary
action is auto-width; "not scanned" was a hint while "no results" was an
empty_state card — now both empty_state). breadclip gets an actual "Open
history" action instead of reading as an unfinished stub. breadbox's Save
button pulled out of a mixed row into its own row like every other panel.
Packages list rows now get the same card styling as every other row in
the app.

Panel title now shares view_scaffold's width+center treatment with the
content column, so it actually heads the column instead of sitting ~440px
to its left.

Also: switch widgets had a stray box-shadow/outline/border showing as a
faint ring around the knob, and bread-theme's switch slider color
(@on-surface) was being masked by Adwaita's default gloss background-image
— clearing it reveals the correctly-themed near-white knob against the
dark surface.
2026-07-04 10:09:59 +08:00

56 lines
3.1 KiB
Rust

//! Theming for bos-settings.
//!
//! bos-settings deliberately owns almost no styling: it loads the ecosystem's
//! shared stylesheet (the same one breadbar/breadbox/breadpad use, generated by
//! `bread-theme` from the pywal palette) and adds only the few layout rules
//! specific to this app's sidebar + content shell. This keeps it visually
//! identical to the rest of the bread desktop and live-recolouring for free.
use gtk4::CssProvider;
use std::cell::RefCell;
// App-specific layout only — everything visual (colours, buttons, entries,
// switches, sidebar/row styling, cards, scrollbars) comes from the shared sheet.
const APP_CSS: &str = "\
.view-content { padding: 24px; }\n\
.view-content > label.title { margin-bottom: 16px; }\n\
/* Sidebar row sub-labels (the underlying binary/config name under a row's \
human label) — smaller than the shared sheet's default dim-label size. */\n\
.caption { font-size: 11px; }\n\
/* bread-theme's shared sheet only overrides background-color on \
suggested/destructive buttons, not background-image — so Adwaita's \
built-in gradient (bright blue/red) paints over our flat colour \
underneath it. Belongs upstream in bread-theme; patched locally here \
until that's worth its own release. */\n\
button.suggested-action, button.destructive-action { background-image: none; }\n\
/* Same upstream gap for scale (Sound's volume sliders) — the shared sheet \
has no `scale` rules at all, so they render in Adwaita's default blue. */\n\
scale trough { background-color: alpha(@on-surface, 0.15); border-radius: 999px; min-height: 6px; background-image: none; }\n\
scale highlight { background-color: @accent; background-image: none; border-radius: 999px; }\n\
scale slider { background-color: @on-surface; border-radius: 999px; }\n\
/* Destructive actions must not follow the wallpaper palette: @red is \
pywal's color1, which can land on gold/yellow/anything depending on the \
wallpaper (it did, this session) — making Delete/Remove look like a \
primary action instead of a dangerous one. Fixed regardless of palette. */\n\
button.destructive-action { background-color: #c0392b; color: #ffffff; }\n\
button.destructive-action:hover { background-color: #d64535; }\n\
/* Adwaita's default switch slider (the knob) carries a box-shadow used for \
its 3D bevel look — bread-theme's override only sets background-color, \
so that shadow still renders as a pale ring around the knob on top of \
our flat colour. */\n\
switch slider { box-shadow: none; outline: none; border: none; background-image: none; }\n\
switch { box-shadow: none; outline: none; border: none; background-image: none; }\n\
";
thread_local! {
static APP_PROVIDER: RefCell<Option<CssProvider>> = const { RefCell::new(None) };
}
pub fn load(_display: &gtk4::gdk::Display) {
// Shared ecosystem stylesheet (loads the generated file or a rendered
// fallback, and live-reloads when the palette changes).
bread_theme::gtk::apply_shared();
// bos-settings layout, layered on top at APPLICATION priority.
APP_PROVIDER.with(|cell| bread_theme::gtk::apply_css(APP_CSS, cell));
}