Waybar icon indicating copy to clipboard operation
Waybar copied to clipboard

Automatically restart waybar after config change

Open Hubro opened this issue 4 years ago • 19 comments

Polybar has this option:

       -r, --reload
              Reload the application when the config file has been modified

Is there anything equivalent for Waybar?

Currently my workflow is to update the config, run "killall waybar" and then restart it, which is quite time consuming when doing lots of tweaks.

Rather than re-invent the wheel, is there currently a way to achieve this with Waybar? I have been utterly unable to find anything about this after thorough Googling and searching through existing issues, so my feeling is that I am missing something completely obvious.

Hubro avatar Dec 31 '20 07:12 Hubro

As a workaround, you could write a script using inotify to restart Waybar whenever the config changes - example (first Google result): https://superuser.com/questions/181517/how-to-execute-a-command-whenever-a-file-changes

Markaos avatar Jan 01 '21 21:01 Markaos

As a workaround, you could write a script using inotify to restart Waybar whenever the config changes - example (first Google result): https://superuser.com/questions/181517/how-to-execute-a-command-whenever-a-file-changes

Yeah my current workaroud looks like this:

launch-waybar:

#!/bin/bash

CONFIG_FILES="$HOME/.config/waybar/config $HOME/.config/waybar/style.css"

trap "killall waybar" EXIT

while true; do
    waybar &
    inotifywait -e create,modify $CONFIG_FILES
    killall waybar
done

Hubro avatar Jan 02 '21 21:01 Hubro

Thanks @Hubro! I'm currently making use of your solution until something "better" comes along =)

x10an14 avatar Jan 15 '21 11:01 x10an14

@Hubro how do you execute this from your Sway config? I am trying to run it using an exec command and it isn't working. This is at the bottom of my sway config

`bar { swaybar_command waybar }

exec ~/.config/sway/launch_waybar.sh`

hiszd avatar Jan 21 '22 15:01 hiszd

@hiszd I have this line at the end of my Sway config:

exec --no-startup-id "/bin/bash -c '[[ -f $HOME/autostart.sh ]] && . $HOME/autostart.sh &>> $HOME/autostart.log'"

Inside authstart.sh I have this line:

start launch-waybar

And the start command is just this script:

#!/bin/bash

nohup "$@" &>"/tmp/start-$(basename $1).log" &

Hubro avatar Jan 21 '22 17:01 Hubro

I wrote this script to reload waybar, just change the variables that point to the config and style.css files. I also put in a bind in my hyprland.conf file to run it.

'#!/bin/bash

CONFIG="$HOME/.config/hypr/waybar/config" STYLE="$HOME/.config/hypr/waybar/style.css"

if [[ $(pgrep -x "waybar") = "waybar" ]]; then killall waybar else if [[ $(pgrep -x "waybar") = "" ]]; then waybar -c $CONFIG -s $STYLE > /dev/null 2>&1 & fi fi'

maLi9n avatar Feb 09 '23 23:02 maLi9n

@maLi9n Triple backticks on separate lines for code blocks.

```
This is a code block
```

Hubro avatar Feb 10 '23 22:02 Hubro

https://github.com/Alexays/Waybar/wiki/FAQ#how-can-I-reload-the-configuration-without-restarting-waybar

HarHarLinks avatar Jul 26 '23 07:07 HarHarLinks

This is my solution. I have this script in exec-once.

#!/bin/bash

# start waybar if not started
if ! pgrep -x "waybar" > /dev/null; then
	waybar &
fi

# current checksums
current_checksum_config=$(md5sum ~/.config/waybar/config)
current_checksum_style=$(md5sum ~/.config/waybar/style.css)

