Wayland layer-shell popup for quickly controlling PipeWire audio volume.
Built with iced and iced-layershell.
| Tray popup | Settings panel |
|---|---|
![]() |
![]() |
Tray popup
- Output and input volume sliders (0–150%) with live percentage readout
- Individual mute button per channel; icon switches to 🔇 and row dims when muted
- Mute All / Unmute toggle
- Volume feedback sound on output slider release
- Closes on Escape or click outside
Settings panel (⚙ button in tray header)
- System output and input device selection via pick-lists
- Per-application volume sliders and device routing for all active PipeWire streams
- System / Custom routing mode toggle per applications section — System routes all streams to the default device automatically; Custom restores per-app preferences
- Routing preferences persisted in
~/.config/veu/device-prefs.confand re-applied on launch - Application icons loaded from the hicolor icon theme; app name shown as tooltip
- Theme picker at the bottom of the panel — changes apply instantly
- Wayland compositor with
wlr-layer-shellsupport (Hyprland, Sway, etc.) - PipeWire + WirePlumber (
wpctlandpactlin PATH) - Rust toolchain (for building from source)
System-wide (installs to /usr/local/bin, requires sudo):
bash scripts/install.shCurrent user only (installs to ~/.local/bin, no sudo):
bash scripts/install.sh --userOne-line install from GitHub:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/rafaelzimmermann/veu/main/scripts/install.sh)"bash scripts/install.sh --uninstallBind veu to a key in your compositor config, e.g. Hyprland:
bind = $mod, V, exec, veu
Control where the popup appears by editing ~/.config/veu/theme.conf:
# Options: top-right | top-left | top-center
# bottom-right | bottom-left | bottom-center | center
placement = top-right
# Gap in pixels from the anchored screen edge (set to your waybar height
# so the popup appears just below it rather than overlapping).
margin = 40Select a theme from the THEME pick-list at the bottom of the settings panel — the change applies immediately and is persisted automatically.
Alternatively, write a theme name directly to ~/.config/veu/current-theme:
echo catppuccin-mocha > ~/.config/veu/current-themeBundled themes: default, catppuccin-mocha, dracula, gruvbox-dark, nord, tokyo-night.
To customise colours, edit ~/.config/veu/theme.conf (installed automatically, or copy from assets/theme.conf). Named themes only override colours — your placement and margin are preserved.
src/
├── main.rs # entry point, layer-shell window settings
├── app/
│ ├── mod.rs # app state, message routing, tray/settings mode switch
│ └── components/
│ ├── mod.rs
│ ├── volume.rs # tray popup — sliders, per-channel mute, gear button
│ └── settings.rs # settings panel — system devices, per-app routing, themes
├── audio/
│ └── mod.rs # PipeWire abstraction (wpctl + pactl), icon lookup, prefs
└── theme/
└── mod.rs # Theme struct, named theme loading, persistence helpers

