Only run the clamshell poll while docked, not for every laptop

The reconciliation poll (added in "Fix clamshell display recovery") is a
backstop for lid transitions the Hyprland switch binds can miss across
suspend/resume. But the internal panel is only ever disabled while the
laptop is docked — lid shut with an external monitor active — so the poll
has nothing to reconcile when undocked. Running it 24/7 on every laptop
wakes the CPU every 2s for no reason, which is exactly the case where
battery matters most.

Start the poll when an external monitor is present and stop it when the
last one goes away (driven by the socat monitor-add/remove watch), gated
on omarchy-hw-laptop. Undocked laptops and desktops now never poll; a
docked laptop keeps the 2s recovery poll. Switch the event reader from a
pipe to process substitution so it runs in the main shell and can manage
the poll's lifetime.

Desktop verified: no poll runs even with external monitors attached. The
docked-laptop start/stop path needs a check on real laptop hardware.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-07-20 08:15:09 -07:00
co-authored by Claude Fable 5
parent 63f147ef85
commit d548b730e0
+26 -9
View File
@@ -30,22 +30,39 @@ poll_clamshell_state() {
done
}
# The internal panel is only ever disabled while a laptop is docked (lid shut
# with an external monitor active), so the reconciliation poll only has anything
# to reconcile in that window. Run it while docked, stop it when undocked, and
# never on a machine without a lid. Lid open/close itself is handled by the
# Hyprland "switch:*:Lid Switch" binds; this poll is the recovery backstop for
# drift those binds can miss (e.g. across suspend/resume).
poll_pid=""
sync_poll_state() {
if omarchy-hw-laptop && omarchy-hyprland-monitor-external-active; then
if [[ -z $poll_pid ]] || ! kill -0 "$poll_pid" 2>/dev/null; then
poll_clamshell_state &
poll_pid=$!
fi
elif [[ -n $poll_pid ]]; then
kill "$poll_pid" 2>/dev/null
poll_pid=""
fi
}
sync_clamshell_after_monitor_change
sync_poll_state
# The socat watch below already reconciles clamshell state on monitor
# hotplug. The periodic poll only exists to catch laptop-lid transitions,
# so there is nothing for it to do on a machine that isn't a laptop.
if omarchy-hw-laptop; then
poll_clamshell_state &
fi
socat -U - "UNIX-CONNECT:$SOCKET" | while read -r event; do
# Process substitution (not a pipe) keeps this loop in the main shell, so
# sync_poll_state can start and stop the background poll as monitors come and go.
while read -r event; do
case "$event" in
monitoradded\>\>*|monitoraddedv2\>\>*)
sync_clamshell_after_monitor_change
sync_poll_state
;;
monitorremoved\>\>*|monitorremovedv2\>\>*)
sync_clamshell_after_monitor_change
sync_poll_state
;;
esac
done
done < <(socat -U - "UNIX-CONNECT:$SOCKET")