1

The following Python code is supposed to print out how much time has passed since the last user activity (mouse movement, keyboard keys pressed)

from ctypes import Structure, windll, c_uint, sizeof, byref
import time

class LASTINPUTINFO(Structure):
    _fields_ = [
        ('cbSize', c_uint),
        ('dwTime', c_uint),
    ]

def get_idle_duration():
    lastInputInfo = LASTINPUTINFO()
    lastInputInfo.cbSize = sizeof(lastInputInfo)
    windll.user32.GetLastInputInfo(byref(lastInputInfo))
    millis = windll.kernel32.GetTickCount() - lastInputInfo.dwTime
    return millis / 1000.0



for i in range(10):
    print get_idle_duration()
    time.sleep(1)

Problem: However, running this script prints out the following when no user input is being made during the execution of the script:

0.109
0.047
0.203
0.124
0.093
0.031
0.187
0.125
0.062
0.0

Why does the idle time printed out not continue to increase, but rather looks like it is being reset continuously?

J.J. Hakala
  • 6,136
  • 6
  • 27
  • 61
Nyxynyx
  • 61,411
  • 155
  • 482
  • 830
  • This may be related - http://stackoverflow.com/questions/26327150/getlastinputinfo-does-not-correctly-work – kmaork May 15 '16 at 20:43
  • Hmm, that's interesting. Check the second sentence of the remarks [GetLastInputInfo function](https://msdn.microsoft.com/de-de/library/windows/desktop/ms646302(v=vs.85).aspx). It seems, that it works [here](http://stackoverflow.com/questions/911856/detecting-idle-time-using-python) well. – Darius May 15 '16 at 20:43
  • @DariusM. Does that mean `GetLastInputInfo` function cannot reliably give us the idle time? If so, any alternatives? – Nyxynyx May 15 '16 at 20:51
  • I'm not familiar with the os lifecycle of Windows, so it was just a hint. Nevertheless, maybe [this implementation based on GetLastInputInfo](http://code.activestate.com/recipes/576786-detect-when-system-is-idle/) will work. – Darius May 15 '16 at 21:03
  • You can also try to track events with win32 – Cosinux May 15 '16 at 22:27
  • Using `windll` is problematic because it's global. Instead use `kernel32 = WinDLL('kernel32', use_last_error=True)` and `user32 = WinDLL('user32', use_last_error=True)`. Also, the default result type is a signed `c_int`, so you have to set `kernel32.GetTickCount.restype = c_uint`. This enables the full unsigned range of 49.7 days on the tick count. As to your problem, it may be related to the fact that the `GetLastInputInfo` tick count isn't guaranteed to be monotonic. – Eryk Sun May 16 '16 at 04:55

0 Answers0