bread-theme 0.2.7: luminance-picked ink + live reload
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.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0c8c5c00e4
commit
ea87083c06
3 changed files with 167 additions and 42 deletions
|
|
@ -7,6 +7,10 @@ use std::path::Path;
|
|||
thread_local! {
|
||||
static SHARED_PROVIDER: RefCell<Option<CssProvider>> = const { RefCell::new(None) };
|
||||
static SHARED_MONITOR: RefCell<Option<gio::FileMonitor>> = const { RefCell::new(None) };
|
||||
static APP_PROVIDER: RefCell<Option<CssProvider>> = const { RefCell::new(None) };
|
||||
static APP_MONITOR: RefCell<Option<gio::FileMonitor>> = const { RefCell::new(None) };
|
||||
#[allow(clippy::type_complexity)]
|
||||
static APP_BUILDER: RefCell<Option<Box<dyn Fn() -> String>>> = const { RefCell::new(None) };
|
||||
}
|
||||
|
||||
fn reload_shared() {
|
||||
|
|
@ -15,6 +19,42 @@ fn reload_shared() {
|
|||
SHARED_PROVIDER.with(|cell| apply_css(&css, cell));
|
||||
}
|
||||
|
||||
fn reload_app() {
|
||||
let css = APP_BUILDER.with(|b| b.borrow().as_ref().map(|f| f()));
|
||||
if let Some(css) = css {
|
||||
APP_PROVIDER.with(|cell| apply_css(&css, cell));
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply an app's *own* stylesheet and keep it live across palette changes.
|
||||
///
|
||||
/// `build` is called now to produce the app-specific CSS, and again every time
|
||||
/// the shared theme file is rewritten — i.e. whenever `bread-theme reload` (or
|
||||
/// `generate`) runs after pywal changes. The app recolours in place, no restart.
|
||||
///
|
||||
/// This is the counterpart to [`apply_shared`]: that hot-reloads the *shared*
|
||||
/// component sheet; this hot-reloads the app's *own* rules (which are built from
|
||||
/// the palette, so they'd otherwise be frozen at startup). Apps that build their
|
||||
/// CSS from [`crate::stylesheet`] themselves can use this alone; apps that layer
|
||||
/// on top of [`apply_shared`] call both.
|
||||
///
|
||||
/// Call once at startup. The closure should read the current palette
|
||||
/// ([`crate::load_palette`]) each time so it picks up the new colours.
|
||||
pub fn apply_app_css<F: Fn() -> String + 'static>(build: F) {
|
||||
APP_BUILDER.with(|b| *b.borrow_mut() = Some(Box::new(build)));
|
||||
reload_app();
|
||||
APP_MONITOR.with(|cell| {
|
||||
if cell.borrow().is_some() {
|
||||
return;
|
||||
}
|
||||
let file = gio::File::for_path(crate::shared_css_path());
|
||||
if let Ok(monitor) = file.monitor_file(gio::FileMonitorFlags::NONE, gio::Cancellable::NONE) {
|
||||
monitor.connect_changed(|_, _, _, _| reload_app());
|
||||
*cell.borrow_mut() = Some(monitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Load the ecosystem's shared stylesheet (the file written by
|
||||
/// `bread-theme generate`, or a freshly rendered fallback if absent) at
|
||||
/// APPLICATION priority, and watch the file so the whole UI recolours live when
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue