diff --git a/.forgejo/workflows/mirror.yml b/.forgejo/workflows/mirror.yml deleted file mode 100644 index ac655db..0000000 --- a/.forgejo/workflows/mirror.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Mirror to GitHub - -on: - push: - branches: ['**'] - tags: ['**'] - -jobs: - mirror: - runs-on: [self-hosted, hestia] - steps: - - name: Mirror to GitHub - run: | - set -euo pipefail - git clone --mirror "https://git.breadway.dev/${GITHUB_REPOSITORY}.git" repo.git - cd repo.git - # Mirror only branches and tags (not refs/pull/*, which GitHub rejects); - # --prune deletes GitHub refs that no longer exist on Forgejo. - git push --prune \ - "https://x-access-token:${{ secrets.MIRROR_TOKEN }}@github.com/Breadway/breadbar.git" \ - '+refs/heads/*:refs/heads/*' '+refs/tags/*:refs/tags/*' diff --git a/.forgejo/workflows/package.yml b/.forgejo/workflows/package.yml deleted file mode 100644 index 2895a76..0000000 --- a/.forgejo/workflows/package.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Build and publish package - -on: - push: - tags: ['v*'] - -jobs: - package: - runs-on: [self-hosted, hestia] - container: - image: archlinux:latest - steps: - # Note: no actions/checkout — the archlinux image has no Node, which JS - # actions require. Everything runs as shell steps and clones manually. - - name: Build and publish - env: - PUBLISH_TOKEN: ${{ secrets.REGISTRY_TOKEN }} - run: | - set -euo pipefail - VERSION="${GITHUB_REF_NAME#v}" - pacman -Syu --noconfirm base-devel git rust cargo gtk4 gtk4-layer-shell libpulse iw - useradd -m builder - git config --global --add safe.directory '*' - git clone --branch "${GITHUB_REF_NAME}" --depth 1 \ - "https://git.breadway.dev/${GITHUB_REPOSITORY}.git" /home/builder/src - cd /home/builder/src - git archive --format=tar.gz --prefix="breadbar-${VERSION}/" HEAD \ - > packaging/arch/breadbar-${VERSION}.tar.gz - SHA=$(sha256sum packaging/arch/breadbar-${VERSION}.tar.gz | awk '{print $1}') - sed -i "s/^pkgver=.*/pkgver=${VERSION}/" packaging/arch/PKGBUILD - sed -i "s/^sha256sums=.*/sha256sums=('${SHA}')/" packaging/arch/PKGBUILD - chown -R builder:builder /home/builder/src - # --nocheck: packaging builds the artifact; tests belong in a CI job. - su builder -c "cd /home/builder/src/packaging/arch && makepkg -f --noconfirm --nocheck" - PKG=$(find /home/builder/src/packaging/arch -name '*.pkg.tar.zst' | head -1) - curl -fsS -X PUT \ - -H "Authorization: token ${PUBLISH_TOKEN}" \ - -H "Content-Type: application/octet-stream" \ - --data-binary "@${PKG}" \ - "https://git.breadway.dev/api/packages/Breadway/arch/os" diff --git a/Cargo.lock b/Cargo.lock index aa34dc1..dd6d212 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,30 +2,12 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "anyhow" version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - [[package]] name = "async-broadcast" version = "0.7.2" @@ -88,18 +70,6 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.13.0" @@ -108,8 +78,8 @@ checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "bread-theme" -version = "0.2.3" -source = "git+https://github.com/Breadway/bread-ecosystem?tag=v0.2.8#77417d552130281ff787e07d52541eb25e9d533b" +version = "0.1.0" +source = "git+https://github.com/Breadway/bread-ecosystem?tag=v0.1.0#6b5f4f475f66a645b08cb865e6dda8228d23679b" dependencies = [ "dirs", "gtk4", @@ -119,7 +89,7 @@ dependencies = [ [[package]] name = "breadbar" -version = "0.1.7" +version = "0.1.2" dependencies = [ "bread-theme", "futures-lite", @@ -127,7 +97,6 @@ dependencies = [ "gtk4-layer-shell", "hyprland", "relm4", - "resvg", "serde", "serde_json", "tokio", @@ -140,12 +109,6 @@ version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" -[[package]] -name = "bytemuck" -version = "1.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" - [[package]] name = "bytes" version = "1.11.1" @@ -158,7 +121,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cc8d9aa793480744cd9a0524fef1a2e197d9eaa0f739cde19d16aba530dcb95" dependencies = [ - "bitflags 2.13.0", + "bitflags", "cairo-sys-rs", "glib", "libc", @@ -209,27 +172,12 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" -[[package]] -name = "data-url" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" - [[package]] name = "derive_more" version = "2.1.1" @@ -323,15 +271,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "euclid" -version = "0.22.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" -dependencies = [ - "num-traits", -] - [[package]] name = "event-listener" version = "5.4.1" @@ -362,15 +301,6 @@ dependencies = [ "getrandom 0.3.4", ] -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - [[package]] name = "field-offset" version = "0.3.6" @@ -381,22 +311,6 @@ dependencies = [ "rustc_version", ] -[[package]] -name = "flate2" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" - [[package]] name = "flume" version = "0.12.0" @@ -677,7 +591,7 @@ version = "0.22.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c207e04e51605dcf7b2924c41591b3a10e1438eaac5bcf448fb91f325381104a" dependencies = [ - "bitflags 2.13.0", + "bitflags", "futures-channel", "futures-core", "futures-executor", @@ -806,7 +720,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4069987ff4793699511a251028cc336b438e46565b463f111250148d574752a" dependencies = [ - "bitflags 2.13.0", + "bitflags", "gdk4", "glib", "glib-sys", @@ -921,12 +835,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" -[[package]] -name = "imagesize" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" - [[package]] name = "indexmap" version = "2.14.0" @@ -963,17 +871,6 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" -[[package]] -name = "kurbo" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62" -dependencies = [ - "arrayvec", - "euclid", - "smallvec", -] - [[package]] name = "leb128fmt" version = "0.1.0" @@ -1031,16 +928,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - [[package]] name = "mio" version = "1.2.1" @@ -1052,15 +939,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.21.4" @@ -1119,12 +997,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" -[[package]] -name = "pico-args" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" - [[package]] name = "pin-project-lite" version = "0.2.17" @@ -1137,19 +1009,6 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - [[package]] name = "prettyplease" version = "0.2.37" @@ -1244,35 +1103,6 @@ dependencies = [ "syn", ] -[[package]] -name = "resvg" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a325d5e8d1cebddd070b13f44cec8071594ab67d1012797c121f27a669b7958" -dependencies = [ - "log", - "pico-args", - "rgb", - "svgtypes", - "tiny-skia", - "usvg", -] - -[[package]] -name = "rgb" -version = "0.8.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "roxmltree" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" - [[package]] name = "rustc_version" version = "0.4.1" @@ -1288,7 +1118,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.13.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -1386,27 +1216,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-adler32" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" - -[[package]] -name = "simplecss" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c" -dependencies = [ - "log", -] - -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - [[package]] name = "slab" version = "0.4.12" @@ -1438,25 +1247,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "strict-num" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" -dependencies = [ - "float-cmp", -] - -[[package]] -name = "svgtypes" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" -dependencies = [ - "kurbo", - "siphasher", -] - [[package]] name = "syn" version = "2.0.117" @@ -1520,32 +1310,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tiny-skia" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" -dependencies = [ - "arrayref", - "arrayvec", - "bytemuck", - "cfg-if", - "log", - "png", - "tiny-skia-path", -] - -[[package]] -name = "tiny-skia-path" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" -dependencies = [ - "arrayref", - "bytemuck", - "strict-num", -] - [[package]] name = "tokio" version = "1.52.3" @@ -1685,28 +1449,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "usvg" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7447e703d7223b067607655e625e0dbca80822880248937da65966194c4864e6" -dependencies = [ - "base64", - "data-url", - "flate2", - "imagesize", - "kurbo", - "log", - "pico-args", - "roxmltree", - "simplecss", - "siphasher", - "strict-num", - "svgtypes", - "tiny-skia-path", - "xmlwriter", -] - [[package]] name = "uuid" version = "1.23.2" @@ -1821,7 +1563,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.13.0", + "bitflags", "hashbrown 0.15.5", "indexmap", "semver", @@ -1981,7 +1723,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.13.0", + "bitflags", "indexmap", "log", "serde", @@ -2017,12 +1759,6 @@ version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" -[[package]] -name = "xmlwriter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" - [[package]] name = "zbus" version = "5.16.0" diff --git a/Cargo.toml b/Cargo.toml index 0950f3a..4594c93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "breadbar" -version = "0.1.7" +version = "0.1.2" edition = "2021" description = "Minimal status bar and notification daemon for Hyprland on Wayland" license = "MIT" @@ -10,7 +10,7 @@ keywords = ["wayland", "hyprland", "bar", "status-bar", "gtk4"] categories = ["gui"] [dependencies] -bread-theme = { git = "https://github.com/Breadway/bread-ecosystem", tag = "v0.2.8", features = ["gtk"] } +bread-theme = { git = "https://github.com/Breadway/bread-ecosystem", tag = "v0.1.0", features = ["gtk"] } gtk4 = { version = "0.11", features = ["v4_12"] } gtk4-layer-shell = "0.8" relm4 = { version = "0.11", features = ["macros"] } @@ -20,9 +20,6 @@ zbus = { version = "5", default-features = false, features = ["tokio"] } tokio = { version = "1", features = ["rt-multi-thread", "macros", "time", "process", "signal", "sync"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -# Pure-Rust SVG rasteriser (default features off → no text/font deps; the icons -# are vector-only). Needed because librsvg dropped its gdk-pixbuf SVG loader. -resvg = { version = "0.44", default-features = false } [profile.release] lto = "thin" diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD deleted file mode 100644 index c021698..0000000 --- a/packaging/arch/PKGBUILD +++ /dev/null @@ -1,36 +0,0 @@ -# Maintainer: Breadway - -pkgname=breadbar -pkgver=0.1.0 -pkgrel=1 -pkgdesc="Minimal status bar and notification daemon for Hyprland" -arch=('x86_64') -url="https://github.com/Breadway/breadbar" -license=('MIT') -# Some Rust deps (ring/mlua) build vendored C/asm into static archives; makepkg's -# default -flto=auto emits GCC LTO bitcode the Rust (lld) link cannot read, -# causing undefined-symbol errors. Disable LTO. -options=(!lto !debug) -depends=('gtk4' 'gtk4-layer-shell' 'libpulse' 'iw') -optdepends=( - 'hyprland: workspace and window data integration' -) -makedepends=('rust' 'cargo') -source=("${pkgname}-${pkgver}.tar.gz") -sha256sums=('SKIP') - -build() { - cd "${srcdir}/${pkgname}-${pkgver}" - cargo build --release --locked -} - -check() { - cd "${srcdir}/${pkgname}-${pkgver}" - cargo test --release --locked -} - -package() { - cd "${srcdir}/${pkgname}-${pkgver}" - install -Dm755 target/release/breadbar "${pkgdir}/usr/bin/breadbar" - install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" -} diff --git a/src/bar/stats.rs b/src/bar/stats.rs index 2d4908b..8a6b5d1 100644 --- a/src/bar/stats.rs +++ b/src/bar/stats.rs @@ -15,25 +15,22 @@ static BT_CONN: AsyncOnce = AsyncOnce::const_new(); static BT_CACHE: LazyLock> = LazyLock::new(|| Mutex::new(BT_OFF)); static BT_TICK: AtomicU8 = AtomicU8::new(0); -// Embedded SVG contents (not paths). These &str constants double as stable -// HashMap keys via their .as_ptr(); include_str! keeps each one a single -// 'static literal, so pointer identity still holds. -pub const WIFI_STRONG: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Strong.svg")); -pub const WIFI_MEDIUM: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Medium.svg")); -pub const WIFI_WEAK: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Weak.svg")); -pub const WIFI_OFF: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Disconnect.svg")); +pub const WIFI_STRONG: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Strong.svg"); +pub const WIFI_MEDIUM: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Medium.svg"); +pub const WIFI_WEAK: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Weak.svg"); +pub const WIFI_OFF: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Disconnect.svg"); -pub const BAT_HIGH: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Battery 3 Bars.svg")); -pub const BAT_MID: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Battery 2 Bars.svg")); -pub const BAT_LOW: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Battery 1 Bar.svg")); -pub const AC_POWER: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/AC Power.svg")); +pub const BAT_HIGH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Battery 3 Bars.svg"); +pub const BAT_MID: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Battery 2 Bars.svg"); +pub const BAT_LOW: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Battery 1 Bar.svg"); +pub const AC_POWER: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/AC Power.svg"); -pub const BT_OFF: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Bluetooth Off.svg")); -pub const BT_ON: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Bluetooth.svg")); -pub const BT_CONNECTED: &str = include_str!(concat!( +pub const BT_OFF: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Bluetooth Off.svg"); +pub const BT_ON: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Bluetooth.svg"); +pub const BT_CONNECTED: &str = concat!( env!("CARGO_MANIFEST_DIR"), "/assets/Bluetooth Connected.svg" -)); +); #[derive(Debug)] pub struct Stats { diff --git a/src/main.rs b/src/main.rs index 877490c..f1d77b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,6 @@ -// Embed asset SVGs into the binary at compile time. Previously these were -// referenced by their build-time filesystem path (CARGO_MANIFEST_DIR), which -// does not exist on an installed system — so the packaged binary loaded empty -// bytes and panicked. include_str! bakes the contents in instead. macro_rules! asset { ($n:literal) => { - include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/", $n)) + concat!(env!("CARGO_MANIFEST_DIR"), "/assets/", $n) }; } @@ -278,39 +274,24 @@ impl App { } } -fn stat_pair(icon_svg: &str, label: >k4::Label) -> gtk4::Box { +fn stat_pair(icon_path: &str, label: >k4::Label) -> gtk4::Box { let pair = gtk4::Box::new(gtk4::Orientation::Horizontal, 0); pair.add_css_class("stat-pair"); - let img = gtk4::Image::from_paintable(Some(&svg_texture(icon_svg))); + let img = gtk4::Image::from_paintable(Some(&svg_texture(icon_path))); img.add_css_class("stat-icon"); pair.append(&img); pair.append(label); pair } -// Rasterise an (embedded) SVG to a texture. Done in pure Rust with resvg -// because librsvg dropped its gdk-pixbuf SVG loader, so gdk::Texture::from_bytes -// can no longer decode SVG on a stock system. -fn svg_texture(svg_src: &str) -> gtk4::gdk::Texture { - use resvg::{tiny_skia, usvg}; +fn svg_texture(path: &str) -> gtk4::gdk::Texture { let fg = theme::fg_color(); - let svg = svg_src + let svg = std::fs::read_to_string(path) + .unwrap_or_default() .replace("currentColor", &fg) .replace(r#"width="24" height="24""#, r#"width="16" height="16""#); - let tree = usvg::Tree::from_str(&svg, &usvg::Options::default()).expect("parse svg"); - let size = tree.size().to_int_size(); - let (w, h) = (size.width(), size.height()); - let mut pixmap = tiny_skia::Pixmap::new(w, h).expect("alloc pixmap"); - resvg::render(&tree, tiny_skia::Transform::identity(), &mut pixmap.as_mut()); - let bytes = gtk4::glib::Bytes::from_owned(pixmap.take()); - gtk4::gdk::MemoryTexture::new( - w as i32, - h as i32, - gtk4::gdk::MemoryFormat::R8g8b8a8Premultiplied, - &bytes, - (w * 4) as usize, - ) - .upcast() + let bytes = gtk4::glib::Bytes::from_owned(svg.into_bytes()); + gtk4::gdk::Texture::from_bytes(&bytes).expect("svg load") } fn stat_label() -> gtk4::Label { diff --git a/src/theme.rs b/src/theme.rs index e02ed01..62ce751 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -1,68 +1,57 @@ -use bread_theme::{gtk as bgtk, hex_to_rgba, ink_on, load_palette}; +use bread_theme::{gtk as bgtk, hex_to_rgba, load_palette}; use gtk4::CssProvider; use std::cell::RefCell; thread_local! { + static PROVIDER: RefCell> = const { RefCell::new(None) }; static USER_PROVIDER: RefCell> = const { RefCell::new(None) }; } fn load_css() -> String { let p = load_palette(); - // breadbar-specific rules only — fonts, base colours, and generic widgets - // 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!( - "window.breadbar {{ background-color: {bg_rgba}; color: {on_bg}; border-radius: 0; }}\ - .workspace-btn {{ background: transparent; opacity: 0.45;\ - border-radius: 0; border: none; outline: none; box-shadow: none;\ + "* {{ font-family: 'Varela Round', sans-serif; font-size: 14px; }}\ + window.breadbar {{ background-color: {bg_rgba}; border-radius: 0; }}\ + label {{ color: {fg}; }}\ + .workspace-btn {{ background: transparent; color: {fg}; opacity: 0.45;\ + border-radius: 0 0 8px 8px; border: none; outline: none; box-shadow: none;\ min-width: 24px; padding: 4px 8px; }}\ .workspace-btn:hover {{ opacity: 0.8; }}\ - .workspace-btn.active {{ background: {accent}; color: {on_accent}; opacity: 1; }}\ + .workspace-btn.active {{ background: {accent}; opacity: 1; }}\ .stats-box {{ margin-right: 8px; }}\ .stat-pair {{ margin-right: 12px; }}\ .stat-icon {{ margin-right: 5px; }}\ .bt-icon {{ margin-right: 12px; }}\ - window.breadbar-notification {{ background-color: alpha({bg_plain}, 0.95); color: {on_bg}; }}\ - .notification-card {{ background: {surface}; color: {on_surface}; border-radius: 8px;\ + window.breadbar-notification {{ background-color: alpha({bg_plain}, 0.95); }}\ + .notification-card {{ background: {surface}; border-radius: 8px;\ padding: 12px; margin-bottom: 8px; }}\ - .notification-summary {{ font-weight: bold; }}\ - .notification-app {{ opacity: 0.6; }}\ - window.breadbar-osd {{ background-color: alpha({bg_plain}, 0.95); color: {on_bg}; border-radius: 8px; }}\ - .osd-kind {{ opacity: 0.75; font-size: 12px; }}\ - .osd-pct {{ font-weight: bold; font-size: 12px; }}\ + .notification-summary {{ font-weight: bold; color: {fg}; }}\ + .notification-app {{ color: {fg}; opacity: 0.6; }}\ + .notification-body {{ color: {fg}; }}\ + window.breadbar-osd {{ background-color: alpha({bg_plain}, 0.95); border-radius: 8px; }}\ + .osd-kind {{ color: {fg}; opacity: 0.75; font-size: 12px; }}\ + .osd-pct {{ color: {fg}; font-weight: bold; font-size: 12px; }}\ 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 progress {{ background-image: none; background-color: {accent}; border-radius: 4px; min-height: 8px; }}", - bg_plain = p.background, - bg_rgba = hex_to_rgba(&p.background, 0.92), - surface = p.color0, - 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), + bg_plain = p.background, + bg_rgba = hex_to_rgba(&p.background, 0.92), + surface = p.color0, + fg = p.foreground, + accent = p.color4, + trough = hex_to_rgba(&p.color4, 0.25), ) } -/// 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. +/// Returns the current foreground colour (used for icon tinting in the stats bar). pub fn fg_color() -> String { - ink_on(&load_palette().background).to_string() + load_palette().foreground } /// Apply (or reload) the theme CSS. Safe to call from `glib::MainContext::invoke`. pub fn apply() { - // Shared ecosystem base (fonts, palette, generic widgets) — applied first - // (and self-reloading) so breadbar's own rules below layer on top. - bgtk::apply_shared(); - - // breadbar's own rules, hot-reloaded on `bread-theme reload`: the closure - // re-reads the pywal palette each time so the bar recolours without restart. - bgtk::apply_app_css(load_css); + let css = load_css(); + PROVIDER.with(|cell| bgtk::apply_css(&css, cell)); let home = std::env::var("HOME").unwrap_or_default(); let user_path = std::path::PathBuf::from(format!("{home}/.config/breadbar/style.css"));