aboutsummaryrefslogtreecommitdiff
path: root/tw/services/files/volume
diff options
context:
space:
mode:
authorTimo Wilken2024-03-09 14:52:56 +0100
committerTimo Wilken2024-03-10 16:19:00 +0100
commitde20fc8d904643ffe6957febfc6a24e57c12b512 (patch)
tree8177459e40786bd432a37c5833f26350fb689356 /tw/services/files/volume
parentda5e9d5ee98dfc216eb7e3b1559c09f4bf868bf6 (diff)
Separate home service into PIM, dev env and graphical parts
This means we only instantiate Shepherd and mcron services if we really need them, to avoid annoyance on servers.
Diffstat (limited to 'tw/services/files/volume')
-rwxr-xr-xtw/services/files/volume60
1 files changed, 60 insertions, 0 deletions
diff --git a/tw/services/files/volume b/tw/services/files/volume
new file mode 100755
index 00000000..96398553
--- /dev/null
+++ b/tw/services/files/volume
@@ -0,0 +1,60 @@
+#!/usr/bin/env -S guile --no-auto-compile
+!#
+(use-modules (ice-9 format)
+ (ice-9 match)
+ (ice-9 popen)
+ (ice-9 regex)
+ (ice-9 textual-ports))
+
+(define (read-from-pactl . args)
+ (let* ((port (apply open-pipe* OPEN_READ "pactl" args))
+ (output (get-string-all port)))
+ (close-pipe port)
+ (string-trim-right output #\newline)))
+
+(define %default-sink
+ (read-from-pactl "get-default-sink"))
+
+(define* (sink-muted? #:optional (sink %default-sink))
+ (match (read-from-pactl "get-sink-mute" sink)
+ ("Mute: yes" #t)
+ ("Mute: no" #f)
+ (output (error "Unknown `pactl get-sink-mute' output" output))))
+
+(define* (sink-volume #:optional (sink %default-sink))
+ (match-let ((`#(,match (,start . ,end))
+ (string-match "[0-9]+%" (read-from-pactl "get-sink-volume" sink))))
+ (string->number (substring match start (1- end))))) ; trim trailing "%"
+
+(define* (set-sink-mute! #:optional (state "toggle") (sink %default-sink))
+ (status:exit-val
+ (system* "pactl" "set-sink-mute" sink state)))
+
+(define* (increment-sink-volume! increment-percent #:optional (sink %default-sink))
+ (status:exit-val
+ (system* "pactl" "set-sink-volume" sink
+ ;; A percentage with a sign is an increment.
+ (format #f "~@d%" increment-percent))))
+
+(define* (notify #:optional (muted? (sink-muted?)) (volume (sink-volume)))
+ (status:exit-val
+ (system* "dunstify" "-a" "volume" "-u" "low"
+ "-i" (cond (muted? "audio-volume-muted")
+ ((< volume 50) "audio-volume-low")
+ (#t "audio-volume-high"))
+ "-h" "string:x-canonical-private-synchronous:volume"
+ "-h" (format #f "int:value:~d" (if muted? 0 volume))
+ (if muted? "Volume muted" "Volume"))))
+
+(match (cdr (program-arguments))
+ (() 0) ; notify only
+ (("mute") (set-sink-mute! "true"))
+ (("unmute") (set-sink-mute! "false"))
+ (("toggle-mute") (set-sink-mute! "toggle"))
+ (((? string->number increment-percent))
+ (and (set-sink-mute! "false")
+ (increment-sink-volume!
+ (string->number increment-percent))))
+ (args (error "Could not parse command-line arguments:" args)))
+
+(notify)