GTK4 + gtk4-layer-shell volume OSD for Hyprland.
Runtime:
- Hyprland (Wayland session)
- PipeWire/WirePlumber with
wpctlavailable (/usr/bin/wpctl,/usr/local/bin/wpctl, or/bin/wpctl) jq(used by install script to readenable_slide)
Build:
gcc(or compatible C11 compiler)makepkg-configgtk4development filesgtk4-layer-shelldevelopment files
makeWarnings as errors:
make strictGenerate compile_commands.json for clangd/IDE diagnostics:
make compdbInstall binary + config + Hyprland startup hook:
make installReset config to latest shipped defaults:
make install-reset-configReset only the shipped style.css while keeping current config:
make install-reset-styleUninstall (keep config):
make uninstallUninstall and remove config:
make uninstall-purgeInstall uses the hyprvolume binary and a managed Hyprland snippet.
Install manages a namespace-scoped layer rule for slide animation:
enable_slide: falsewritesno_anim = onformatch:namespace = ^hyprvolume$- only
hyprvolumeis affected; no other layer app rules are touched
Watch mode:
./hyprvolume --watch --watch-poll-ms 120 --timeout-ms 1200Watch-mode performance behavior:
- while the popup is visible, polling uses
watch_poll_ms - while hidden, polling automatically backs off to a slower idle interval to reduce CPU load
- transient
wpctlquery failures are retried in-place so the watcher stays alive instead of exiting - watch mode always reads system volume from
wpctl(manual--value/--mutedapplies to one-shot mode only)
One-shot mode:
./hyprvolume --from-system --no-watch --timeout-ms 1200Default path:
$HOME/.config/hyprvolume/config.json
Load config explicitly:
./hyprvolume --config "$HOME/.config/hyprvolume/config.json"CLI options override config values.
For text/path options when the value starts with -, use either:
--option=-value--option -- -value
Config validation is strict:
- unknown top-level keys are rejected
- duplicate top-level keys are rejected
- trailing commas are rejected
Custom CSS can be loaded from file:
--css-file "$HOME/.config/hyprvolume/custom.css"--css-appendkeeps built-in theme CSS and applies custom CSS afterwards--css-replaceskips built-in theme CSS and uses only custom CSS--vertical/--horizontaltoggles layout direction
Default install ships and uses:
$HOME/.config/hyprvolume/style.cssas the user-editable style filecss_replace: trueandcss_fileset to that path in fresh/reset config- use
make install-reset-styleto restore style.css defaults
Custom CSS requirements:
- file must be a regular UTF-8 text file
- GTK CSS parsing errors are reported and style load is rejected
- file must be no larger than 256 KiB
Config file requirements:
- file must be no larger than 1 MiB
If wpctl is not in the trusted locations, an explicit override is supported:
- set
HYPRVOLUME_ALLOW_WPCTL_PATH_OVERRIDE=1 - set
HYPRVOLUME_WPCTL_PATHto an absolute executable path
Percent placement:
x_percent:0..100(left to right)y_percent:0..100(top to bottom)
Centered example:
{
"x_percent": 50,
"y_percent": 50
}Anchor placement is also supported:
anchor:top-center,top-left,top-right,bottom-center,bottom-left,bottom-rightmargin_x,margin_y
CLI margin note:
--margin-topmaps to configmargin_y
watch_mode(bool)use_system_volume(bool)enable_slide(bool, installer-managed Hyprland layerrule toggle)css_file(string, optional)css_replace(bool)timeout_ms(100-10000)watch_poll_ms(40-2000)monitor_index(-1 = default monitor)anchor(string)x_percent(0-100)y_percent(0-100)margin_x(0-500)margin_y(0-500)width(40-1400)height(20-300)vertical(bool)radius(0-200)icon_size(8-200)font_size(8-200)background_color(CSS color)border_color(CSS color)fill_color(CSS color)track_color(CSS color)text_color(CSS color)icon_color(CSS color)
Reference defaults:
assets/default-config.json
Shipped defaults are centered and riced for a cleaner look:
- smaller percentage text (
font_size: 14) - blue gradient slider accent (
fill_color) - indigo track contrast (
track_color) - dark glass panel tone (
background_color)

