33

I need a way to detect mouse/keyboard activity on Linux. Something similar to what any IM program would do. If no activity is detected for, say 5 minutes, it will set your IM status to "I'm not here right now".

Any help towards this is appreciated.

Thanks.

usmanayubsh
  • 173
  • 1
  • 11

7 Answers7

36

Or simply use the command xprintidle which returns the idle time in milliseconds.

It has been packaged for debian based systems. (the source is not available any more on the original site dtek.chalmers.se/~henoch but you can get it at packages.ubuntu.com)

more info on freshmeat.net

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
rosch
  • 667
  • 7
  • 13
  • 1
    `xprintidle` appears unmaintained (upstream). The [last archive of its web page](https://web.archive.org/web/20110404231138/http://www.dtek.chalmers.se/~henoch/text/xprintidle.html) was 2011 and has its latest revision (0.2) dated in 2008. That said, it does appear that the [Debian version](https://packages.qa.debian.org/x/xprintidle.html) is (kind of) getting maintenance. – Adam Katz Apr 15 '15 at 20:51
  • 4
    Some programs are just finished. – Ari Gesher Jul 10 '18 at 21:03
  • Another option is to use python: https://stackoverflow.com/questions/4855823/get-mouse-deltas-using-python-in-linux – rosch Jul 13 '18 at 09:19
  • 1
    very nice utility but is there one for only KEYBOARD activity? – Zibri Nov 06 '18 at 09:00
  • Yes I'm also looking for a way to ignore for example if a video is played. – bob dylan Oct 22 '19 at 10:23
  • Am I positive that it works only under X windows? So not in a server? – xerostomus Jun 06 '22 at 15:48
  • @xerostomus: yes X is necessary, without you'll get the message "couldn't op en display", tested on Ubuntu 20.04. – rosch Jun 15 '22 at 09:09
  • @RoschHaShana Yes, I would have to test: /dev/input/mice or /dev/input/by-path/platform-i8042-serio-0-event-kbd on my server... :-) – xerostomus Jun 16 '22 at 18:14
  • At the moment `xprintidle` on [GitHub](https://github.com/g0hl1n/xprintidle) got last update on June 7, 2022. I tried it on OpenSUSE 15.4 and it worked. – Gianluca Frustagli Sep 30 '22 at 18:24
22

Complete solution : (cut & paste the whole code in a terminal)

cat>/tmp/idletime.c<<EOF
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/scrnsaver.h>

int GetIdleTime () {
        time_t idle_time;
        static XScreenSaverInfo *mit_info;
        Display *display;
        int screen;
        mit_info = XScreenSaverAllocInfo();
        if((display=XOpenDisplay(NULL)) == NULL) { return(-1); }
        screen = DefaultScreen(display);
        XScreenSaverQueryInfo(display, RootWindow(display,screen), mit_info);
        idle_time = (mit_info->idle) / 1000;
        XFree(mit_info);
        XCloseDisplay(display); 
        return idle_time;
}

int main() {
        printf("%d\n", GetIdleTime());
        return 0;
}
EOF

gcc -Wall /tmp/idletime.c -o /tmp/idletime -L/usr/X11R6/lib/ -lX11 -lXext -lXss 
DISPLAY=:0 /tmp/idletime

(the main part is coming from X11::IdleTime perl module)

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • Thank you. For me this was exactly the solution I was looking for :) – nex Jun 01 '13 at 09:21
  • 2
    However your compile line is wrong. It needs to be in this order to work because otherwise the linker will think the libraries are not needed and will drop them if you place your source file after them: gcc idletime.c -o idletime -lX11 -lXext -lXss – nex Jun 01 '13 at 09:38
  • 9
    As the author of the X11::IdleTime module, I'm glad to see people are still getting a use out of it 11 years later. – thelsdj Oct 15 '14 at 18:41
  • 1
    Instead of getting the screen, you can probably use `DefaultRootWindow(display)`; saves a few lines of code. Also the includes for Xlib.h and Xutil.h shouldn't be necessary; `scrnsaver.h` already pulls them in. – Aaron Digulla Feb 11 '15 at 10:59
  • 1
    @thelsdj It's now 18 years and it's still useful. Thank you! – Roger Dahl Dec 16 '21 at 18:03
4

My aproach is to use ad-hoc perl module :

# cpan -i X11::IdleTime; sleep 2; perl -MX11::IdleTime -e 'print GetIdleTime(), $/;'
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
3

Don't poll when there's better methods available.

You don't specify the environment, but since you mention the mouse, I'm going to assume modern X11.

xidle uses the MIT-SCREEN-SAVER extension to determine whether the user is idle or not -- you can use xidle directly, or read its source code to learn how to use the XScreenSaver(3) yourself.

Edit

man 3 XScreenSaver -- just use the idle-reporting/notification portions of it, since there is no more XIDLE extension since X11R6.

ephemient
  • 198,619
  • 38
  • 280
  • 391
2

Try executing who -u -H at the command line. It will tell you who's logged in and how long they've been idle. At least users logged in to a terminal; I don't think it works at all in X. Anyhow, with this information you can tell who's idle or not and take actions appropriately.

If you're in X you could create a script to run as a screen saver or something like that.

GChuf
  • 1,135
  • 1
  • 17
  • 28
Keith Twombley
  • 1,666
  • 1
  • 17
  • 21
  • i'll have to look at this and run it on my linux box when i get a chance. but this looks great. sticks to internal commands. probably a oneliner of _awk_ or _sed_ will do the job. or maybe even _grep_. – franklin Mar 30 '12 at 15:00
  • You can also just use `w` - this prints out minutes and seconds instead of hours and minutes. But they both work for terminal only (they don't monitor activity in X). – GChuf May 27 '20 at 07:29
2

This is an example how to check that an user is idle for 5 minutes using xprintidle and shell script:

#!/bin/sh
idletime=$(xprintidle)
threshold=300000 # 5 min = 5 * 60 * 1000 ms
if [ "$idletime" -gt "$threshold" ]; then
  echo "idle"
fi

xprintidle returns time in milliseconds.

This script does not do any polling or the like. It only executes some code if user is idle and does nothing otherwise.

shitpoet
  • 419
  • 5
  • 11
0

I wrote the wait-while-idle.rb which does the "detecting keyboard, mouse activity in linux" but the other way around — wait until the user's come back.

Yes, sure — it's polling, but I doubt anyone requires performance here.

Planning to catch pranksters sneaking up on my computer with it and a little scripting.

galva
  • 1,253
  • 10
  • 17