On X11 I was using Polybar for my status bar and modules. One thing I liked about it was how easy it was to have modules that only appear when relevant. There are certain bar modules that I don’t need visible at all times — for example, I have a script that lets me quickly record a section of my screen. I don’t use this often enough to justify a permanent module for it. I can easily invoke the recording in other ways, but once it starts it would be useful to have a module that displays a “🔴 REC” indicator and lets me stop the recording with a click.

Polybar modules have a hidden parameter and a mechanism for changing module visibility at runtime:

polybar-msg action screen-capture module_show

where screen-capture is a simple custom Polybar module:

[module/screen-capture]
type = custom/text
format = <label>
label = 🔴
hidden = true
click-left = ~/.local/bin/record-screen-area-stop

When I migrated to Wayland I started using Waybar as a Polybar replacement. I generally find it more feature-rich than Polybar, but it doesn’t have an explicit mechanism for toggling module visibility at runtime.

What it does have, however, is support for signals. Each module can be assigned a signal number (SIGRTMIN+n) and when Waybar receives that signal, it triggers the module to refresh. This means you can poke a specific module from the outside rather than relying on polling.

With a little bit of hacking, this mechanism can be used to hide and show a module on demand. The trick is to back the module with a file: when the file exists and has content, the module displays it; when the file is empty or missing, the module produces no output and Waybar hides it. Each time the file changes, you send the signal to tell Waybar to re-read it. Instead of separate start/stop scripts for my screen recording, I now have one script that handles everything:

#!/usr/bin/env bash

geometry="$(slurp)" || exit 0

echo '{"text": "🔴 REC", "class": "recording", "tooltip": "Click to stop"}' > /tmp/waybar-recording
pkill -SIGRTMIN+9 waybar   # wake the module

filename="screen-area-capture-$(date '+%Y-%m-%d-%H:%M:%S').mp4"
wf-recorder -g "$geometry" --file ~/Downloads/"$filename"

# Recording stopped (by on-click sending SIGINT to wf-recorder)
rm /tmp/waybar-recording
pkill -SIGRTMIN+9 waybar   # wake again → empty output → module hides

notify-send "Saved to: $filename"

And the corresponding Waybar module:

"custom/screen-recording": {
    "exec": "cat /tmp/waybar-recording 2>/dev/null",
    "signal": 9,
    "return-type": "json",
    "on-click": "pkill -INT wf-recorder",
    "format": "{}"
},

The same pattern works for any module you want to show conditionally — write to a file when the module should be visible, remove it when it shouldn’t, and signal Waybar each time.