Prepare repo for public GitHub release

Add README, MIT LICENSE, expanded .gitignore, and updated SVG icon set
to make the repository presentable for open-source publication.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Breadway 2026-05-19 12:30:12 +08:00
parent e233750b24
commit 9ed275b6c5
11 changed files with 181 additions and 2 deletions

37
.gitignore vendored
View file

@ -1,2 +1,37 @@
/target # Build artifacts
/target/
# Editor files
.vscode/
.idea/
*.swp
*.swo
*~
# OS artifacts
.DS_Store
Thumbs.db
desktop.ini
# Environment / secrets
.env
.env.*
*.env
*.pem
*.key
*.p12
secrets/
# Log files
*.log
logs/
# Runtime files
*.sock
*.pid
# Claude Code session data
.claude/
# Internal design documents (not for distribution)
aster-brief.md aster-brief.md

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Riley Horsham
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

116
README.md Normal file
View file

@ -0,0 +1,116 @@
# breadbar
Minimal status bar and notification daemon for [Hyprland](https://hyprland.org/) on Wayland.
A single Rust binary that provides a full-width top bar and a standards-compliant D-Bus notification daemon, with no system tray, no launcher, and no wallpaper logic.
## Features
**Status bar** (anchored to the top of every monitor via `gtk4-layer-shell`):
- Left: live workspace buttons sourced from Hyprland IPC, active workspace highlighted
- Centre: clock (`HH:MM`, updates at the top of each minute)
- Right: CPU%, RAM, power draw (W), battery level + AC indicator, Bluetooth state, WiFi SSID with signal strength
**Notification daemon**:
- Implements `org.freedesktop.Notifications` (D-Bus) — works with any standard notification sender (`notify-send`, etc.)
- Popups appear top-right, stack vertically, auto-dismiss after the sender-specified timeout (default 5 s)
- Supports `CloseNotification`
**Theming**:
- Reads `~/.cache/wal/colors.json` (pywal) on startup for a palette that matches your wallpaper
- Falls back to a Catppuccin Mocha palette if pywal is not present
- User CSS override: `~/.config/breadbar/style.css`
- Send `SIGHUP` to reload the theme at runtime (integrates with wallpaper-change hooks)
## Dependencies
Runtime:
- GTK4 (≥ 4.12)
- `gtk4-layer-shell`
- `iw` — for WiFi SSID/signal (`iw dev <iface> link`)
- A running Hyprland compositor
- D-Bus session bus
Bluetooth status is read from `/sys/class/rfkill` and BlueZ D-Bus; it degrades gracefully if unavailable.
## Building
```sh
cargo build --release
```
The binary is at `target/release/breadbar`.
Requirements: Rust 1.77+ (uses `LazyLock`), a GTK4 development environment (`libgtk-4-dev` / `gtk4` package).
On Arch Linux:
```sh
sudo pacman -S gtk4 gtk4-layer-shell iw
cargo build --release
```
## Running
```sh
./target/release/breadbar
```
Typically launched from your Hyprland config:
```
exec-once = /path/to/breadbar
```
breadbar claims `org.freedesktop.Notifications` on the session D-Bus on startup. If another notification daemon is already running, startup will fail — stop the other daemon first.
## Theming
### pywal integration
breadbar reads `~/.cache/wal/colors.json` automatically. To reload after a wallpaper change:
```sh
pkill -HUP breadbar
```
Or hook it into your wallpaper script:
```sh
wal -i /path/to/wallpaper.jpg
pkill -HUP breadbar
```
### Custom CSS
Drop a `~/.config/breadbar/style.css` file and send `SIGHUP` to reload. This CSS is applied at a higher priority than the pywal palette so you can override anything.
Example — change the font size:
```css
* {
font-size: 13px;
}
```
## Architecture
| Module | Responsibility |
|---|---|
| `src/main.rs` | GTK4 app entry point, widget tree, `relm4` component |
| `src/bar/workspaces.rs` | Hyprland IPC event stream, workspace buttons |
| `src/bar/clock.rs` | Minute-tick clock |
| `src/bar/stats.rs` | Polling loop: CPU, RAM, power, battery, Bluetooth, WiFi |
| `src/notifications/mod.rs` | `org.freedesktop.Notifications` zbus service |
| `src/notifications/popup.rs` | Layer-shell popup window and card stack |
| `src/theme.rs` | pywal reader, GTK CSS provider injection |
Stats are polled every 2 seconds. Bluetooth and WiFi are sampled every 16 seconds and cached in between to avoid hammering D-Bus and `iw`.
## License
MIT

1
assets/AC Power.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plug-zap-icon lucide-plug-zap"><path d="M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z"/><path d="m2 22 3-3"/><path d="M7.5 13.5 10 11"/><path d="M10.5 16.5 13 14"/><path d="m18 3-4 4h6l-4 4"/></svg>

After

Width:  |  Height:  |  Size: 424 B

1
assets/Battery 1 Bar.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-low-icon lucide-battery-low"><path d="M22 14v-4"/><path d="M6 14v-4"/><rect x="2" y="6" width="16" height="12" rx="2"/></svg>

After

Width:  |  Height:  |  Size: 335 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-medium-icon lucide-battery-medium"><path d="M10 14v-4"/><path d="M22 14v-4"/><path d="M6 14v-4"/><rect x="2" y="6" width="16" height="12" rx="2"/></svg>

After

Width:  |  Height:  |  Size: 362 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-full-icon lucide-battery-full"><path d="M10 10v4"/><path d="M14 10v4"/><path d="M22 14v-4"/><path d="M6 10v4"/><rect x="2" y="6" width="16" height="12" rx="2"/></svg>

After

Width:  |  Height:  |  Size: 376 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bluetooth-connected-icon lucide-bluetooth-connected"><path d="m7 7 10 10-5 5V2l5 5L7 17"/><line x1="18" x2="21" y1="12" y2="12"/><line x1="3" x2="6" y1="12" y2="12"/></svg>

After

Width:  |  Height:  |  Size: 374 B

1
assets/Bluetooth Off.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bluetooth-off-icon lucide-bluetooth-off"><path d="m17 17-5 5V12l-5 5"/><path d="m2 2 20 20"/><path d="M14.5 9.5 17 7l-5-5v4.5"/></svg>

After

Width:  |  Height:  |  Size: 336 B

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-icon lucide-battery"><path d="M 22 14 L 22 10"/><rect x="2" y="6" width="16" height="12" rx="2"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bluetooth-icon lucide-bluetooth"><path d="m7 7 10 10-5 5V2l5 5L7 17"/></svg>

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 278 B

Before After
Before After

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-wifi-off-icon lucide-wifi-off"><path d="M12 20h.01"/><path d="M8.5 16.429a5 5 0 0 1 7 0"/><path d="M5 12.859a10 10 0 0 1 5.17-2.69"/><path d="M19 12.859a10 10 0 0 0-2.007-1.523"/><path d="M2 8.82a15 15 0 0 1 4.177-2.643"/><path d="M22 8.82a15 15 0 0 0-11.288-3.764"/><path d="m2 2 20 20"/></svg>

After

Width:  |  Height:  |  Size: 497 B