Files
dotfiles/docs/superpowers/specs/2026-05-11-volume-notification-design.md
funman300 a812715e46 docs: spec for volume change notification
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 10:36:47 -07:00

4.0 KiB
Raw Permalink Blame History

Volume Notification Design

Date: 2026-05-11 Status: Approved

Summary

Show a mako notification with the current volume level (or "Muted") whenever the user presses the XF86Audio volume keys. Notifications collapse onto themselves so rapid key presses produce a single updating bubble rather than a stack. Mako's progress-bar render shows the current level visually.

Current Behaviour

niri/config.kdl lines 9799 wire the media keys directly to pamixer:

XF86AudioRaiseVolume allow-when-locked=true { spawn "pamixer" "-i" "5"; }
XF86AudioLowerVolume allow-when-locked=true { spawn "pamixer" "-d" "5"; }
XF86AudioMute        allow-when-locked=true { spawn "pamixer" "-t"; }

Volume changes silently. The waybar pulseaudio widget reflects the new value on its next 5 s poll, but there is no immediate visual feedback at the moment of the keypress — and on the lock screen, no feedback at all (waybar isn't visible).

Target Behaviour

Each volume keypress:

  1. Adjusts the master sink via pamixer -i 5 / pamixer -d 5 / pamixer -t.
  2. Reads the resulting state.
  3. Fires a notify-send with mako's progress-bar hint, replacing any previous volume notification (no stacking).
Key Action Notification
XF86AudioRaiseVolume volume +5% Volume: NN% with N% progress bar
XF86AudioLowerVolume volume 5% Volume: NN% with N% progress bar
XF86AudioMute toggle mute Muted (with 0% bar) when muting; Volume: NN% when unmuting

Notification timeout: 1500 ms.

Implementation

scripts/volume.sh (new)

#!/bin/bash

case "${1:-}" in
    up)   pamixer -i 5 ;;
    down) pamixer -d 5 ;;
    mute) pamixer -t ;;
    *)    echo "usage: $0 up|down|mute" >&2; exit 1 ;;
esac

if [ "$(pamixer --get-mute)" = "true" ]; then
    notify-send -h string:x-canonical-private-synchronous:volume \
                -h int:value:0 \
                -t 1500 \
                "Muted"
else
    LEVEL=$(pamixer --get-volume)
    notify-send -h string:x-canonical-private-synchronous:volume \
                -h int:value:"$LEVEL" \
                -t 1500 \
                "Volume: ${LEVEL}%"
fi

The string:x-canonical-private-synchronous:volume hint is mako's standard mechanism for "transient" notifications — successive notifications carrying the same synchronous-key replace the previous one in place rather than stacking. Mashing the volume key produces a single updating bubble.

int:value:N makes mako render a progress bar at N% (mako displays this for any notification carrying the value hint).

niri/config.kdl

Replace lines 9799 with calls to the wrapper:

XF86AudioRaiseVolume allow-when-locked=true { spawn "volume" "up"; }
XF86AudioLowerVolume allow-when-locked=true { spawn "volume" "down"; }
XF86AudioMute        allow-when-locked=true { spawn "volume" "mute"; }

allow-when-locked=true stays — the notification is still wanted on the lock screen (the lockscreen appears above mako, but mako's bubble shows briefly when the screen is unlocked, and the volume change itself happens regardless).

install.sh

Append one symlink line in the existing ==> Installing scripts block (after the existing waybar-restart.sh and screenshot.sh lines):

ln -sf "$(pwd)/scripts/volume.sh" ~/.local/bin/volume

Files Touched

File Action
scripts/volume.sh created
niri/config.kdl three lines (9799) modified
install.sh one symlink line appended

Out of Scope

  • Volume changes from other sources (terminal pamixer, GUI like pavucontrol). Only this wrapper's invocations trigger notifications. A pulseaudio event listener daemon could cover that case but is bigger scope.
  • Per-app sink-input volumes. Master volume only.
  • Variable step sizes (Shift for 1% etc.). Fixed 5% step matches the existing keybinds.
  • Microphone toggle (XF86AudioMicMute). Not in current keybinds.
  • Custom notification icon. Default mako presentation suffices; icon hint would add machine-specific theming.