Skip to content

smemsh/idled

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Idled

Daemon to detect keypresses or mice movements, Logs idle events and maintains an away-from-keyboard state.

Inputs are registered from anywhere known to the kernel's evdev subsystem (see kernel Documentation/input/input.rst): VTs outside X, psuedo-TTYs in X or Wayland, or any other kernel-known inputs. All mouse movements are known, including from gpm.

idled uses a heuristic match of udev symlink names in /sys/ to determine the keyboard and mouse devices to monitor. It handles added/removed devices by rescanning from start on inotify(7).


Right now, this is used only to tell if we're at the keyboard or not, and generate afk/back output messages and/or logfile. There is a state machine with crude heuristics to determine when the console operator is idle, back, etc (see Configure)

Idle state could inform other things. The plan is to implement configurable scripts / shell commands that will trigger on state changes.

For the moment the output is used with a companion shell loop, like so:

sudo ./idled |& tee fifo & while true
do read timestamp length status
if [[ $timestamp ]]
then if [[ $status == soon ]]
then xflashscreen; length=; fi
rp echo $length $status
else sleep 1; fi; done < fifo

(where rp is an interface to my window manager, and xflashscreen is a sequence of xcalib -invert calls). The loop causes my screen to flash and output the message soon when we're close to idle and afk when we're really idle. There's also an output log of events that looks something like this:

20250717062352   0:00:11 unidle
20250717062516   0:00:00 soon
20250717062526   0:01:34 afk
20250717062840   0:03:13 unidle
20250717063405   0:00:00 soon
20250717063415   0:05:34 afk
20250717063503   0:00:48 unidle
20250717063744   0:00:00 soon
20250717063850   0:00:00 soon
20250717063900   0:03:56 afk
20250717063901   0:00:01 unidle

This helps a lot to reconstruct things when I forget to enter time tracking events! Lots of integration possibilities with the window manager and time tracking tools.

More in the future! TODO


The config file ~/.idlerc configures idled:

unidle_keyboard_count: 3
unidle_keyboard_secs: 10
unidle_mouse_count: 60
unidle_mouse_secs: 7
idle_secs: 30
restart_secs: 3
rescan_secs: 2

In the future we will add variables to configure execve() on idle events.

TODO detail those variables!

When devices are added and removed, idled currently rescans devices, resetting the global idle state machine. We could keep a per-device state in the future and use them to infer the global idle state.

The overhead is very low. It uses an edge triggered kernel event. TODO confirm. Specifically, it uses epoll(7) and inotify(7) mechanisms via ctypes-linked C code (via pypi inotify library at the moment).

Requires: inotify-0.2.10+ | https://pypi.org/project/inotify/

We use inotify lib from pypi, but what we use from it is small and we should just port this into idled. We have to go through unnecessary abstractions and have limitation on sleep time per loop when using th library. Better to do ourselves and remove the dependency TODO

example debug run:

 $ DEBUG=1 sudo idled
debug: enabled
> /home/scott/bin/idled(519)main()
-> process_rcfile()
(Pdb) r
debug: making async task process_events-8154414866282
debug: making async task watch_devices-8154414866292
20241030200522 2s device enumeration sleep...
debug: paths
['/dev/input/by-path/pci-0000:00:14.0-usb-0:4.2:1.1-event-kbd',
 '/dev/input/by-path/platform-i8042-serio-0-event-kbd',
 '/dev/input/by-path/pci-0000:00:14.0-usb-0:4.4:1.0-event-mouse',
 '/dev/input/by-path/pci-0000:00:15.1-platform-i2c_designware.1-event-mouse']
debug: making async task queue_events-8154414866272
debug: making async task queue_events-8154414866272
debug: making async task queue_events-8154414866272
debug: making async task queue_events-8154414866272
20241030200524 monitoring 4 inputs
debug: fd6: type:1, code:30, value:1
debug: fd6: type:0, code:0, value:0
debug: fd6: saw 3, processed 1, key 1, mouse 0
debug: fd6: type:1, code:30, value:0
debug: fd6: type:0, code:0, value:0
debug: fd6: saw 3, processed 1, key 0, mouse 0
debug: fd6: type:1, code:48, value:1
debug: fd6: type:0, code:0, value:0
debug: fd6: saw 3, processed 1, key 1, mouse 0
debug: fd6: type:1, code:48, value:0
debug: fd6: type:0, code:0, value:0
debug: fd6: saw 3, processed 1, key 0, mouse 0
debug: fd8: type:2, code:0, value:1
debug: fd8: type:2, code:1, value:-2
debug: fd8: type:0, code:0, value:0
debug: fd8: saw 3, processed 2, key 0, mouse 2
debug: fd8: type:2, code:1, value:-1
debug: fd8: type:0, code:0, value:0
debug: fd8: saw 2, processed 1, key 0, mouse 1
debug: fd8: type:2, code:1, value:-1
debug: fd8: type:0, code:0, value:0
debug: fd8: saw 2, processed 1, key 0, mouse 1

About

script: idle daemon, tracks keyboard/mouse events and exec stuff on state change

Resources

Stars

Watchers

Forks

Packages

No packages published