# loop forever
while true; do
	# new checksums
	new_checksum_config=$(md5sum ~/.config/waybar/config)
	new_checksum_style=$(md5sum ~/.config/waybar/style.css)

	# if checksums are different
	if [ "$current_checksum_config" != "$new_checksum_config" ] || [ "$current_checksum_style" != "$new_checksum_style" ]; then
		# kill waybar
		killall waybar

		# start waybar
		waybar &

		# update checksums
		current_checksum_config=$new_checksum_config
		current_checksum_style=$new_checksum_style
	fi
done

This kills and restarts waybar every time the config changes. The change in config is detected by matching the checksums.

abhiyandhakal avatar Nov 03 '23 18:11 abhiyandhakal

So your loop constantly calculates checksums forever...? Seems highly inefficient, borderline abusive to the system...

I would expect that waybar would implement something along the lines of a SIGHUP that seems to be the standard for these kind of operations...

The rest of the scripts offered above, that kill/restart waybar, have an annoying refresh of the screen (at least on hyprland when the desktop is redrawn to occupy the waybar space on top).

My usecase is to change the colors of the styles (changed with pywal) something that should not cause any geometry changes so the switch should be almost "transparent".

EDITED: Edited to add that after a quick googling (again) I found that killall -SIGUSR2 waybar does exactly what I want. There is a slight refresh, but at least I do not need a while loop or monitoring changing files. I simply trigger the restart on my script that changes wallpapers!

stratosgear avatar Nov 09 '23 21:11 stratosgear

This is my solution. I have this script in exec-once.

#!/bin/bash

# start waybar if not started
if ! pgrep -x "waybar" > /dev/null; then
	waybar &
fi

# current checksums
current_checksum_config=$(md5sum ~/.config/waybar/config)
current_checksum_style=$(md5sum ~/.config/waybar/style.css)

# loop forever
while true; do
	# new checksums
	new_checksum_config=$(md5sum ~/.config/waybar/config)
	new_checksum_style=$(md5sum ~/.config/waybar/style.css)

	# if checksums are different
	if [ "$current_checksum_config" != "$new_checksum_config" ] || [ "$current_checksum_style" != "$new_checksum_style" ]; then
		# kill waybar
		killall waybar

		# start waybar
		waybar &

		# update checksums
		current_checksum_config=$new_checksum_config
		current_checksum_style=$new_checksum_style
	fi
done

This kills and restarts waybar every time the config changes. The change in config is detected by matching the checksums.

just use this bro

killall -SIGUSR2 waybar make a script to run this with pywal but seems awkward to make a script for few words so maybe put this in along with other scripts if you have for pywal .

ssamin69 avatar Nov 19 '23 06:11 ssamin69

For the above comments, I still want hot restart, so that I don't have to restart the waybar myself (even with the keybinds...). So, the script is still necessary for my use-case.

If you are not lazy like me, killall -SIGUSR2 waybar works awesome if you set a keybinding!

abhiyandhakal avatar Nov 19 '23 06:11 abhiyandhakal

