nvm actual init commit

This commit is contained in:
Breadway 2026-05-17 13:17:31 +08:00
parent 633467b6f2
commit 255be18ca2
6 changed files with 21 additions and 146 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/target
aster-brief.md

30
Cargo.lock generated
View file

@ -8,21 +8,6 @@ version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "aster"
version = "0.1.0"
dependencies = [
"futures-lite",
"gtk4",
"gtk4-layer-shell",
"hyprland",
"relm4",
"serde",
"serde_json",
"tokio",
"zbus",
]
[[package]]
name = "async-broadcast"
version = "0.7.2"
@ -91,6 +76,21 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
[[package]]
name = "breadbar"
version = "0.1.0"
dependencies = [
"futures-lite",
"gtk4",
"gtk4-layer-shell",
"hyprland",
"relm4",
"serde",
"serde_json",
"tokio",
"zbus",
]
[[package]]
name = "bumpalo"
version = "3.20.2"

View file

@ -1,5 +1,5 @@
[package]
name = "aster"
name = "breadbar"
version = "0.1.0"
edition = "2021"

View file

@ -1,126 +0,0 @@
# aster — Hyprland Bar & Notification Daemon
Minimal Rust status bar and notification daemon for Hyprland. Replaces colorshell with a lower system footprint. No system tray, no launcher, no wallpaper logic.
---
## Stack
| Crate | Purpose |
|---|---|
| `gtk4` | UI toolkit |
| `gtk4-layer-shell` | Wayland layer surface anchoring |
| `relm4` | Component architecture for GTK4 |
| `hyprland` | Hyprland IPC (workspace events) |
| `zbus` | D-Bus (notifications daemon) |
| `serde` + `serde_json` | Parse pywal colors.json |
| `tokio` | Async polling runtime |
---
## Component 1: Top Bar
Full-width bar anchored to the top of the screen via `gtk4-layer-shell`. Single horizontal row, three sections.
### Left — Workspaces
- Numbered workspace buttons sourced from Hyprland IPC
- Subscribe to live workspace change events via `/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock`
- Active workspace highlighted with accent colour
### Centre — Clock
- Format: `HH:MM`
- Updated every second
### Right — System Stats
Displayed left to right: CPU% → RAM% → Power draw (W) → WiFi SSID
| Stat | Source |
|---|---|
| CPU usage | `/proc/stat` delta between polls |
| RAM usage | `/proc/meminfo` |
| Power draw | `/sys/class/power_supply/*/power_now` or `current_now * voltage_now` |
| WiFi SSID | Parse `iw dev` output — no NetworkManager dependency, no system tray |
Polled every 2 seconds.
---
## Component 2: Notification Daemon
Implements the `org.freedesktop.Notifications` D-Bus interface via `zbus`.
- On `Notify` call: spawn a GTK4 layer-shell popup anchored **top-right**, 20px from edge
- Shows: app name, summary, body
- Auto-dismisses after the hint timeout (default 5s if unset by sender)
- Multiple notifications stack vertically downward
- Supports `CloseNotification`
---
## Theming
Read `~/.cache/wal/colors.json` on startup. Reload on `SIGHUP` for live wallpaper-change integration.
| pywal key | Role |
|---|---|
| `special.background` | Bar background (with slight CSS transparency) |
| `colors.color0` | Widget background / secondary surfaces |
| `colors.color15` | Foreground text |
| `colors.color1` | Accent — active workspace, highlights |
Apply as a GTK CSS provider at the `Display` level so the bar and all notification popups share the same palette automatically.
---
## Explicit Non-Goals
- No system tray (`StatusNotifierItem` / `XEmbed`)
- No launcher or search (external tool handles this)
- No wallpaper engine (external tool handles this)
- No Bluetooth, volume, or media controls
---
## Suggested File Structure
```
aster/
├── Cargo.toml
└── src/
├── main.rs # Init GTK app, spawn bar + notification daemon
├── bar/
│ ├── mod.rs
│ ├── workspaces.rs # Hyprland IPC workspace subscription
│ ├── clock.rs # Second-tick clock widget
│ └── stats.rs # CPU, RAM, power draw, WiFi SSID
├── notifications/
│ ├── mod.rs # zbus D-Bus service
│ └── popup.rs # GTK4 layer-shell popup window + stack
└── theme.rs # pywal reader + GTK CSS provider injection
```
---
## Build Order for Claude Code
Follow this sequence so each step is independently testable:
1. **Scaffold**`Cargo.toml` with all dependencies, module stubs, empty `main.rs`
2. **Layer shell anchor** — blank GTK4 window pinned to top of screen; confirm it appears correctly on your setup before adding any widgets
3. **Theme loader** — read `colors.json`, build CSS string, inject as `CssProvider` at display level
4. **Bar layout** — three-section `Box`, no data yet, just structure with placeholder labels
5. **Workspaces** — Hyprland IPC socket reader, live workspace buttons
6. **Stats poller** — tokio task polling CPU/RAM/power/WiFi, sending results to bar via channels
7. **Clock** — second-tick timer widget
8. **Notification daemon** — zbus service on session bus claiming `org.freedesktop.Notifications`
9. **Notification popup** — layer-shell window anchored top-right, vertical stack, auto-dismiss timer
10. **Wire SIGHUP** — reload `colors.json` and re-inject CSS on signal
---
## First Prompt for Claude Code
> Create a new Rust project called `aster`. It is a minimal Hyprland status bar and notification daemon. Start with `Cargo.toml` — I need gtk4, relm4, gtk4-layer-shell, hyprland, zbus, tokio, serde, and serde_json as dependencies. Then scaffold the module structure from the file tree in the brief and get a blank GTK4 window anchored full-width to the top of the screen with gtk4-layer-shell before adding any widgets. The layer-shell anchor is the most environment-sensitive step so I want to confirm it works on my setup first.

View file

@ -43,8 +43,8 @@ impl SimpleComponent for App {
view! {
gtk::ApplicationWindow {
add_css_class: "aster-bar",
set_title: Some("aster"),
add_css_class: "breadbar",
set_title: Some("breadbar"),
set_default_height: 32,
#[name = "center_box"]
@ -199,6 +199,6 @@ fn main() {
}
});
let app = RelmApp::new("sh.breadway.aster");
let app = RelmApp::new("sh.breadway.breadbar");
app.run::<App>(());
}

View file

@ -49,7 +49,7 @@ fn load_css() -> String {
border: none; min-width: 24px; padding: 0 8px; }}\
.workspace-btn:hover, .workspace-btn.active {{ background: {accent}; }}\
label {{ color: {fg}; }}\
window.aster-notification {{ background-color: alpha({bg_plain}, 0.95); }}\
window.breadbar-notification {{ background-color: alpha({bg_plain}, 0.95); }}\
.notification-card {{ background: {surface}; border-radius: 6px;\
padding: 10px; margin-bottom: 4px; }}\
.notification-summary {{ font-weight: bold; color: {fg}; }}\