Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
[workspace]
members = [
"crates/tablero",
"tools/icongen",
]
# The bar is the only shipped artifact; `icongen` is a build-time SVG flattener.
# Default builds/tests target just the bar so its lean dependency graph stays the
# common path — run the generator explicitly with `cargo run -p icongen`.
default-members = ["crates/tablero"]
resolver = "2"

# Size-optimized release build. The bar is a long-running daemon whose render
Expand Down
37 changes: 26 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ RUST_LOG=info cargo run -p tablero
that executable directly (no shell), so a typical use is `on-click =
"/path/to/blueman-manager"` to launch a Bluetooth manager on click.
- **Volume** — the active output sink's level (`Vol N%`) and mute state
(`Mute`), read over the native PipeWire wire protocol. The glyph swaps
between headphones / speakers / monitor / phone / TV based on the
active sink's device kind, so the user can tell at a glance which
output the level they see is on. **Opt-in**: not in the default set;
(`Mute`), read over the native PipeWire wire protocol. The icon is a
built-in speaker that follows the level — low / medium / high, or a
muted variant when muted — so the fill hints at the level at a glance.
Switching the active sink still triggers a repaint. **Opt-in**: not in the default set;
add `"volume"` to a zone to enable it. The widget reserves no slot
when no PipeWire server is reachable (or no output sink exists),
matching how the `network` and `system` widgets treat an absent
Expand Down Expand Up @@ -272,6 +272,22 @@ foreground = "#5ff5a0"
border = "#2df185"
```

Widget icons are **built-in vector art** drawn directly with `tiny-skia`, so no
icon font, SVG parser, or bundled glyph set is shipped — the icon inherits the
widget's state colors and scales with the output. Each icon-bearing widget takes
an `icon` field on its `[widget.<name>]` table:

- omitted → the widget's built-in icon,
- `icon = "none"` → **opt out**; the widget renders label-only (or nothing, for
icon-only widgets like `power`), keeping a simple text look,
- `icon = "<text>"` → override with any literal string, e.g. a Nerd Font glyph
or an emoji, rendered as text in place of the vector icon.

For widgets with a `format`/`format-icons` string (battery, backlight,
power-profiles-daemon, updates), the `{icon}` placeholder marks where the icon
sits; a `format-icons` entry supplies a per-state text glyph that overrides the
built-in art for that state.

Per-widget click handlers live on every `[widget.<name>]` table as
`on-click = "/path/to/executable"`. When set, a left-click inside that widget
spawns the file directly (no shell) — typical use is
Expand Down Expand Up @@ -534,9 +550,9 @@ surface placement and input need a live compositor. To verify on Hyprland:
15. Verify the **volume widget** (opt-in: add `"volume"` to a zone). With
a running PipeWire server (pipewire + wireplumber / pipewire-pulse)
and at least one output sink configured:
- The widget appears with a device-kind glyph (headphones, speakers,
monitor, …) and a label of `Vol N%` (where `N` is the active sink's
level). On a system with PipeWire but no output sink configured,
- The widget appears with a built-in speaker icon whose fill follows the
level (low / medium / high) and a label of `Vol N%` (where `N` is the
active sink's level). On a system with PipeWire but no output sink configured,
the widget reserves no slot (matching the `network` / `system`
pattern); on a system with no PipeWire running, the widget also
reserves no slot.
Expand All @@ -546,14 +562,13 @@ surface placement and input need a live compositor. To verify on Hyprland:
seconds when the cached state changes). The widget should track
per-cent: `12%`, `13%`, …
- Toggle mute with `pactl set-sink-mute @DEFAULT_SINK@ 1` and confirm
the label flips to `Mute` with the volume-mute glyph; toggling
mute back restores `Vol N%` with the device glyph.
the label flips to `Mute` with the muted speaker icon; toggling
mute back restores `Vol N%` with the level-based icon.
- With multiple sinks configured (e.g. headphones + monitor speakers),
play audio through one and confirm the widget tracks *that* sink
(active sink has its `NodeState` set to `Running`); switching
playback to a different sink updates the widget to that sink
within a poll, and the glyph follows the device kind (e.g.
headphones → speakers).
within a poll.
- If a `[widget.volume] on-click = "/path/to/executable"` is set
(typical: `pavucontrol`), left-click the widget and confirm the
configured process is spawned (no shell, direct exec). A missing
Expand Down
2 changes: 1 addition & 1 deletion crates/tablero/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tablero"
version = "0.2.4"
version = "0.3.0"
edition = "2024"
authors = ["piny4man <development@pinya.dev>"]
description = "A fast, native Wayland status bar for Hyprland"
Expand Down
21 changes: 10 additions & 11 deletions crates/tablero/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ foreground = "#eae2cf"
accent = "#7decff"

[font]
# Install this Nerd Font for the intended compact telemetry look and glyphs.
# Remove `family` to use the system default if it is unavailable.
# Widget icons are built-in vector art, so no icon font is required. `family`
# just picks the text face for labels; remove it to use the system default. A
# Nerd Font is only needed if you set custom text glyphs via `icon = "…"` or a
# `format-icons` string.
family = "JetBrainsMono Nerd Font"
size = 15.0

Expand All @@ -66,11 +68,11 @@ radius = 2
padding = 12
icon = "none"

# App tray icons arrive pre-rendered from each application, so a panel plate and
# outline only box them in and clash with their own colors. Left transparent, the
# icons sit directly on the bar the way Waybar renders them — sharp and self-styled.
[widget.tray]
background = "#1c0e1ee8"
foreground = "#eae2cf"
border = "#3d1f3a"
border-width = 1
radius = 2
padding = 6

Expand Down Expand Up @@ -189,12 +191,9 @@ padding = 8
format = "{icon}"
tooltip = true
tooltip-format = "POWER MODE: {profile}\nDRIVER: {driver}"

[widget.power-profiles-daemon.format-icons]
default = ""
performance = ""
balanced = ""
power-saver = ""
# No `format-icons` map: the built-in vector icons carry their own accent per
# profile — green for power-saver, blue for balanced, yellow for performance.
# Set a `format-icons` table here to override them with your own text glyphs.

# Cyan means the idle daemon is protecting the session; red means it is paused.
# Left-click toggles the native Hypridle process state without a helper script.
Expand Down
Loading