mirror of
https://gitlab.com/linuxstuff/dotfiles.git
synced 2026-08-15 12:59:28 +02:00
Finalized cava module integration
This commit is contained in:
+7
-11
@@ -25,9 +25,9 @@ unfocused = ${xrdb:foreground}
|
|||||||
; Bars
|
; Bars
|
||||||
|
|
||||||
[bar/floating]
|
[bar/floating]
|
||||||
;modules-right = disk_short_pc checkupdates ovpn nvpn eth_pc
|
|
||||||
modules-left = sysinfo button_pavucontrol
|
modules-left = sysinfo button_pavucontrol
|
||||||
modules-center = cava clock playerctl_long
|
modules-center = cava
|
||||||
|
;modules-center = cava clock playerctl_long
|
||||||
modules-right = sensors_cpu_pc nvgpu memory
|
modules-right = sensors_cpu_pc nvgpu memory
|
||||||
monitor = ${env:MONITOR:DP-4}
|
monitor = ${env:MONITOR:DP-4}
|
||||||
width = 60%
|
width = 60%
|
||||||
@@ -381,18 +381,9 @@ exec = ~/.config/polybar/scripts/polypopup.sh
|
|||||||
click-left = ~/.config/polybar/scripts/polypopup.sh --toggle
|
click-left = ~/.config/polybar/scripts/polypopup.sh --toggle
|
||||||
content =
|
content =
|
||||||
|
|
||||||
[module/cava]
|
|
||||||
type = custom/script
|
|
||||||
tail = true
|
|
||||||
interval = 0.1
|
|
||||||
format = <label>
|
|
||||||
exec = bash ~/.config/polybar/scripts/modules/cava_read.sh
|
|
||||||
|
|
||||||
[module/playerctl]
|
[module/playerctl]
|
||||||
type = custom/script
|
type = custom/script
|
||||||
tail = true
|
tail = true
|
||||||
format-prefix = ""
|
|
||||||
format = <label>
|
|
||||||
exec = ~/.config/polybar/scripts/modules/playerctl.sh
|
exec = ~/.config/polybar/scripts/modules/playerctl.sh
|
||||||
click-left = "playerctl play-pause"
|
click-left = "playerctl play-pause"
|
||||||
click-right = "playerctl next"
|
click-right = "playerctl next"
|
||||||
@@ -402,6 +393,11 @@ click-middle = "playerctl previous"
|
|||||||
inherit="module/playerctl"
|
inherit="module/playerctl"
|
||||||
exec = bash ~/.config/polybar/scripts/modules/playerctl.sh 30
|
exec = bash ~/.config/polybar/scripts/modules/playerctl.sh 30
|
||||||
|
|
||||||
|
[module/cava]
|
||||||
|
type = custom/script
|
||||||
|
tail = true
|
||||||
|
exec = python /home/sim/.config/polybar/scripts/modules/cava.py
|
||||||
|
|
||||||
[module/playerctl-buttons]
|
[module/playerctl-buttons]
|
||||||
type = custom/menu
|
type = custom/menu
|
||||||
expand-right = true
|
expand-right = true
|
||||||
|
|||||||
@@ -1,31 +1,49 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Kill hideit instances
|
######################
|
||||||
|
# Kill programs used by modules
|
||||||
|
#
|
||||||
|
# hideit
|
||||||
ps -ef | grep hideIt | grep -v grep | awk '{print $2}' | xargs kill
|
ps -ef | grep hideIt | grep -v grep | awk '{print $2}' | xargs kill
|
||||||
|
#
|
||||||
|
# cava
|
||||||
|
killall -q cava
|
||||||
|
|
||||||
|
|
||||||
|
######################
|
||||||
# Kill polybar instances
|
# Kill polybar instances
|
||||||
|
#
|
||||||
killall -q polybar
|
killall -q polybar
|
||||||
|
#
|
||||||
# Wait until the processes have been shut down
|
# Wait until the processes have been shut down
|
||||||
while pgrep -x polybar >/dev/null; do sleep 1; done
|
while pgrep -x polybar >/dev/null; do sleep 1; done
|
||||||
|
|
||||||
# Launch
|
|
||||||
polybar floating -r -l warning &
|
|
||||||
#setsid ~/.config/polybar/scripts/hideIt.sh --wait --region 0x1080+1920+-10 --name '^Polybar tray window$' &
|
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Launch polybar(s)
|
||||||
|
#
|
||||||
|
polybar floating -r -l warning &
|
||||||
polybar floating_wm -r -l warning &
|
polybar floating_wm -r -l warning &
|
||||||
polybar floating_sysinfo -r -l warning &
|
polybar floating_sysinfo -r -l warning &
|
||||||
|
#
|
||||||
polybar pc_vnc_landscape -r -l warning &
|
#polybar pc_vnc_landscape -r -l warning &
|
||||||
|
#
|
||||||
|
# Wait a moment for the bar(s) to set up
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
setsid ~/.config/polybar/scripts/hideIt.sh --wait --region 0x1080+1920+-10 --name '^polybar-floating_DP-4$' &
|
|
||||||
|
|
||||||
# Toggle sysinfo polybar
|
|
||||||
(xdo id -m -N Polybar && polybar-msg -p $(ps -ef | grep floating_sysinfo | grep -v grep | awk '{print $2}') cmd hide)&
|
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Launch programs used by modules
|
||||||
|
#
|
||||||
|
setsid ~/.config/polybar/scripts/hideIt.sh --wait --region 0x1080+1920+-10 --name '^polybar-floating_DP-4$' > /dev/null 2>&1 &
|
||||||
|
#
|
||||||
|
# Hide floating_sysinfo polybar and reset popup state
|
||||||
|
(xdo id -m -N Polybar && polybar-msg -p $(ps -ef | grep floating_sysinfo | grep -v grep | awk '{print $2}') cmd hide) > /dev/null 2>&1 &
|
||||||
STATUSFILE="$HOME/.config/polybar/scripts/.sysinfo.active"
|
STATUSFILE="$HOME/.config/polybar/scripts/.sysinfo.active"
|
||||||
rm "$STATUSFILE"
|
rm -f "$STATUSFILE"
|
||||||
|
|
||||||
echo "Bar launched..."
|
|
||||||
|
######################
|
||||||
|
# Done!
|
||||||
|
#
|
||||||
|
echo "Bar launched!"
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
######################
|
######################
|
||||||
# Preferences
|
# Preferences
|
||||||
|
|
||||||
|
# Print verbose logs
|
||||||
|
LOGS=0
|
||||||
|
|
||||||
# Set if opened popups should keep the bar shown
|
# Set if opened popups should keep the bar shown
|
||||||
POPUPS_PIN=1
|
POPUPS_PIN=1
|
||||||
|
|
||||||
@@ -61,7 +64,6 @@ _HAS_REGION=1
|
|||||||
_WAIT_PID=""
|
_WAIT_PID=""
|
||||||
_PID_FILE=""
|
_PID_FILE=""
|
||||||
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
# Print usage
|
# Print usage
|
||||||
printf "usage: $0 [options]\n"
|
printf "usage: $0 [options]\n"
|
||||||
@@ -143,7 +145,6 @@ usage() {
|
|||||||
printf " $ hideIt.sh --name '^dropdown-terminal$' --toggle\n"
|
printf " $ hideIt.sh --name '^dropdown-terminal$' --toggle\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
argparse() {
|
argparse() {
|
||||||
# Parse system args
|
# Parse system args
|
||||||
|
|
||||||
@@ -181,7 +182,7 @@ argparse() {
|
|||||||
;;
|
;;
|
||||||
"-r" | "--region")
|
"-r" | "--region")
|
||||||
local posX posY offsetX offsetY
|
local posX posY offsetX offsetY
|
||||||
read posX posY offsetX offsetY <<<$(echo "$2" | \
|
read posX posY offsetX offsetY <<<$(echo "$2" |
|
||||||
sed -rn 's/^([0-9]+)x([0-9]+)\+(-?[0-9]+)\+(-?[0-9]+)/\1 \2 \3 \4/p')
|
sed -rn 's/^([0-9]+)x([0-9]+)\+(-?[0-9]+)\+(-?[0-9]+)/\1 \2 \3 \4/p')
|
||||||
|
|
||||||
# Test if we have proper values by trying
|
# Test if we have proper values by trying
|
||||||
@@ -204,8 +205,8 @@ argparse() {
|
|||||||
read MINY MAXY <<<"$MAXY $MINY"
|
read MINY MAXY <<<"$MAXY $MINY"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! $MINX =~ [0-9]+ ]] || [[ ! $MINY =~ [0-9]+ ]] \
|
if [[ ! $MINX =~ [0-9]+ ]] || [[ ! $MINY =~ [0-9]+ ]] ||
|
||||||
|| [[ ! $MAXY =~ [0-9]+ ]] || [[ ! $MAXY =~ [0-9]+ ]]; then
|
[[ ! $MAXY =~ [0-9]+ ]] || [[ ! $MAXY =~ [0-9]+ ]]; then
|
||||||
printf "Missing or invalid region. See --help for usage.\n" 1>&2
|
printf "Missing or invalid region. See --help for usage.\n" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -274,8 +275,8 @@ argparse() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $TOGGLE -ne 0 ] && [ $TOGGLE_PEEK -ne 0 ] && [ $SIGNAL -ne 0 ] \
|
if [ $TOGGLE -ne 0 ] && [ $TOGGLE_PEEK -ne 0 ] && [ $SIGNAL -ne 0 ] &&
|
||||||
&& [ $_HAS_REGION -ne 0 ] && [ $HOVER -ne 0 ]; then
|
[ $_HAS_REGION -ne 0 ] && [ $HOVER -ne 0 ]; then
|
||||||
printf "At least one of --toggle, --signal, --hover or" 1>&2
|
printf "At least one of --toggle, --signal, --hover or" 1>&2
|
||||||
printf " --region is required!\n" 1>&2
|
printf " --region is required!\n" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -375,7 +376,6 @@ function fetch_screen_dimensions() {
|
|||||||
SCREEN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
|
SCREEN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function fetch_window_dimensions() {
|
function fetch_window_dimensions() {
|
||||||
# Sets the values for the following globals unless no WIN_ID exists
|
# Sets the values for the following globals unless no WIN_ID exists
|
||||||
# WIN_WIDTH, WIN_HEIGHT, WIN_POSX, WIN_POSY
|
# WIN_WIDTH, WIN_HEIGHT, WIN_POSX, WIN_POSY
|
||||||
@@ -390,18 +390,17 @@ function fetch_window_dimensions() {
|
|||||||
WIN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
|
WIN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
|
||||||
|
|
||||||
if [ ! -z "$1" ] && [ $1 -eq 0 ]; then
|
if [ ! -z "$1" ] && [ $1 -eq 0 ]; then
|
||||||
WIN_POSX=$(echo "$win_info" | \
|
WIN_POSX=$(echo "$win_info" |
|
||||||
sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
|
sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
|
||||||
WIN_POSY=$(echo "$win_info" | \
|
WIN_POSY=$(echo "$win_info" |
|
||||||
sed -rn 's/.*Absolute upper-left Y: +(-?[0-9]+)/\1/p')
|
sed -rn 's/.*Absolute upper-left Y: +(-?[0-9]+)/\1/p')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local win_info_MOVEALONG=$(xwininfo -id $WIN_ID_MOVEALONG_ONE)
|
local win_info_MOVEALONG=$(xwininfo -id $WIN_ID_MOVEALONG_ONE)
|
||||||
WIN_POSX_MOVEALONG_ONE=$(echo "$win_info_MOVEALONG" | \
|
WIN_POSX_MOVEALONG_ONE=$(echo "$win_info_MOVEALONG" |
|
||||||
sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
|
sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function send_signal() {
|
function send_signal() {
|
||||||
# Send a SIGUSR1 to an active hideIt.sh instance
|
# Send a SIGUSR1 to an active hideIt.sh instance
|
||||||
# if a pid file was found.
|
# if a pid file was found.
|
||||||
@@ -411,8 +410,8 @@ function send_signal() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local _pid=`cat $_PID_FILE`
|
local _pid=$(cat $_PID_FILE)
|
||||||
printf "Sending ${signal} to instance...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Sending ${signal} to instance...\n"; fi
|
||||||
|
|
||||||
if [[ $_pid =~ [0-9]+ ]]; then
|
if [[ $_pid =~ [0-9]+ ]]; then
|
||||||
kill -${signal} $_pid
|
kill -${signal} $_pid
|
||||||
@@ -426,12 +425,12 @@ function send_signal() {
|
|||||||
function winmove() {
|
function winmove() {
|
||||||
#echo "WIN_ID $WIN_ID"
|
#echo "WIN_ID $WIN_ID"
|
||||||
xdotool windowmove $WIN_ID $1 $2
|
xdotool windowmove $WIN_ID $1 $2
|
||||||
2>/dev/null 1>&2 xdotool windowmove $WIN_ID $1 $2
|
xdotool 2>/dev/null 1>&2 windowmove $WIN_ID $1 $2
|
||||||
|
|
||||||
# Tray
|
# Tray
|
||||||
#echo "WIN_ID_MOVEALONG_ONE $WIN_ID_MOVEALONG_ONE"
|
#echo "WIN_ID_MOVEALONG_ONE $WIN_ID_MOVEALONG_ONE"
|
||||||
#xdotool windowmove $WIN_ID_MOVEALONG_ONE $1 $2
|
#xdotool windowmove $WIN_ID_MOVEALONG_ONE $1 $2
|
||||||
2>/dev/null 1>&2 xdotool windowmove $WIN_ID_MOVEALONG_ONE $WIN_POSX_MOVEALONG_ONE $(($2 + 4))
|
xdotool 2>/dev/null 1>&2 windowmove $WIN_ID_MOVEALONG_ONE $WIN_POSX_MOVEALONG_ONE $(($2 + 4))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,7 +537,6 @@ function hide_window() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
# Toggle the hidden state of the window
|
# Toggle the hidden state of the window
|
||||||
|
|
||||||
@@ -586,8 +584,8 @@ function serve_region() {
|
|||||||
eval $(xdotool getmouselocation --shell)
|
eval $(xdotool getmouselocation --shell)
|
||||||
|
|
||||||
# Test if the cursor is within the region
|
# Test if the cursor is within the region
|
||||||
if [ $X -ge $MINX -a $X -le $MAXX ] \
|
if [ $X -ge $MINX -a $X -le $MAXX ] &&
|
||||||
&& [ $Y -ge $MINY -a $Y -le $MAXY ]; then
|
[ $Y -ge $MINY -a $Y -le $MAXY ]; then
|
||||||
_hide=1
|
_hide=1
|
||||||
else
|
else
|
||||||
|
|
||||||
@@ -600,9 +598,9 @@ function serve_region() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Don't hide if the cursor is still above the window
|
# Don't hide if the cursor is still above the window
|
||||||
if [ $_IS_HIDDEN -ne 0 ] \
|
if [ $_IS_HIDDEN -ne 0 ] &&
|
||||||
&& [ $_hide -eq 0 ] \
|
[ $_hide -eq 0 ] &&
|
||||||
&& [ $WINDOW -eq $WIN_ID ]; then
|
[ $WINDOW -eq $WIN_ID ]; then
|
||||||
_hide=1
|
_hide=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -618,7 +616,6 @@ function serve_region() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function serve_xev() {
|
function serve_xev() {
|
||||||
# Wait for cursor "Enter" and "Leave" events reported by
|
# Wait for cursor "Enter" and "Leave" events reported by
|
||||||
# xev and act accordingly
|
# xev and act accordingly
|
||||||
@@ -634,7 +631,6 @@ function serve_xev() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function restore() {
|
function restore() {
|
||||||
# Called by trap once we receive an EXIT
|
# Called by trap once we receive an EXIT
|
||||||
|
|
||||||
@@ -647,39 +643,38 @@ function restore() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $_IS_HIDDEN -eq 0 ]; then
|
if [ $_IS_HIDDEN -eq 0 ]; then
|
||||||
printf "Restoring original window position...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Restoring original window position...\n"; fi
|
||||||
hide_window 1
|
hide_window 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
# Entry point for hideIt
|
# Entry point for hideIt
|
||||||
|
|
||||||
# Parse all the args!
|
# Parse all the args!
|
||||||
argparse "$@"
|
argparse "$@"
|
||||||
|
|
||||||
printf "Searching window...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Searching window...\n"; fi
|
||||||
fetch_window_id
|
fetch_window_id
|
||||||
|
|
||||||
# If enabled, wait until a window was found.
|
# If enabled, wait until a window was found.
|
||||||
if [ $WAIT -eq 0 ] && [[ ! $WIN_ID =~ [0-9]+ ]]; then
|
if [ $WAIT -eq 0 ] && [[ ! $WIN_ID =~ [0-9]+ ]]; then
|
||||||
printf "Waiting for window"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Waiting for window"; fi
|
||||||
while [[ ! $WIN_ID =~ [0-9]+ ]]; do
|
while [[ ! $WIN_ID =~ [0-9]+ ]]; do
|
||||||
printf "."
|
printf "."
|
||||||
fetch_window_id
|
fetch_window_id
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
printf "\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "\n"; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! $WIN_ID =~ [0-9]+ ]]; then
|
if [[ ! $WIN_ID =~ [0-9]+ ]]; then
|
||||||
printf "No window found!\n" 1>&2
|
printf "No window found!\n" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
printf "Found window with id: $WIN_ID\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Found window with id: $WIN_ID\n"; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $TOGGLE -eq 0 ]; then
|
if [ $TOGGLE -eq 0 ]; then
|
||||||
@@ -692,15 +687,15 @@ function main() {
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "Fetching window dimensions...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Fetching window dimensions...\n"; fi
|
||||||
fetch_window_dimensions 0
|
fetch_window_dimensions 0
|
||||||
|
|
||||||
printf "Fetching screen dimensions...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Fetching screen dimensions...\n"; fi
|
||||||
fetch_screen_dimensions
|
fetch_screen_dimensions
|
||||||
|
|
||||||
trap restore EXIT
|
trap restore EXIT
|
||||||
|
|
||||||
printf "Initially hiding window...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Initially hiding window...\n"; fi
|
||||||
hide_window 0
|
hide_window 0
|
||||||
|
|
||||||
# Save our pid into a file
|
# Save our pid into a file
|
||||||
@@ -709,20 +704,22 @@ function main() {
|
|||||||
|
|
||||||
# Start observing
|
# Start observing
|
||||||
if [ $_HAS_REGION -eq 0 ]; then
|
if [ $_HAS_REGION -eq 0 ]; then
|
||||||
|
if [ ! "$LOGS" -eq 0 ]; then
|
||||||
printf "Defined region:\n"
|
printf "Defined region:\n"
|
||||||
printf " X: $MINX $MAXX\n"
|
printf " X: $MINX $MAXX\n"
|
||||||
printf " Y: $MINY $MAXY\n"
|
printf " Y: $MINY $MAXY\n"
|
||||||
printf "\n"
|
printf "\n"
|
||||||
printf "Waiting for region...\n"
|
printf "Waiting for region...\n"
|
||||||
|
fi
|
||||||
serve_region &
|
serve_region &
|
||||||
_WAIT_PID=$!
|
_WAIT_PID=$!
|
||||||
elif [ $SIGNAL -eq 0 ]; then
|
elif [ $SIGNAL -eq 0 ]; then
|
||||||
printf "Waiting for SIGUSR1...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Waiting for SIGUSR1...\n"; fi
|
||||||
trap toggle SIGUSR1
|
trap toggle SIGUSR1
|
||||||
sleep infinity &
|
sleep infinity &
|
||||||
_WAIT_PID=$!
|
_WAIT_PID=$!
|
||||||
elif [ $HOVER -eq 0 ]; then
|
elif [ $HOVER -eq 0 ]; then
|
||||||
printf "Waiting for HOVER...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Waiting for HOVER...\n"; fi
|
||||||
serve_xev &
|
serve_xev &
|
||||||
_WAIT_PID=$!
|
_WAIT_PID=$!
|
||||||
fi
|
fi
|
||||||
@@ -730,7 +727,7 @@ function main() {
|
|||||||
if [ -n "$_WAIT_PID" ]; then
|
if [ -n "$_WAIT_PID" ]; then
|
||||||
while true; do
|
while true; do
|
||||||
wait "$_WAIT_PID"
|
wait "$_WAIT_PID"
|
||||||
printf "Received signal...\n"
|
if [ ! "$LOGS" -eq 0 ]; then printf "Received signal...\n"; fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+255
-129
@@ -1,178 +1,304 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import struct
|
import struct
|
||||||
import os.path
|
import os.path
|
||||||
import subprocess
|
import subprocess
|
||||||
import configparser
|
import configparser
|
||||||
from collections import defaultdict
|
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# Config
|
# Config
|
||||||
|
|
||||||
# Decide if the output should go to STDOUT or a fifo buffer
|
# This script converts cava's data output into fancy little bars. These values can range from 0 to 100
|
||||||
PRINT_TO_STDOUT = False
|
# We need to distribute 9 characters ('Zero output' and all bar heights: '▁▂▃▄▅▆▇█') over this value range.
|
||||||
|
# The 'BAR_FACTOR' is used to calculator all those states and keep the code readable
|
||||||
|
# (See 'BAR_CHARACTERS')
|
||||||
|
#
|
||||||
|
BAR_FACTOR = 100 / 7
|
||||||
|
|
||||||
# Display no output if all bars are at level 0
|
# Configure resolution and style of the output here.
|
||||||
HIDE_WHEN_EMPTY = True
|
# The script fetches the cava output value and searches for the biggest matching key to get the character from
|
||||||
|
# (See 'BAR_FACTOR')
|
||||||
|
#
|
||||||
|
BAR_CHARACTERS = dict([
|
||||||
|
(000, '▁'), # Zero output
|
||||||
|
|
||||||
# Separator Character between bars
|
(BAR_FACTOR * 1, '▁'),
|
||||||
# Examples: https://www.compart.com/en/unicode/category/Zs
|
(BAR_FACTOR * 2, '▂'),
|
||||||
|
(BAR_FACTOR * 3, '▃'),
|
||||||
|
(BAR_FACTOR * 4, '▄'),
|
||||||
|
(BAR_FACTOR * 5, '▅'),
|
||||||
|
(BAR_FACTOR * 6, '▆'),
|
||||||
|
(BAR_FACTOR * 7, '▇'),
|
||||||
|
|
||||||
|
(100, '█'), # Highest output
|
||||||
|
])
|
||||||
|
|
||||||
|
# Separator Character between bars. Can be anything
|
||||||
|
#
|
||||||
|
# Default: ' '
|
||||||
|
#
|
||||||
SEPARATOR = ' '
|
SEPARATOR = ' '
|
||||||
|
|
||||||
CONFIG_PATH = os.path.join(os.sep, "tmp","cava_polybar.config")
|
# Display no output if all bars are at minimum level (no sound output)
|
||||||
RAW_PIPE_OUT = os.path.join(os.sep, "tmp","cava_polybar_output.fifo")
|
#
|
||||||
|
# Default: False
|
||||||
|
#
|
||||||
|
HIDE_WHEN_EMPTY = True
|
||||||
|
|
||||||
# Data from the cava config
|
# Specify how long this script should wait before printing another value
|
||||||
RAW_PIPE_IN = os.path.join(os.sep, "tmp","cava_polybar_input.fifo")
|
#
|
||||||
OUTPUT_FILE = os.path.join(os.sep, "tmp","cava_polybar.out")
|
# Default: 0.0005
|
||||||
BARS_NUMBER = 8
|
#
|
||||||
OUTPUT_BIT_FORMAT = "8bit"
|
OUTPUT_DELAY = 0.0005
|
||||||
|
|
||||||
# Values range from 0 to 100
|
# Specify how many times cava can report "no sound" (all values are 0) before the script detects it
|
||||||
# Distribute 9 states over this value range
|
#
|
||||||
# ▁▂▃▄▅▆▇█
|
# Default: 5
|
||||||
|
#
|
||||||
|
EMPTY_OUTPUT_THRESHOLD = 5
|
||||||
|
|
||||||
bar_factor = 100 / 10
|
# If the script output should be written to a named pipe, specify the path here.
|
||||||
bar_characters = dict([
|
# Set to 'None' to disable FIFO output and print to STDOUT
|
||||||
(0, '▁'),
|
#
|
||||||
(bar_factor * 1, '▁'),
|
# Default: None
|
||||||
(bar_factor * 2, '▂'),
|
#
|
||||||
(bar_factor * 3, '▃'),
|
# Examples:
|
||||||
(bar_factor * 4, '▄'),
|
# "/tmp/cava_polybar_output.fifo"
|
||||||
(bar_factor * 5, '▅'),
|
# os.path.join(os.sep, "tmp", "cava_polybar_output.fifo")
|
||||||
(bar_factor * 6, '▆'),
|
#
|
||||||
(bar_factor * 7, '▇'),
|
PIPE_OUT = None
|
||||||
(bar_factor * 8, '█')
|
|
||||||
])
|
|
||||||
|
# Path of the temporary cava configuration used to run the cava subprocess
|
||||||
|
#
|
||||||
|
# Default: os.path.join(os.sep, "tmp", "cava_polybar.config")
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# "/tmp/cava_polybar.config"
|
||||||
|
# os.path.join(os.sep, "tmp", "cava_polybar.config")
|
||||||
|
#
|
||||||
|
CAVA_CONFIG_PATH = os.path.join(os.sep, "tmp", "cava_polybar.config")
|
||||||
|
|
||||||
|
# The following data will be used in the temporary cava config
|
||||||
|
#
|
||||||
|
# FIFO input pipe for raw cava data
|
||||||
|
#
|
||||||
|
PIPE_IN = os.path.join(os.sep, "tmp", "cava_polybar_input.fifo")
|
||||||
|
|
||||||
|
# Number of bars in cava
|
||||||
|
#
|
||||||
|
# Default: 8
|
||||||
|
#
|
||||||
|
CAVA_BARS_NUMBER = 16
|
||||||
|
|
||||||
|
# Output bit format for cava.
|
||||||
|
# Can be 16bit ot 8bit, but 8 should be plenty of resolution for the default of 8 bars...
|
||||||
|
#
|
||||||
|
# Default: "8bit"
|
||||||
|
#
|
||||||
|
CAVA_BIT_FORMAT = "8bit"
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# Code begins here
|
# Code begins here
|
||||||
|
|
||||||
bytetype, bytesize, bytenorm = ("H", 2, 65535) if (OUTPUT_BIT_FORMAT == "16bit") else ("B", 1, 255)
|
bytetype, bytesize, bytenorm = ("H", 2, 65535) if (
|
||||||
|
CAVA_BIT_FORMAT == "16bit") else ("B", 1, 255)
|
||||||
|
|
||||||
def output(value, fifo):
|
|
||||||
if (PRINT_TO_STDOUT):
|
def output(string, file):
|
||||||
print(value, end="")
|
"""
|
||||||
|
Print/Write the given value either to STDOUT ot the specified output pipe
|
||||||
|
|
||||||
|
Args:
|
||||||
|
string ([string]): String to print
|
||||||
|
file ([file]): [description]
|
||||||
|
"""
|
||||||
|
|
||||||
|
if (PIPE_OUT):
|
||||||
|
file.write(string)
|
||||||
else:
|
else:
|
||||||
fifo.write(value)
|
print(string, end="")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
time.sleep(OUTPUT_DELAY)
|
||||||
|
|
||||||
|
|
||||||
def valToBar(value):
|
def valueToCharacter(value):
|
||||||
for bar_threshold in bar_characters:
|
"""
|
||||||
|
Returns the respective character for a value. Returns 'highest' character if no match is found
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value ([int]): Value that should be mapped to a character
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
[char]: Respective character for the given value
|
||||||
|
"""
|
||||||
|
|
||||||
|
for bar_threshold in BAR_CHARACTERS:
|
||||||
if(value < bar_threshold):
|
if(value < bar_threshold):
|
||||||
return bar_characters[bar_threshold]
|
return BAR_CHARACTERS[bar_threshold]
|
||||||
|
return BAR_CHARACTERS[100]
|
||||||
|
|
||||||
return bar_characters[bar_factor * 8]
|
|
||||||
|
|
||||||
def test():
|
def run():
|
||||||
|
"""
|
||||||
|
Prepare variables and run the conversion process
|
||||||
|
"""
|
||||||
|
|
||||||
|
createCavaConfig()
|
||||||
|
|
||||||
|
# Create cava subprocess
|
||||||
|
FNULL = open(os.devnull, 'w')
|
||||||
|
cavaProcess = subprocess.Popen(
|
||||||
|
["cava", "-p", CAVA_CONFIG_PATH],
|
||||||
|
stdout=FNULL,
|
||||||
|
stderr=subprocess.STDOUT
|
||||||
|
)
|
||||||
|
|
||||||
|
# Open output pipe if specified
|
||||||
|
outputPipe = None
|
||||||
|
if (PIPE_OUT):
|
||||||
|
print("The converted output can be found in " + PIPE_OUT)
|
||||||
|
|
||||||
|
if os.path.exists(PIPE_OUT):
|
||||||
|
os.remove(PIPE_OUT)
|
||||||
|
|
||||||
|
os.mkfifo(PIPE_OUT)
|
||||||
|
outputPipe = open(PIPE_OUT, "w")
|
||||||
|
|
||||||
|
# Open input pipe (raw cava data)
|
||||||
|
inputPipe = open(PIPE_IN, "rb")
|
||||||
|
|
||||||
|
exitCode = 0
|
||||||
|
try:
|
||||||
|
# Run the conversion process
|
||||||
|
convert(inputPipe, outputPipe)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
exitCode = 1
|
||||||
|
|
||||||
|
# Close output pipe if needed
|
||||||
|
if (PIPE_OUT):
|
||||||
|
outputPipe.close()
|
||||||
|
os.remove(PIPE_OUT)
|
||||||
|
|
||||||
|
# Close input pipe and kill the subprocess
|
||||||
|
inputPipe.close()
|
||||||
|
cavaProcess.kill()
|
||||||
|
|
||||||
|
sys.exit(exitCode)
|
||||||
|
|
||||||
|
|
||||||
|
def convert(inputPipe, outputPipe=None):
|
||||||
|
"""
|
||||||
|
Converts values taken from the input pipe to printable characters.
|
||||||
|
The result is either printed to STDOUT or written to the output pipe
|
||||||
|
|
||||||
|
Args:
|
||||||
|
inputPipe ([file]): Input file containing raw cava data
|
||||||
|
outputPipe ([file]): Output file (if specified)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Initialize variables
|
||||||
|
chunk = bytesize * CAVA_BARS_NUMBER
|
||||||
|
fmt = bytetype * CAVA_BARS_NUMBER
|
||||||
|
|
||||||
|
emptyOutputs = 0
|
||||||
|
|
||||||
|
# Convert
|
||||||
|
while True:
|
||||||
|
rawData = inputPipe.read(chunk)
|
||||||
|
if len(rawData) < chunk:
|
||||||
|
break
|
||||||
|
|
||||||
|
tstring = ""
|
||||||
|
emptyOutput = True
|
||||||
|
|
||||||
|
for i in struct.unpack(fmt, rawData):
|
||||||
|
value = int(i / bytenorm * 100)
|
||||||
|
|
||||||
|
if (len(tstring) > 0):
|
||||||
|
tstring += SEPARATOR
|
||||||
|
tstring += valueToCharacter(value)
|
||||||
|
|
||||||
|
if (value != 0):
|
||||||
|
emptyOutput = False
|
||||||
|
|
||||||
|
if (emptyOutput and HIDE_WHEN_EMPTY):
|
||||||
|
emptyOutputs += 1
|
||||||
|
if (emptyOutputs > EMPTY_OUTPUT_THRESHOLD):
|
||||||
|
output(" " + os.linesep, outputPipe)
|
||||||
|
else:
|
||||||
|
emptyOutputs = 0
|
||||||
|
output(tstring + os.linesep, outputPipe)
|
||||||
|
|
||||||
|
|
||||||
|
def createCavaConfig():
|
||||||
|
"""
|
||||||
|
Create the temporary configuration file used by the cava subprocess
|
||||||
|
"""
|
||||||
|
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
|
config.add_section('general')
|
||||||
|
config.set('general', 'bars', str(CAVA_BARS_NUMBER))
|
||||||
|
config.set('general', 'overshoot', str(0))
|
||||||
|
|
||||||
|
config.add_section('output')
|
||||||
|
config.set('output', 'method', 'raw')
|
||||||
|
config.set('output', 'channels', 'mono')
|
||||||
|
config.set('output', 'mono_option', 'average')
|
||||||
|
config.set('output', 'raw_target', PIPE_IN)
|
||||||
|
config.set('output', 'bit_format', CAVA_BIT_FORMAT)
|
||||||
|
|
||||||
|
config.add_section('smoothing')
|
||||||
|
config.set('smoothing', 'integral', '0')
|
||||||
|
|
||||||
|
with open(CAVA_CONFIG_PATH, 'w') as configfile:
|
||||||
|
config.write(configfile)
|
||||||
|
|
||||||
|
|
||||||
|
def printTestData():
|
||||||
|
"""
|
||||||
|
Prints test data to stdout. Useful for checking resolution and customisation configuration
|
||||||
|
"""
|
||||||
|
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
print("Bar Characters:")
|
print("Bar Characters:")
|
||||||
for bar_threshold in bar_characters:
|
for bar_threshold in BAR_CHARACTERS:
|
||||||
print('{:02.2f}: {}'.format(bar_threshold,bar_characters[bar_threshold]))
|
print('{:06.2f}: {}'.format(
|
||||||
|
bar_threshold, BAR_CHARACTERS[bar_threshold]))
|
||||||
|
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
print("Value Test:")
|
print("Value Test:")
|
||||||
for i in range(101):
|
for i in range(101):
|
||||||
print('{:03d}: {}'.format(i,valToBar(i)))
|
print('{:03d}: {}'.format(i, valueToCharacter(i)))
|
||||||
|
|
||||||
def createCavaConfig():
|
|
||||||
# Exit if file is already there
|
|
||||||
#if (os.path.isfile(CONFIG_PATH)):
|
|
||||||
# return
|
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
|
|
||||||
config.add_section('general')
|
|
||||||
config.set('general', 'bars', str(BARS_NUMBER))
|
|
||||||
#config.set('general', 'overshoot', str(0))
|
|
||||||
|
|
||||||
config.add_section('output')
|
|
||||||
config.set('output', 'method', 'raw')
|
|
||||||
#config.set('output', 'channels', 'mono')
|
|
||||||
#config.set('output', 'mono_option', 'average')
|
|
||||||
config.set('output', 'raw_target', RAW_PIPE_IN)
|
|
||||||
config.set('output', 'bit_format', OUTPUT_BIT_FORMAT)
|
|
||||||
|
|
||||||
#config.add_section('smoothing')
|
|
||||||
#config.set('smoothing', 'integral', '0')
|
|
||||||
|
|
||||||
with open(CONFIG_PATH, 'w') as configfile:
|
|
||||||
config.write(configfile)
|
|
||||||
|
|
||||||
def run():
|
|
||||||
createCavaConfig()
|
|
||||||
process = subprocess.Popen(["cava", "-p", CONFIG_PATH])
|
|
||||||
|
|
||||||
exit_code = 0
|
|
||||||
|
|
||||||
fifo_out = None
|
|
||||||
if (not PRINT_TO_STDOUT):
|
|
||||||
if os.path.exists(RAW_PIPE_OUT):
|
|
||||||
os.remove(RAW_PIPE_OUT)
|
|
||||||
os.mkfifo(RAW_PIPE_OUT)
|
|
||||||
print("Output can be found in " + RAW_PIPE_OUT)
|
|
||||||
fifo_out = open(RAW_PIPE_OUT, "w")
|
|
||||||
fifo_in = open(RAW_PIPE_IN, "rb")
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
convert(fifo_in, fifo_out)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
exit_code = 1
|
|
||||||
finally:
|
|
||||||
if (not PRINT_TO_STDOUT):
|
|
||||||
fifo_out.close()
|
|
||||||
os.remove(RAW_PIPE_OUT)
|
|
||||||
|
|
||||||
fifo_in.close()
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
||||||
def convert(fifo_in, fifo_out):
|
|
||||||
chunk = bytesize * BARS_NUMBER
|
|
||||||
fmt = bytetype * BARS_NUMBER
|
|
||||||
|
|
||||||
emptyOutputs = 0
|
|
||||||
tstring = ""
|
|
||||||
|
|
||||||
while True:
|
|
||||||
rawData = fifo_in.read(chunk)
|
|
||||||
if len(rawData) < chunk:
|
|
||||||
break
|
|
||||||
|
|
||||||
empty = True
|
|
||||||
tstring = ""
|
|
||||||
|
|
||||||
for i in struct.unpack(fmt, rawData):
|
|
||||||
|
|
||||||
value = int(i / bytenorm * 100)
|
|
||||||
|
|
||||||
tstring += valToBar(value) + SEPARATOR
|
|
||||||
|
|
||||||
if (value != 0):
|
|
||||||
empty = False
|
|
||||||
|
|
||||||
if (empty and HIDE_WHEN_EMPTY):
|
|
||||||
emptyOutputs += 1
|
|
||||||
if (emptyOutputs > 5):
|
|
||||||
output(" " + '\n', fifo_out)
|
|
||||||
else:
|
|
||||||
emptyOutputs = 0
|
|
||||||
output(tstring + '\n', fifo_out)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
# Sort the dict to ensure correct character mapping
|
||||||
|
BAR_CHARACTERS = OrderedDict(sorted(BAR_CHARACTERS.items()))
|
||||||
|
|
||||||
for arg in sys.argv:
|
for arg in sys.argv:
|
||||||
if (arg == "h" or arg == "help"):
|
if (arg == "h" or arg == "help"):
|
||||||
print("")
|
print("")
|
||||||
print("cava polybar parse script")
|
print("cava polybar parse script")
|
||||||
print("Converts cava raw values into characters and outputs to STDOUT or a fifo buffer")
|
print(
|
||||||
|
"Converts cava raw values into characters and outputs to STDOUT or a fifo buffer")
|
||||||
print("")
|
print("")
|
||||||
print("Adjust thresholds, characters and config directly in the script")
|
print("Adjust thresholds, characters and config directly in the script")
|
||||||
print("If the config file at 'CONFIG_PATH' (/tmp/cava_polybar.config) is messed up, simply delet it")
|
print(
|
||||||
|
"If the config file at 'CONFIG_PATH' (/tmp/cava_polybar.config) is messed up, simply delet it")
|
||||||
print("")
|
print("")
|
||||||
print("Arguments:")
|
print("Arguments:")
|
||||||
print("<none> ... Execute normally")
|
print("<none> ... Execute normally")
|
||||||
@@ -182,7 +308,7 @@ if __name__ == "__main__":
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
if (arg == "t" or arg == "test"):
|
if (arg == "t" or arg == "test"):
|
||||||
test()
|
printTestData()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
run()
|
run()
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
python "$HOME/.config/polybar/scripts/modules/cava.py" &
|
|
||||||
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
fifo_name="/tmp/cava_polybar_output.fifo"
|
|
||||||
while true
|
|
||||||
do
|
|
||||||
|
|
||||||
echo "$line"
|
|
||||||
done <"$fifo_name"
|
|
||||||
Reference in New Issue
Block a user