The main loop slept on time.sleep(event_deadline()), so a click sat in
the datagram socket until the next 0.5s timer tick woke the loop. That
added up to ~450ms of latency before the click affected state.json, on
top of waybar's 1s re-poll. Replace the sleep with select() on the
socket: select returns the moment a datagram arrives, so the loop
drains and writes the click within milliseconds (measured 29ms) while
still bounding idle sleep by the next timer deadline. Rotation cadence
and click-during-fetch behavior are unchanged.
The waybar custom-module interval stays 1: fractional intervals below
1s break custom modules (Waybar #4894 turns 0.5 into a 1ms busy loop),
so the 0-1s re-poll is the floor and not safely tunable.
The omarchy matte-black theme file
(~/.config/omarchy/current/theme/waybar.css) is empty, so @background
and @foreground are undefined GTK variables. A tooltip rule using
background-color: @background resolves to nothing, so the popover
rendered transparent. Replace the theme variables with the literal
matte-black colors (#121212 / #bebebe) from colors.toml so the
popover is dark even though the theme file is empty. Scoped to the
tooltip; the bar background is left unchanged.
The native tooltip never rendered. Two waybar quirks stacked:
1. custom/ocd had tooltip-format set. For a custom module with
return-type json, a tooltip-format overrides the JSON tooltip field
and waybar falls back to the label text (Waybar #3022). So the
popover showed the single rotating account label instead of all
accounts. Remove tooltip-format; waybar now uses the daemon's
JSON tooltip field.
2. The daemon joined tooltip lines with newline. waybar custom
modules break on newline (the tooltip vanishes; Waybar #3153). The
wiki says to use carriage return instead. Switch the separator to
\r.
Reformat the tooltip so each limit (5h/1w/1m) is on its own row under
the account, with a blank row between accounts for a bigger gap, as
requested.
Add a dark tooltip background. waybar scopes tooltip CSS globally
(wiki / PR #4930): style all bar tooltips with the existing theme
dark color @background/@foreground so the popover matches the bar
instead of rendering backgroundless.
Two root causes shared one symptom: the waybar module froze after a
click and needed a waybar restart to recover.
1. oc-waybar-ctl used socat's UNIX-SENDTO, a bidirectional relay that
can block on a datagram socket. waybar runs the click command on
its per-module event thread and stops updating the module until the
command returns, so a hung socat froze the module. Replace the
socat/nc chain with a bounded python3 sendto (2s timeout). python3
is guaranteed present since the daemon needs it.
2. The daemon ran oc raw json with a blocking subprocess.run on the
main loop, so a slow network fetch (up to 60s) stalled the 5s
rotation and queued clicks. Move fetch_ocd to a worker thread; the
main loop adopts the result when it lands and never blocks. Rotation
and click draining stay live during a fetch.
Reconnect after a daemon restart now works because the click helper no
longer wedges waybar's event thread; the module's interval-1 cat
re-reads state.json as soon as the new daemon rewrites it (verified:
state.json returns within 1s).
Notes the two-way relationship: scripts are symlinked (one source of
truth), but the config/ snippets are inserted by hand into existing
omarchy files and must be edited in both places to stay in sync.