coderrr

April 20, 2008

Getting idle time in linux

Filed under: c, linux, ruby — Tags: , , — coderrr @ 4:20 pm

For a little alarm prog I’m writing to help myself out with my polyphasic sleep endeavor I needed to get the idle time of an X session, the length of time since the user last used the mouse or keyboard. I searched for a while and there were a few people asking about it but no answers.

So I hacked around and found a simple way to do it in C. This requires you have the Xss (Xscreensaver, not cross site scripting :P) library and includes. (ubuntu: sudo apt-get install libxss-dev)

I wrote this on linux but in theory it should work in any unix X environment with libXss.

#include <X11/extensions/scrnsaver.h>

main() {
  XScreenSaverInfo *info = XScreenSaverAllocInfo();
  Display *display = XOpenDisplay(0);

  XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
  printf("%u ms\n", info->idle);
}

Compile with: gcc -o idle idle.c -lXss

And here’s a simple Ruby wrapper for it using RubyInline:

require 'inline'

class XScreenSaver
  class << self
    inline do |builder|
      builder.add_link_flags '-lXss'
      builder.include '<X11/extensions/scrnsaver.h>'
      builder.c %{
        double idle_time() {
          static Display *display;
          XScreenSaverInfo *info = XScreenSaverAllocInfo();

          if (!display)  display = XOpenDisplay(0);
          if (!display)  return -1;

          XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);

          return info->idle / 1000.0;
        }
      }
    end
  end
end

if __FILE__ == $0
  loop { puts XScreenSaver.idle_time; sleep 0.2 }
end

Does anyone know a better way to do it?

12 Comments »

  1. Nice and useful program. I used it to cobble together some adaptive adjustments to cpufreq_ondemand power saving.

    I have found that a “noisy” mouse can sometimes trip the alarm unintentionally.

    Can you think of a method that measures that the mouse has moved a significant distance, or maybe only responds to keyboard presses and not the mouse?

    Comment by anonymous — July 23, 2008 @ 3:38 pm

  2. Thanks for posting this — it was just what I was looking for! I have some conky scripts that do some intense scraping of websites, and I was thinking that in the spirit of etiquette, I should only have them run when I’m actually at my computer..

    Comment by mike — October 8, 2008 @ 10:32 pm

  3. Some improvements to the C version:

    Display *display = XOpenDisplay(NULL); //empty argument means to use $DISPLAY variable

    //check that X11 is running or else you get a segafult/coredump
    if (display != NULL) {
    XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
    }

    Comment by anonymous--same as #1 — January 7, 2009 @ 4:29 pm

  4. Hey thanks for the comment,

    I agree some error handling would be nice to prevent segfaults.

    I used 0 instead of NULL to prevent the need to #include stdio.h

    Comment by coderrr — January 7, 2009 @ 4:37 pm

  5. Hi, trying to use your program, but having trouble with the library… apt-get doesn’t seem to be very happy with it, lots of unmet dependencies that “are not going to be installed”. apt-get sits there with “open” and “closed” counters slowly going up, something I’ve never seen before, and not sure how to fix.

    Is there a newer version for the library?

    Comment by alan — May 2, 2009 @ 6:49 am

    • nevermind the above comment, the trick is to avoid pasting line numbers into your .c file.

      Comment by alan — May 2, 2009 @ 4:55 pm

  6. [...] One thing I wanted to get working is to ignore when the computer was idle. This program should give you the idle time of the machine, you can use the output to determine whether to take a screenshot – getting idle time in Linux [...]

    Pingback by gorethrasher » Blog Archive » Linux automation - Capturing screenshots — July 17, 2009 @ 8:12 am

  7. Thanks for sharing this! I’d like to use it for sending out alarms when there is network traffic while I’m away.

    Comment by Bogdan — July 23, 2009 @ 3:16 pm

    • cool, i’d be interested in seeing what you make

      Comment by coderrr — July 23, 2009 @ 4:16 pm

  8. The script seems to generally work great, however it doesn’t seem to work when executed from remote console (i.e. ssh console) or, more importantly from cron.

    Is there anyway to have this look for a specific X session … or any X session?

    Thanks in advance.

    Comment by Ray — October 13, 2009 @ 8:07 pm

  9. ‘w’ utility prints idle time, it might be possible to use this info. There are some issues, like grepping only contents of the first column, or converting time in different formats to seconds, or getting idle time for some session, but it should be easy to solve with some scripting. For example, X session may use certain terminal which can be grepped in output of w. I guess ‘w’ uses data from /proc to get idle all this info (on linux), so more info can be obtained there if necessary.

    w | grep username | awk ‘//{print $5;}’

    Comment by Mike — November 18, 2009 @ 3:57 pm

  10. you’re my saver man, you’re my personal jesus christ

    btw, I’ve been trying polyphasic too, for a few months – unfortunately doesn’t work with a full time job

    Comment by comboy — November 23, 2009 @ 2:22 am


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.