How To: Refresh your status bar in response to a hotkey - Desktop Customization & Workflow
Users browsing this thread: 1 Guest(s)
|
|||
(This post tries to explain how every part works in some detail. If you're just interested in code to copy/paste, look at the end of the post.)
A lot of you are probably using status bars where the actual status bar process just essentially renders the text printed by a script. I know at least both swaybar and i3bar work like that. A simple status script would be this: Code: update() { That works well enough, it shows the current volume of your audio devices and shows the current date. However, it's not great; it only updates once every 5 seconds, which makes it annoying to use to adjust your volume. You could decrease the update interval, but it would be stupid to have a status script running every 100ms when nothing almost ever changes. One decent solution would be to make the status script update after your Code: pactl set-sink-volume @DEFAULT_SINK@ +10% A signal is basically one of the ways a Unix-like kernel (like Linux) can use to communicate with its processes. The kernel sends a SIGSEGV signal ("Segmentation Fault") when the application tries to access memory it's not supposed to, it sends a SIGWINCH signal when the terminal window's dimensions changes, it sends a SIGINT signal when you interrupt the process (such as by hitting ctrl-c in a terminal), it sends a SIGCHLD signal when a child process terminates. Processes can install signal handlers, which is code which is executed when the process receives a signal. Gracefully, the designers of Unix gave us two signals which don't have any semantic meaning in and of themselves; SIGUSR1 and SIGUSR2. The purpose of these signals is to trigger application-specific behavior. We can make the script call the update function again when it receives the SIGUSR1 signal: Code: update() { This does two things: it "traps" the SIGUSR1 signal (this gets rid of the default SIGUSR1 behavior, which is to exit the process), and it replaces the sleep 5 with sleep 5 & wait $!. The meaning of sleep 5 & wait $! is basically: "Spawn a new background child process (sleep 5), and wait for it to exit", but the crucial difference is that the "wait" command is aborted when a signal is received. (The $! variable always refers to the previous background process that was spawned, in this case the sleep process.) So now, when we send our script a SIGUSR1 signal, it will instantly print a new status line. Now we need to run Code: kill -USR1 <our script's process ID> Code: update() { The $$ variable always refers to the PID of the currently executing script. Now, everything that remains is to add Code: kill -USR1 "$(cat "/tmp/status-$USER.pid")" Code: pactl set-sink-volume @DEFAULT_SINK@ +10% && kill -USR1 "$(cat "/tmp/status-$USER.pid")" Here's my status script, which uses something like what's described here to update in response to my hotkeys: https://github.com/mortie/dots/blob/mast.../status.sh |
|||