4

Sorry if the title isn't too descriptive. I want to achieve the following "animation":

- Song Name
\ Song Name    # all these 4 would stay on the same line by
| Song Name    # replacing each other every 0.5 seconds     
/ Song Name
current_window_title # then for 2 seconds the current window 
                     # title will be displayed

# repeat the animation from the start over and over

I hope that you understand. I'm trying to make a module for my Polybar that shows the played song, then shows the current window title. Unfortunately, I'm not that experienced with Bash in order to achieve this result.

So far I managed to get the song animation part, but when it comes to combining it with the 2 seconds of displaying the current window name on the same line, ahh kind of a headache.

#!/bin/bash

chars="/-\|"
while sleep 0.5; do
    echo -en "${chars:$(( i=(i+1) % ${#chars} )):1}" "Song Name" "\r"
done

Can you guys give me some pointers or some help please? Tried to do it myself for 2 days but I can't really figure it out. Is it possible at least?

Thank you in advance.

2 Answers 2

4

Try,

#!/bin/bash

chars="/-\|"
while :; do
    for (( i=0; i<${#chars}; i++ )); do
        printf '%s %s\r' "${chars:$i:1}" "Song Name"
        sleep 0.5
    done
    # Clear line and print window name
    printf '\033[2K%s\r' "$(xdotool getactivewindow getwindowname)"
    sleep 2
    # Go up one line and clear line
    printf "\033[2K"

done
# Add newline in the very end if you like
echo

This is a combination of:

You may need to install xdotool:

sudo apt install xdotool
1
  • Just as a side note: OP wants to use the script in polybar and "clearing" a line in polybar works a bit different than in the shell. In polybar each new line clears the previous one. So no carriage return or ANSI escape codes are needed. Apr 20, 2021 at 17:22
2

You are very close.

#!/bin/bash

chars="/-\|"

while sleep 0.5; do
    tput el
    echo -en "${chars:$(( i=(i+1) % ${#chars} )):1}" "Song Name" "\r"
    (($i == 3)) && sleep 0.5 && tput el && echo -en "$(xdotool getactivewindow getwindowname)" "\r" && sleep 1.5     
done
  • tput el clears the line for next output. Although you might not need it for Polybar... But it's there just in case.
  • (($i == 3)) when this condition is met, the commands after it on the same line separated by && will run one after the other. 3 is how many characters in chars="/-\|" starting from 0 so 0,1,2,3... Keep this in mind when changing the string in chars.

Notice that xdotool getactivewindow getwindowname will get the current active window name... This means the active window at each time "$(xdotool getactivewindow getwindowname)" is run... which could be your browser tab for example if you click on it at that time. Unfortunately this behavior is the same with other tools like xprop and wmctrl... a workaround would be to declare a variable before the while loop like so window="$(xdotool getactivewindow getwindowname)" and echo this variable inside the loop so it remains the same afterwords avoiding other active windows later on... Or you can set a static name and echo it if you know the name in advance.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .