Profile Picture

Assorted tech

Hi, my name is Spencer. I'm a CS graduate focused on systems programming, Linux, and low-complexity design. Other interests: metal, hiking, guitar, rationality.

feed | contact

Configuring Swaybar with MPD, Volume, and Weather Display

Calendar icon March 5, 2021

Clock icon 4 min read

Folder icon #linux #sway #mpd #customize #tiling in tech

Swaybar

Swaybar is the default bar that comes with Sway, a tiling window manager for Wayland. By default it displays only the workspace indicator and time, it looks like this: Swaybar Default

It’s functional but a little plain. This is what mine looks like: Customized Swaybar

Aesthetic Changes

There are main ways to make it look better:

Fonts

Fonts can be specified in ~/.config/sway/config: just add font pango:Fira Sans SemiBold 9 or similar somewhere. This font is also used for window titles, if you haven’t disabled them with default_border pixel.

Colors

To change the bar colors, edit the colors subsection in the bar block:

bar {
    colors {
        statusline #ebdbb2
        background #3c3836
        
        # Outline, Background, Foreground
        inactive_workspace #282828 #282828 #928374
        focused_workspace #83a598 #458588 #eddbb2
    }
}

Functional Changes

How do we add more useful things to the bar?

The first step is to move the status_command into its own file, replace the line with status_command ~/.config/sway/bar.sh or whatever file you’d like, then create that file and make sure to run chmod +x ~/.config/sway/bar.sh so it can be executed. Inside this file you will need a while loop so that it always updates at a constant step:

while true
do
    msg='This will display on the bar'
    echo "$msg"
    sleep 1
done 

Now adding things to the bar is simply echoing output from the script. For cleanliness, I put all of the components I want to display in their own variables just as shown above with msg. To divide things up for readability, I separate my components with vertical pipe characters: echo "$msg | $time", etc.

Custom Time Format

I didn’t like the default datetime format, so I split it up. Inside the while loop I have the following:

# $(cmd) stores the output of cmd
date=$(date +'%A, %b %d')
time=$(date +'%I%M %p')

# => Friday, Mar 05 | 03:47 PM
echo "$date | $time"
sleep 1

Volume

This will work for both pulseaudio and pipewire, which I recently switched to. Install pamixer if you don’t have it already, then you can store the output of pamixer --get-volume in a variable, and echo "$vol% to suffix it with a percent sign.

MPD Music

The command to be stored and echo'd here is mpc -f "%title% - %artist%" | head -n 1. head is used to remove unwanted lines from mpc (may need to be installed) output.

Weather

This took me a bit to get right. We want a fast refresh rate (sleep 1 = update every second) for time and music, but making an HTTP request to get the current temperature every second is:

My solution is to read from a temporary file every second, but only update the temporary file every 15 minutes.

In my bar.sh script, I have temp=$(cat /tmp/weather). In the Sway configuration file I have exec ~/.config/sway/weather.sh to start the script to update the temporary file when Sway starts.

weather.sh is a bit more involved:

while true
do
    # Get output silently, remove unwanted lines, reformat, output to temp file
    curl -s wttr.in?QT0 | grep -m 1 ' °F' | perl -pe 's/.*?\+(\d+2)(\(d+\))? °F.*$/$1$2 °F/' > /tmp/weather
    sleep 900
done

You may want to curl wttr.in to make sure it is getting weather data for the correct location. If it isn’t, add /cityname to the end of the URL.

Conclusion

It’s easy to add any information you want to Swaybar. Simply echo the data you want in a script pointed to by the Sway configuration file. If Swaybar doesn’t meet your customization/aesthetic needs, have a look at Waybar.

Comments