waybar: add nowplaying module

- Add a playerctl-backed now playing widget
- Track a default disk list file instead of a home-manager symlink
This commit is contained in:
2026-02-05 12:01:06 -08:00
committed by Kat Huang
parent b089d7701c
commit 937b1c218c
3 changed files with 131 additions and 3 deletions

View File

@@ -1,4 +1,5 @@
// -*- mode: jsonc -*- // -*- mode: jsonc -*-
// Icon sizes are synced at runtime from vars.env via scripts/render-config.
{ {
"height": 42, "height": 42,
"spacing": 4, "spacing": 4,
@@ -7,7 +8,8 @@
"hyprland/submap" "hyprland/submap"
], ],
"modules-center": [ "modules-center": [
"hyprland/window" "hyprland/window",
"custom/nowplaying"
], ],
"modules-right": [ "modules-right": [
"idle_inhibitor", "idle_inhibitor",
@@ -31,10 +33,12 @@
} }
}, },
"tray": { "tray": {
"spacing": 10 "spacing": 10,
"icon-size": 24,
"watcher": "internal"
}, },
"clock": { "clock": {
"format": "{:%H:%M}", "format": "{:%I:%M %p}",
"tooltip-format": "{:%Y %B}\n{calendar}", "tooltip-format": "{:%Y %B}\n{calendar}",
"format-alt": "{:%Y-%m-%d}" "format-alt": "{:%Y-%m-%d}"
}, },
@@ -51,6 +55,15 @@
"format": "DISK {text}", "format": "DISK {text}",
"tooltip": false "tooltip": false
}, },
"custom/nowplaying": {
"exec": "~/.config/waybar/scripts/nowplaying",
"exec-if": "command -v playerctl",
"return-type": "json",
"format": "NP {text}",
"interval": 2,
"max-length": 50,
"tooltip": true
},
"temperature": { "temperature": {
"critical-threshold": 80, "critical-threshold": 80,
"format": "TEMP {temperatureC}C" "format": "TEMP {temperatureC}C"

View File

@@ -0,0 +1,2 @@
# One mountpoint per line (comments with # are ignored).
/

View File

@@ -0,0 +1,113 @@
#!/usr/bin/env bash
set -euo pipefail
if ! command -v playerctl >/dev/null 2>&1; then
exit 0
fi
preferred_players="${WAYBAR_NOWPLAYING_PLAYERS:-spotify,spotifyd,playerctld,vlc,mpv,firefox,chromium}"
IFS=',' read -r -a preferred_list <<< "$preferred_players"
mapfile -t players < <(playerctl -l 2>/dev/null || true)
if [[ ${#players[@]} -eq 0 ]]; then
exit 0
fi
has_player() {
local target="$1"
for player in "${players[@]}"; do
if [[ "$player" == "$target" ]]; then
return 0
fi
done
return 1
}
selected=""
selected_status=""
for player in "${preferred_list[@]}"; do
player="${player//[[:space:]]/}"
[[ -z "$player" ]] && continue
if has_player "$player"; then
status=$(playerctl --player "$player" status 2>/dev/null || true)
if [[ "$status" == "Playing" ]]; then
selected="$player"
selected_status="$status"
break
fi
if [[ "$status" == "Paused" && -z "$selected" ]]; then
selected="$player"
selected_status="$status"
fi
fi
done
if [[ -z "$selected" ]]; then
for player in "${players[@]}"; do
status=$(playerctl --player "$player" status 2>/dev/null || true)
if [[ "$status" == "Playing" ]]; then
selected="$player"
selected_status="$status"
break
fi
if [[ "$status" == "Paused" && -z "$selected" ]]; then
selected="$player"
selected_status="$status"
fi
done
fi
if [[ -z "$selected" ]]; then
exit 0
fi
if [[ -z "$selected_status" ]]; then
selected_status=$(playerctl --player "$selected" status 2>/dev/null || true)
fi
if [[ "$selected_status" != "Playing" && "$selected_status" != "Paused" ]]; then
exit 0
fi
artist=$(playerctl --player "$selected" metadata artist 2>/dev/null || true)
title=$(playerctl --player "$selected" metadata title 2>/dev/null || true)
artist="${artist//$'\n'/ }"
artist="${artist//$'\r'/ }"
title="${title//$'\n'/ }"
title="${title//$'\r'/ }"
if [[ -z "$artist" && -z "$title" ]]; then
exit 0
fi
text="$title"
if [[ -n "$artist" && -n "$title" ]]; then
text="$artist - $title"
elif [[ -n "$artist" ]]; then
text="$artist"
fi
if [[ "${WAYBAR_NOWPLAYING_SHOW_PLAYER:-0}" == "1" ]]; then
text="${selected}: ${text}"
fi
json_escape() {
local input="$1"
input=${input//\\/\\\\}
input=${input//\"/\\\"}
input=${input//$'\n'/\\n}
printf '%s' "$input"
}
class="paused"
if [[ "$selected_status" == "Playing" ]]; then
class="playing"
fi
tooltip="${selected}\n${selected_status}\n${text}"
printf '{"text":"%s","class":"%s","tooltip":"%s"}\n' \
"$(json_escape "$text")" \
"$(json_escape "$class")" \
"$(json_escape "$tooltip")"