diff --git a/desktopenvs/hyprlua/scripts/presence-detect.sh b/desktopenvs/hyprlua/scripts/presence-detect.sh index 2166685..9a2fb65 100755 --- a/desktopenvs/hyprlua/scripts/presence-detect.sh +++ b/desktopenvs/hyprlua/scripts/presence-detect.sh @@ -63,6 +63,17 @@ _camera_id() { fi } +# True if any process OTHER than this daemon currently holds the real camera +# open — a video call, howdy, etc. `fuser` lists same-user holders without root +# (every camera app runs as us), and we only ever call this when we aren't +# reading the camera ourselves, so any holder is another app. If fuser isn't +# installed we return false: the tick then just tries the camera and the Python +# helper's busy/in-use path (exit 3) still covers an already-held device. +_camera_in_use() { + command -v fuser >/dev/null 2>&1 || return 1 + fuser -s "/dev/video${1}" 2>/dev/null +} + # Prints current CPU-or-RAM usage as a fraction (0..1): the higher of the # core-count-normalized 1-minute load average and the used-RAM fraction. Load # average is a cheap, sampling-free proxy for "CPU busy" — no extra measurement @@ -147,10 +158,21 @@ while true; do fi DEVICE="$(_camera_id)" + now="$(date +%s)" + + # Back-off: if another app already holds the camera (a video call, howdy, + # ...), don't even try to read it — attempting would be pointless (we'd just + # get EBUSY) and a simultaneous open could make the app itself fail. A camera + # in use is proof you're present, so mark presence and wait it out instead. + if _camera_in_use "$DEVICE"; then + LAST_MOTION="$now"; touch "$PRESENCE_FLAG"; _start_inhibit + sleep "$(_next_interval)" + continue + fi + # Run the OpenCV motion detector; stderr suppressed to keep the journal clean. python3 "$PYTHON_DETECT" "$DEVICE" 2>/dev/null rc=$? - now="$(date +%s)" case $rc in # Motion (0) or camera busy/in use (3): user is present. rc=3 means # another app (a video call, howdy) is holding the camera, which is