From 29a0070748ebdf059eb2de52400e167fda7eae14 Mon Sep 17 00:00:00 2001 From: Breadway Date: Tue, 16 Jun 2026 16:47:52 +0800 Subject: [PATCH 1/2] bos-settings: use the shared bread-theme stylesheet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the hardcoded Nord palette (which ignored pywal and the rest of the ecosystem entirely) with bread_theme::gtk::apply_shared() — bos-settings now loads the same generated stylesheet as breadbar/breadbox/breadpad and keeps only its own layout rules (.view-content padding). It recolours live with the desktop. Bump gtk4 0.9 -> 0.11 / glib -> 0.22 to match the ecosystem. Note: bread-theme dep pins tag v0.2.6 (cut at release); Cargo.lock to be regenerated then. Co-Authored-By: Claude Opus 4.8 --- bos-settings/Cargo.toml | 7 ++- bos-settings/src/theme.rs | 105 +++++++++----------------------------- 2 files changed, 29 insertions(+), 83 deletions(-) diff --git a/bos-settings/Cargo.toml b/bos-settings/Cargo.toml index 10e3129..b7b74f3 100644 --- a/bos-settings/Cargo.toml +++ b/bos-settings/Cargo.toml @@ -4,8 +4,11 @@ version = "0.2.0" edition = "2021" [dependencies] -gtk4 = { version = "0.9", features = ["v4_12"] } -glib = "0.20" +gtk4 = { version = "0.11", features = ["v4_12"] } +glib = "0.22" +# Shared ecosystem theming — bos-settings loads the same generated stylesheet as +# breadbar/breadbox/breadpad so the whole desktop looks consistent. +bread-theme = { git = "https://github.com/Breadway/bread-ecosystem", tag = "v0.2.6", features = ["gtk"] } serde = { version = "1", features = ["derive"] } serde_json = "1" toml = "0.8" diff --git a/bos-settings/src/theme.rs b/bos-settings/src/theme.rs index 6be4f51..4bd254e 100644 --- a/bos-settings/src/theme.rs +++ b/bos-settings/src/theme.rs @@ -1,87 +1,30 @@ +//! 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; -const CSS: &str = r#" -window { - background-color: #2e3440; - color: #eceff4; +// 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\ +"; + +thread_local! { + static APP_PROVIDER: RefCell> = const { RefCell::new(None) }; } -.sidebar { - background-color: #3b4252; - border-right: 1px solid #434c5e; -} +pub fn load(_display: >k4::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(); -.sidebar row { - padding: 8px 12px; - color: #d8dee9; -} - -.sidebar row:selected { - background-color: #5e81ac; - color: #eceff4; -} - -.sidebar .section-header { - padding: 12px 12px 4px 12px; - font-size: 0.75em; - font-weight: bold; - color: #616e88; - text-transform: uppercase; - letter-spacing: 1px; -} - -.view-content { - padding: 24px; -} - -.view-content label.title { - font-size: 1.4em; - font-weight: bold; - color: #eceff4; - margin-bottom: 16px; -} - -button { - background-color: #5e81ac; - color: #eceff4; - border: none; - border-radius: 4px; - padding: 6px 16px; -} - -button:hover { - background-color: #81a1c1; -} - -button.destructive-action { - background-color: #bf616a; -} - -button.destructive-action:hover { - background-color: #d08770; -} - -entry { - background-color: #434c5e; - color: #eceff4; - border: 1px solid #4c566a; - border-radius: 4px; -} - -textview { - background-color: #272c36; - color: #a3be8c; - font-family: monospace; - padding: 8px; -} -"#; - -pub fn load(display: >k4::gdk::Display) { - let provider = CssProvider::new(); - provider.load_from_string(CSS); - gtk4::style_context_add_provider_for_display( - display, - &provider, - gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION, - ); + // bos-settings layout, layered on top at APPLICATION priority. + APP_PROVIDER.with(|cell| bread_theme::gtk::apply_css(APP_CSS, cell)); } From 0aeb2c4b6b1b9e8812c56aafa1586a11b66d1833 Mon Sep 17 00:00:00 2001 From: Breadway Date: Tue, 16 Jun 2026 16:59:03 +0800 Subject: [PATCH 2/2] BOS: bake the bread-theme CLI and generate the shared stylesheet at login - Add bread-theme to the binaries baked into /etc/skel from bakery state. - Run `bread-theme generate` first in the Hyprland autostart so the shared GUI stylesheet ($XDG_RUNTIME_DIR/bread/theme.css) exists before breadbar / breadbox / bos-settings paint (they also live-reload it on change). Co-Authored-By: Claude Opus 4.8 --- build-local.sh | 2 +- iso/airootfs/etc/skel/.config/hypr/hyprland.lua | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/build-local.sh b/build-local.sh index 3015be0..23f2fea 100755 --- a/build-local.sh +++ b/build-local.sh @@ -41,7 +41,7 @@ grep airootfs_image_tool_options "$STAGE/profiledef.sh" # created from skel (the live user and the installed user) then gets the same # versions `bakery list` reports here, fully offline. Copied at build time so the # binaries never bloat the git repo and always track the current bakery state. -BREAD_BINS=(bakery bread breadd breadman breadbar breadbox breadbox-sync breadcrumbs breadpad) +BREAD_BINS=(bakery bread breadd breadman breadbar breadbox breadbox-sync breadcrumbs breadpad bread-theme) LAPTOP_HOME="${LAPTOP_HOME:-$(getent passwd "${SUDO_USER:-$USER}" | cut -d: -f6)}" BAKERY_BIN="$LAPTOP_HOME/.local/bin" BAKERY_STATE="$LAPTOP_HOME/.local/state/bakery" diff --git a/iso/airootfs/etc/skel/.config/hypr/hyprland.lua b/iso/airootfs/etc/skel/.config/hypr/hyprland.lua index 8485e0c..c7ce981 100644 --- a/iso/airootfs/etc/skel/.config/hypr/hyprland.lua +++ b/iso/airootfs/etc/skel/.config/hypr/hyprland.lua @@ -188,6 +188,9 @@ hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), -- --------------------------------------------------------------------------- hl.on("hyprland.start", function() local startup = { + -- Generate the shared bread GUI stylesheet first, so breadbar/breadbox/ + -- bos-settings load it on start (they also live-reload if it changes). + "bread-theme generate", -- Global dark theme: GTK4/libadwaita + GTK3 theme + icon + cursor. "gsettings set org.gnome.desktop.interface color-scheme prefer-dark", "gsettings set org.gnome.desktop.interface gtk-theme Adwaita-dark",