You do not need a separate keybind (although, you "might" have one, it doesn't hurt).

You simply use a killall -SIGUSR2 waybar at the end of any script that you might have that automatically changes things in the background (like rotating wallpapers, updating colors etc). You will not be manually restarting waybar, the script will. In case you manually make changes to the waybar files (editing styles) you could indeed use the keybind to reload.

In any case, what works for me does not imply that works for everyone else, obviously. I just don't see the need for custom scripts when waybar already makes allowances for cases like this!

Enjoy!

stratosgear avatar Nov 19 '23 13:11 stratosgear

Yeah that would be really effective since it doesn't require another infinite loop... I don't remember if I have any such scripts... I will surely do that if I remember any. Thanks!

abhiyandhakal avatar Nov 19 '23 13:11 abhiyandhakal

Esta é a minha solução. Eu tenho esse script em exec-once.

#!/bin/bash

# start waybar if not started
if ! pgrep -x "waybar" > /dev/null; then
	waybar &
fi

# current checksums
current_checksum_config=$(md5sum ~/.config/waybar/config)
current_checksum_style=$(md5sum ~/.config/waybar/style.css)

# loop forever
while true; do
	# new checksums
	new_checksum_config=$(md5sum ~/.config/waybar/config)
	new_checksum_style=$(md5sum ~/.config/waybar/style.css)

	# if checksums are different
	if [ "$current_checksum_config" != "$new_checksum_config" ] || [ "$current_checksum_style" != "$new_checksum_style" ]; then
		# kill waybar
		killall waybar

		# start waybar
		waybar &

		# update checksums
		current_checksum_config=$new_checksum_config
		current_checksum_style=$new_checksum_style
	fi
done

Isso mata e reinicia o waybar toda vez que a configuração é alterada. A mudança na configuração é detectada pela correspondência das somas de verificação.

nice! worked perfectly on hyprland, thank you

dinhokusanagi avatar Dec 10 '23 14:12 dinhokusanagi

@Hubro Can you please explain what does line with trap does? I'm trying to modify your script to use killall -SIGUSR2 waybar

omnigenous avatar Jan 08 '24 07:01 omnigenous

@omnigenous It runs "killall waybar" when the script exits, so waybar doesn't stay open in the background. I don't remember if it's necessary, but it works.

Hubro avatar Jan 09 '24 20:01 Hubro

Doing killall -SIGUSR2 waybar does "refresh" the bar but does not reflect the changes in the config.

annahri avatar Feb 02 '24 02:02 annahri

Hey I was wondering does anyone know if there is anyway i can just refresh the CSS and not the whole bar as that results in it flashing as it re-opens each time.

For context I am trying to add a element that displays the cover art of the currently playing song on MPD. I have come up with this script which just runs at the startup of my PC and symlinks the cover art to a local file where Waybar can access it.

Before anyone says yes i have set "reload_style_on_change": true and that updates the size of the element but strangely not the actual image, it justs remains the same as whatever the image was when waybar started.

Script:

playerctl --follow metadata | while read -r metadata; do
    image_url=$(echo $metadata | grep "mpris:artUrl" | sed -e 's/.*file:\/\///g')
    if [ -n "$image_url" ]; then
        if [[ "$image_url" == *".png" ]]; then
            ln -fs "$image_url" ~/.config/waybar/cover.png
            rm ~/.config/waybar/cover.jpg
        else
            ln -fs "$image_url" ~/.config/waybar/cover.jpg
        fi
        pkill -SIGUSR2 waybar
        echo "Symlink created for $image_url"
    fi
done

And below here is the CSS that makes it work.

  #mpd {
    padding: 5 55px;
    border-radius: 12px;
    background-image: url("cover.jpg"), url("cover.png");
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    color: #FFF;
    margin-top: 8px;
    margin-bottom: 8px;
    margin-right: 2px;
    margin-left: 2px;
    transition: all 0.3s ease;
    font-weight: 900;
  }

Help greatly appreciated.

jasper-clarke avatar Feb 04 '24 10:02 jasper-clarke

If you just want to use killall -SIGUSR2 waybar (where it just works on css updates), you could use a systemd-path. I have this in my ~/.config/systemd/user/

reload-waybar.service

[Unit]
Description=Reload waybar css

[Service]
Type=oneshot
ExecStart=killall -SIGUSR2 waybar
ExecStart=notify-send "Reloaded waybar"

reload-waybar.path

[Unit]
Description=Watch waybar for changes

[Path]
PathModified=%h/.config/waybar/style.css

Then start it with systemctl --user start reload-waybar.path which you could easily put into your wm's autostart or just use systemd to enable it.

You could likely also make a path file for ~/.config/waybar/config and get it to do a ExecStart=killall waybar and a ExecStart=waybar using what I did above.

Even better would probably be to start waybar by writing an ini for it and starting it using systemd. Then you could have ExecStart=systemctl --user restart waybar.service when the path detects a change. Each to their own however :)

tfemby avatar Feb 20 '24 09:02 tfemby