Add .config/waybar/scripts/privacy_dots.sh
This commit is contained in:
parent
b82d88827c
commit
9b17e17078
1 changed files with 191 additions and 0 deletions
191
private_dot_config/waybar/scripts/executable_privacy_dots.sh
Normal file
191
private_dot_config/waybar/scripts/executable_privacy_dots.sh
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
#!/usr/bin/env bash
|
||||
# dependencies: pipewire (pw-dump), v4l2loopback-dkms, jq, dbus-send (dbus)
|
||||
set -euo pipefail
|
||||
|
||||
JQ_BIN="${JQ:-jq}"
|
||||
PW_DUMP_CMD="${PW_DUMP:-pw-dump}"
|
||||
|
||||
mic=0
|
||||
cam=0
|
||||
loc=0
|
||||
scr=0
|
||||
|
||||
mic_app=""
|
||||
cam_app=""
|
||||
loc_app=""
|
||||
scr_app=""
|
||||
|
||||
# mic & camera
|
||||
if command -v "$PW_DUMP_CMD" >/dev/null 2>&1 && command -v "$JQ_BIN" >/dev/null 2>&1; then
|
||||
dump="$($PW_DUMP_CMD 2>/dev/null || true)"
|
||||
|
||||
mic="$(
|
||||
printf '%s' "$dump" \
|
||||
| $JQ_BIN -r '
|
||||
[ .[]
|
||||
| select(.type=="PipeWire:Interface:Node")
|
||||
| select((.info.props."media.class"=="Audio/Source" or .info.props."media.class"=="Audio/Source/Virtual"))
|
||||
| select((.info.state=="running") or (.state=="running"))
|
||||
] | (if length>0 then 1 else 0 end)
|
||||
' 2>/dev/null || echo 0
|
||||
)"
|
||||
|
||||
if [[ "$mic" -eq 1 ]]; then
|
||||
mic_app="$(
|
||||
printf '%s' "$dump" \
|
||||
| $JQ_BIN -r '
|
||||
[ .[]
|
||||
| select(.type=="PipeWire:Interface:Node")
|
||||
| select((.info.props."media.class"=="Stream/Input/Audio"))
|
||||
| select((.info.state=="running") or (.state=="running"))
|
||||
| .info.props["node.name"]
|
||||
] | unique | join(", ")
|
||||
' 2>/dev/null || echo ""
|
||||
)"
|
||||
fi
|
||||
|
||||
if command -v fuser >/dev/null 2>&1; then
|
||||
cam=0
|
||||
for dev in /dev/video*; do
|
||||
if [ -e "$dev" ] && fuser "$dev" >/dev/null 2>&1; then
|
||||
cam=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
cam=0
|
||||
fi
|
||||
|
||||
if command -v fuser >/dev/null 2>&1; then
|
||||
for dev in /dev/video*; do
|
||||
if [ -e "$dev" ] && fuser "$dev" >/dev/null 2>&1; then
|
||||
pids=$(fuser "$dev" 2>/dev/null)
|
||||
for pid in $pids; do
|
||||
pname=$(ps -p "$pid" -o comm=)
|
||||
if [[ -n "$pname" ]]; then
|
||||
cam_app+="$pname, "
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
cam_app="${cam_app%, }"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# location
|
||||
if command -v gdbus >/dev/null 2>&1; then
|
||||
loc="$(
|
||||
if ps aux | grep [g]eoclue >/dev/null 2>&1; then
|
||||
echo 1
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
)"
|
||||
fi
|
||||
|
||||
if command -v gdbus >/dev/null 2>&1; then
|
||||
if pids=$(pgrep -x geoclue); then
|
||||
loc=1
|
||||
for pid in $pids; do
|
||||
pname=$(ps -p "$pid" -o comm=)
|
||||
[[ -n "$pname" ]] && loc_app+="$pname, "
|
||||
done
|
||||
loc_app="${loc_app%, }"
|
||||
else
|
||||
loc=0
|
||||
fi
|
||||
fi
|
||||
|
||||
# screen sharing
|
||||
if command -v "$PW_DUMP_CMD" >/dev/null 2>&1 && command -v "$JQ_BIN" >/dev/null 2>&1; then
|
||||
if [[ -z "${dump:-}" ]]; then
|
||||
dump="$($PW_DUMP_CMD 2>/dev/null || true)"
|
||||
fi
|
||||
|
||||
scr="$(
|
||||
printf '%s' "$dump" \
|
||||
| $JQ_BIN -e '
|
||||
[ .[]
|
||||
| select(.info?.props?)
|
||||
| select(
|
||||
(.info.props["media.name"]? // "")
|
||||
| test("^(xdph-streaming|gsr-default|game capture)")
|
||||
)
|
||||
]
|
||||
| (if length > 0 then true else false end)
|
||||
' >/dev/null && echo 1 || echo 0
|
||||
)"
|
||||
fi
|
||||
|
||||
if [[ "$scr" -eq 1 ]]; then
|
||||
scr_app="$(
|
||||
printf '%s' "$dump" \
|
||||
| $JQ_BIN -r '
|
||||
[ .[]
|
||||
| select(.type=="PipeWire:Interface:Node")
|
||||
| select((.info.props."media.class"=="Stream/Input/Video") or (.info.props."media.name"=="gsr-default_output") or (.info.props."media.name"=="game capture"))
|
||||
| select((.info.state=="running") or (.state=="running"))
|
||||
| .info.props["media.name"]
|
||||
] | unique | join(", ")
|
||||
' 2>/dev/null || echo ""
|
||||
)"
|
||||
fi
|
||||
|
||||
# output
|
||||
green="#30D158"
|
||||
orange="#FF9F0A"
|
||||
blue="#0A84FF"
|
||||
purple="#9B32FA"
|
||||
|
||||
dot() {
|
||||
local on="$1" color="$2" icon="$3"
|
||||
if [[ "$on" -eq 1 ]]; then
|
||||
printf '<span foreground="%s">'$icon'</span>' "$color"
|
||||
else
|
||||
printf ''
|
||||
fi
|
||||
}
|
||||
|
||||
dots=()
|
||||
mic_dot="$(dot "$mic" "$green" "")"; [[ -n "$mic_dot" ]] && dots+=("$mic_dot")
|
||||
cam_dot="$(dot "$cam" "$orange" "")"; [[ -n "$cam_dot" ]] && dots+=("$cam_dot")
|
||||
loc_dot="$(dot "$loc" "$blue" "")"; [[ -n "$loc_dot" ]] && dots+=("$loc_dot")
|
||||
scr_dot="$(dot "$scr" "$purple" "")"; [[ -n "$scr_dot" ]] && dots+=("$scr_dot")
|
||||
|
||||
text="${dots[*]}"
|
||||
|
||||
if [[ -n "$mic_app" ]]; then
|
||||
mic_status="Mic: $mic_app"
|
||||
else
|
||||
mic_status="Mic: off"
|
||||
fi
|
||||
|
||||
if [[ -n "$cam_app" ]]; then
|
||||
cam_status="Cam: $cam_app"
|
||||
else
|
||||
cam_status="Cam: off"
|
||||
fi
|
||||
|
||||
if [[ -n "$loc_app" ]]; then
|
||||
loc_status="Location: $loc_app"
|
||||
else
|
||||
loc_status="Location: off"
|
||||
fi
|
||||
|
||||
if [[ -n "$scr_app" ]]; then
|
||||
scr_status="Screen sharing: $scr_app"
|
||||
else
|
||||
scr_status="Screen sharing: off"
|
||||
fi
|
||||
|
||||
tooltip="$mic_status | $cam_status | $loc_status | $scr_status"
|
||||
|
||||
classes="privacydot"
|
||||
[[ $mic -eq 1 ]] && classes="$classes mic-on" || classes="$classes mic-off"
|
||||
[[ $cam -eq 1 ]] && classes="$classes cam-on" || classes="$classes cam-off"
|
||||
[[ $loc -eq 1 ]] && classes="$classes loc-on" || classes="$classes loc-off"
|
||||
[[ $scr -eq 1 ]] && classes="$classes scr-on" || classes="$classes scr-off"
|
||||
|
||||
jq -c -n --arg text "$text" --arg tooltip "$tooltip" --arg class "$classes" \
|
||||
'{text:$text, tooltip:$tooltip, class:$class}'
|
||||
Loading…
Reference in a new issue