Wake on click instantly instead of the next 0.5s tick

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.
This commit is contained in:
ocpway 2026-07-30 05:03:11 +03:00
parent 02f0ce1d7c
commit a9254fc70e

View File

@ -16,6 +16,7 @@
import json
import os
import re
import select
import signal
import socket
import subprocess
@ -451,7 +452,17 @@ def main():
d.maybe_tick()
d.drain_socket()
d.render_and_write()
time.sleep(d.event_deadline())
# Sleep until the next tick OR a click, whichever is first.
# select on the socket lets a click wake the loop at once instead
# of waiting up to TICK_SECS for the next timer tick.
timeout = d.event_deadline()
if d.sock is not None:
try:
select.select([d.sock], [], [], timeout)
except (OSError, ValueError):
time.sleep(timeout)
else:
time.sleep(timeout)
d.stop()