Fix illegible text on light pywal palettes + hot-reload
All checks were successful
Mirror to GitHub / mirror (push) Successful in 31s
All checks were successful
Mirror to GitHub / mirror (push) Successful in 31s
Use bread-theme 0.2.7's luminance-picked ink (@on-*) for text on coloured backgrounds: the active workspace pill and notification cards previously kept the pywal foreground, which vanished when those slots came out light. Drop the blanket label colour rule (it overrode the per-surface ink on child labels). Switch to bread_theme::gtk::apply_app_css so the bar recolours live on `bread-theme reload` instead of only at startup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
2b6ad92082
commit
d2ee6e325f
3 changed files with 33 additions and 27 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -109,7 +109,7 @@ checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bread-theme"
|
name = "bread-theme"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "git+https://github.com/Breadway/bread-ecosystem?tag=v0.2.6#0c8c5c00e435fedff4f81e36d603424c153519a9"
|
source = "git+https://github.com/Breadway/bread-ecosystem?tag=v0.2.7#ea87083c0615fc9141b0ae4c99f833748a0189d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs",
|
"dirs",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ keywords = ["wayland", "hyprland", "bar", "status-bar", "gtk4"]
|
||||||
categories = ["gui"]
|
categories = ["gui"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bread-theme = { git = "https://github.com/Breadway/bread-ecosystem", tag = "v0.2.6", features = ["gtk"] }
|
bread-theme = { git = "https://github.com/Breadway/bread-ecosystem", tag = "v0.2.7", features = ["gtk"] }
|
||||||
gtk4 = { version = "0.11", features = ["v4_12"] }
|
gtk4 = { version = "0.11", features = ["v4_12"] }
|
||||||
gtk4-layer-shell = "0.8"
|
gtk4-layer-shell = "0.8"
|
||||||
relm4 = { version = "0.11", features = ["macros"] }
|
relm4 = { version = "0.11", features = ["macros"] }
|
||||||
|
|
|
||||||
46
src/theme.rs
46
src/theme.rs
|
|
@ -1,9 +1,8 @@
|
||||||
use bread_theme::{gtk as bgtk, hex_to_rgba, load_palette};
|
use bread_theme::{gtk as bgtk, hex_to_rgba, ink_on, load_palette};
|
||||||
use gtk4::CssProvider;
|
use gtk4::CssProvider;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static PROVIDER: RefCell<Option<CssProvider>> = const { RefCell::new(None) };
|
|
||||||
static USER_PROVIDER: RefCell<Option<CssProvider>> = const { RefCell::new(None) };
|
static USER_PROVIDER: RefCell<Option<CssProvider>> = const { RefCell::new(None) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -11,52 +10,59 @@ fn load_css() -> String {
|
||||||
let p = load_palette();
|
let p = load_palette();
|
||||||
// breadbar-specific rules only — fonts, base colours, and generic widgets
|
// breadbar-specific rules only — fonts, base colours, and generic widgets
|
||||||
// come from the shared ecosystem stylesheet (applied first in `apply()`).
|
// come from the shared ecosystem stylesheet (applied first in `apply()`).
|
||||||
|
// Colour is set on each surface (bar, active workspace pill, notification
|
||||||
|
// card) and child labels inherit it, so text stays legible whatever lightness
|
||||||
|
// pywal hands a given slot. `on_*` are luminance-picked ink (black/white) for
|
||||||
|
// that background — the pywal hues themselves are untouched.
|
||||||
format!(
|
format!(
|
||||||
"window.breadbar {{ background-color: {bg_rgba}; border-radius: 0; }}\
|
"window.breadbar {{ background-color: {bg_rgba}; color: {on_bg}; border-radius: 0; }}\
|
||||||
label {{ color: {fg}; }}\
|
.workspace-btn {{ background: transparent; opacity: 0.45;\
|
||||||
.workspace-btn {{ background: transparent; color: {fg}; opacity: 0.45;\
|
|
||||||
border-radius: 0; border: none; outline: none; box-shadow: none;\
|
border-radius: 0; border: none; outline: none; box-shadow: none;\
|
||||||
min-width: 24px; padding: 4px 8px; }}\
|
min-width: 24px; padding: 4px 8px; }}\
|
||||||
.workspace-btn:hover {{ opacity: 0.8; }}\
|
.workspace-btn:hover {{ opacity: 0.8; }}\
|
||||||
.workspace-btn.active {{ background: {accent}; opacity: 1; }}\
|
.workspace-btn.active {{ background: {accent}; color: {on_accent}; opacity: 1; }}\
|
||||||
.stats-box {{ margin-right: 8px; }}\
|
.stats-box {{ margin-right: 8px; }}\
|
||||||
.stat-pair {{ margin-right: 12px; }}\
|
.stat-pair {{ margin-right: 12px; }}\
|
||||||
.stat-icon {{ margin-right: 5px; }}\
|
.stat-icon {{ margin-right: 5px; }}\
|
||||||
.bt-icon {{ margin-right: 12px; }}\
|
.bt-icon {{ margin-right: 12px; }}\
|
||||||
window.breadbar-notification {{ background-color: alpha({bg_plain}, 0.95); }}\
|
window.breadbar-notification {{ background-color: alpha({bg_plain}, 0.95); color: {on_bg}; }}\
|
||||||
.notification-card {{ background: {surface}; border-radius: 8px;\
|
.notification-card {{ background: {surface}; color: {on_surface}; border-radius: 8px;\
|
||||||
padding: 12px; margin-bottom: 8px; }}\
|
padding: 12px; margin-bottom: 8px; }}\
|
||||||
.notification-summary {{ font-weight: bold; color: {fg}; }}\
|
.notification-summary {{ font-weight: bold; }}\
|
||||||
.notification-app {{ color: {fg}; opacity: 0.6; }}\
|
.notification-app {{ opacity: 0.6; }}\
|
||||||
.notification-body {{ color: {fg}; }}\
|
window.breadbar-osd {{ background-color: alpha({bg_plain}, 0.95); color: {on_bg}; border-radius: 8px; }}\
|
||||||
window.breadbar-osd {{ background-color: alpha({bg_plain}, 0.95); border-radius: 8px; }}\
|
.osd-kind {{ opacity: 0.75; font-size: 12px; }}\
|
||||||
.osd-kind {{ color: {fg}; opacity: 0.75; font-size: 12px; }}\
|
.osd-pct {{ font-weight: bold; font-size: 12px; }}\
|
||||||
.osd-pct {{ color: {fg}; font-weight: bold; font-size: 12px; }}\
|
|
||||||
progressbar.osd-bar {{ min-height: 8px; }}\
|
progressbar.osd-bar {{ min-height: 8px; }}\
|
||||||
progressbar.osd-bar trough {{ background-image: none; background-color: {trough}; border-radius: 4px; min-height: 8px; }}\
|
progressbar.osd-bar trough {{ background-image: none; background-color: {trough}; border-radius: 4px; min-height: 8px; }}\
|
||||||
progressbar.osd-bar trough progress {{ background-image: none; background-color: {accent}; border-radius: 4px; min-height: 8px; }}",
|
progressbar.osd-bar trough progress {{ background-image: none; background-color: {accent}; border-radius: 4px; min-height: 8px; }}",
|
||||||
bg_plain = p.background,
|
bg_plain = p.background,
|
||||||
bg_rgba = hex_to_rgba(&p.background, 0.92),
|
bg_rgba = hex_to_rgba(&p.background, 0.92),
|
||||||
surface = p.color0,
|
surface = p.color0,
|
||||||
fg = p.foreground,
|
|
||||||
accent = p.color4,
|
accent = p.color4,
|
||||||
|
on_bg = ink_on(&p.background),
|
||||||
|
on_surface = ink_on(&p.color0),
|
||||||
|
on_accent = ink_on(&p.color4),
|
||||||
trough = hex_to_rgba(&p.color4, 0.25),
|
trough = hex_to_rgba(&p.color4, 0.25),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current foreground colour (used for icon tinting in the stats bar).
|
/// Returns the ink colour for icon tinting in the stats bar — the same
|
||||||
|
/// luminance-picked colour the bar's text uses, so icons stay legible on the bar
|
||||||
|
/// whatever lightness pywal gives the background.
|
||||||
pub fn fg_color() -> String {
|
pub fn fg_color() -> String {
|
||||||
load_palette().foreground
|
ink_on(&load_palette().background).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply (or reload) the theme CSS. Safe to call from `glib::MainContext::invoke`.
|
/// Apply (or reload) the theme CSS. Safe to call from `glib::MainContext::invoke`.
|
||||||
pub fn apply() {
|
pub fn apply() {
|
||||||
// Shared ecosystem base (fonts, palette, generic widgets) — applied first
|
// Shared ecosystem base (fonts, palette, generic widgets) — applied first
|
||||||
// so breadbar's own rules below layer on top.
|
// (and self-reloading) so breadbar's own rules below layer on top.
|
||||||
bgtk::apply_shared();
|
bgtk::apply_shared();
|
||||||
|
|
||||||
let css = load_css();
|
// breadbar's own rules, hot-reloaded on `bread-theme reload`: the closure
|
||||||
PROVIDER.with(|cell| bgtk::apply_css(&css, cell));
|
// re-reads the pywal palette each time so the bar recolours without restart.
|
||||||
|
bgtk::apply_app_css(load_css);
|
||||||
|
|
||||||
let home = std::env::var("HOME").unwrap_or_default();
|
let home = std::env::var("HOME").unwrap_or_default();
|
||||||
let user_path = std::path::PathBuf::from(format!("{home}/.config/breadbar/style.css"));
|
let user_path = std::path::PathBuf::from(format!("{home}/.config/breadbar/style.css"));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue