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:
@@ -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"
|
||||||
|
|||||||
2
dotfiles/config/waybar/disks
Normal file
2
dotfiles/config/waybar/disks
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# One mountpoint per line (comments with # are ignored).
|
||||||
|
/
|
||||||
113
dotfiles/config/waybar/scripts/nowplaying
Executable file
113
dotfiles/config/waybar/scripts/nowplaying
Executable 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")"
|
||||||
Reference in New Issue
Block a user