Alexays / Waybar

Highly customizable Wayland bar for Sway and Wlroots based compositors. :v: :tada:
MIT License
6.39k stars 696 forks source link

Automatically restart waybar after config change #961

Open Hubro opened 3 years ago

Hubro commented 3 years ago

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.

Markaos commented 3 years ago

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

Hubro commented 3 years ago

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
x10an14 commented 3 years ago

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

hiszd commented 2 years ago

@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`

Hubro commented 2 years ago

@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" &
maLi9n commented 1 year ago

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'

Hubro commented 1 year ago

@maLi9n Triple backticks on separate lines for code blocks.

```
This is a code block
```
HarHarLinks commented 1 year ago

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

abhiyandhakal commented 11 months ago

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.

stratosgear commented 10 months ago

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!

ssamin69 commented 10 months ago

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 .

abhiyandhakal commented 10 months ago

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!

stratosgear commented 10 months ago

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!

abhiyandhakal commented 10 months ago

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!

dinhokusanagi commented 9 months ago

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

omnigenous commented 8 months ago

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

Hubro commented 8 months ago

@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.

annahri commented 8 months ago

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

jasper-clarke commented 7 months ago

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.

tfemby commented 7 months ago

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 :)