|
1 |
+ |
#!/bin/sh |
|
2 |
+ |
# Requires: wireplumber (wpctl), and dunst or any notification daemon |
|
3 |
+ |
# Volume control without a menu, for the media keys and the bar. One script |
|
4 |
+ |
# does all four jobs; the vol-up/vol-down/vol-mute/vol-status symlinks beside |
|
5 |
+ |
# it pick which, so a keybind is a bare path with no arguments. The action can |
|
6 |
+ |
# also be given directly: `vol up`. The menu version is rofi-audio, which adds |
|
7 |
+ |
# mic and output switching. |
|
8 |
+ |
set -u |
|
9 |
+ |
|
|
10 |
+ |
STEP=${VOL_STEP:-5} |
|
11 |
+ |
# The same notification id rofi-audio uses, so a keypress and the menu replace |
|
12 |
+ |
# each other's popup rather than stacking two of them. |
|
13 |
+ |
NOTIFY_ID=7303 |
|
14 |
+ |
|
|
15 |
+ |
# @DEFAULT_AUDIO_SINK@ always resolves to whatever is current, so none of this |
|
16 |
+ |
# needs to know which sink that is. |
|
17 |
+ |
SINK=@DEFAULT_AUDIO_SINK@ |
|
18 |
+ |
|
|
19 |
+ |
# wpctl warns about rtkit on stderr under a plain X session; only stdout matters. |
|
20 |
+ |
volume() { wpctl get-volume "$SINK" 2>/dev/null; } |
|
21 |
+ |
percent() { volume | awk '{ printf "%d", $2 * 100 }'; } |
|
22 |
+ |
|
|
23 |
+ |
# Tracks the level the same way rofi-audio does, so a notification reads the |
|
24 |
+ |
# same whether it came from a media key or from the menu. |
|
25 |
+ |
icon() { |
|
26 |
+ |
case "$(volume)" in |
|
27 |
+ |
*MUTED*) printf '' ;; |
|
28 |
+ |
*) v=$(percent) |
|
29 |
+ |
if [ "$v" -eq 0 ]; then printf '' |
|
30 |
+ |
elif [ "$v" -lt 34 ]; then printf '' |
|
31 |
+ |
else printf '' |
|
32 |
+ |
fi ;; |
|
33 |
+ |
esac |
|
34 |
+ |
} |
|
35 |
+ |
|
|
36 |
+ |
report() { |
|
37 |
+ |
msg="$(icon) $(percent)%" |
|
38 |
+ |
# int:value draws dunst's progress bar; notify-send is the fallback for a |
|
39 |
+ |
# daemon that is not dunst. |
|
40 |
+ |
dunstify -r "$NOTIFY_ID" -h "int:value:$(percent)" "Volume" "$msg" 2>/dev/null || |
|
41 |
+ |
notify-send "Volume" "$msg" |
|
42 |
+ |
} |
|
43 |
+ |
|
|
44 |
+ |
# The name it was called by (vol-up -> up), or the first argument if given. |
|
45 |
+ |
action=${1:-$(printf '%s' "${0##*/}" | sed 's/^vol-*//')} |
|
46 |
+ |
|
|
47 |
+ |
case "$action" in |
|
48 |
+ |
# -l 1.0 caps at 100%, so a held key cannot push the sink into clipping. |
|
49 |
+ |
up) wpctl set-volume -l 1.0 "$SINK" "$STEP%+" 2>/dev/null; report ;; |
|
50 |
+ |
down) wpctl set-volume "$SINK" "$STEP%-" 2>/dev/null; report ;; |
|
51 |
+ |
mute) wpctl set-mute "$SINK" toggle 2>/dev/null; report ;; |
|
52 |
+ |
# Bar block: prints and exits, no notification. |
|
53 |
+ |
status) printf '%s %s%%\n' "$(icon)" "$(percent)" ;; |
|
54 |
+ |
*) echo "usage: ${0##*/} [up|down|mute|status]" >&2; exit 2 ;; |
|
55 |
+ |
esac |