我想知道自用户上次按键或移动鼠标以来已经有多长时间 - 不仅在我的应用程序中,而且在整个"计算机"(即显示器)上,以便猜测它们是否仍在电脑,能够观察屏幕上弹出的通知.
我想纯粹从(Py)GTK +这样做,但我可以调用特定于平台的函数.理想情况下,我想调用已经包含在Python中的函数,但是如果不可能的话,我不会超过一点C或ctypes
代码,只要我知道我实际上在寻找什么.
在Windows上我认为我想要的功能是GetLastInputInfo
,但这似乎并没有被pywin32包装; 我希望我错过了一些东西.
Gajim在Windows,OS X和GNU/Linux(以及其他*nixes)上这样做:
Python包装器模块(还包括Windows空闲时间检测代码,GetTickCount
用于ctypes
);
基于Ctypes的模块获取X11空闲时间(使用XScreenSaverQueryInfo
,是旧的Gajim版本中的C模块);
C模块获取OS X空闲时间(使用HIDIdleTime
系统属性).
这些链接是相当日期的0.12版本,因此您可能需要检查当前来源以获得可能的进一步改进和更改.
如果你在Linux上使用PyGTK和X11,你可以做这样的事情,这是基于Pidgin的作用:
import ctypes import ctypes.util import platform class XScreenSaverInfo(ctypes.Structure): _fields_ = [('window', ctypes.c_long), ('state', ctypes.c_int), ('kind', ctypes.c_int), ('til_or_since', ctypes.c_ulong), ('idle', ctypes.c_ulong), ('eventMask', ctypes.c_ulong)] class IdleXScreenSaver(object): def __init__(self): self.xss = self._get_library('Xss') self.gdk = self._get_library('gdk-x11-2.0') self.gdk.gdk_display_get_default.restype = ctypes.c_void_p # GDK_DISPLAY_XDISPLAY expands to gdk_x11_display_get_xdisplay self.gdk.gdk_x11_display_get_xdisplay.restype = ctypes.c_void_p self.gdk.gdk_x11_display_get_xdisplay.argtypes = [ctypes.c_void_p] # GDK_ROOT_WINDOW expands to gdk_x11_get_default_root_xwindow self.gdk.gdk_x11_get_default_root_xwindow.restype = ctypes.c_void_p self.xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo) self.xss.XScreenSaverQueryExtension.restype = ctypes.c_int self.xss.XScreenSaverQueryExtension.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)] self.xss.XScreenSaverQueryInfo.restype = ctypes.c_int self.xss.XScreenSaverQueryInfo.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.POINTER(XScreenSaverInfo)] # gtk_init() must have been called for this to work import gtk gtk # pyflakes # has_extension = XScreenSaverQueryExtension(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), # &event_base, &error_base); event_base = ctypes.c_int() error_base = ctypes.c_int() gtk_display = self.gdk.gdk_display_get_default() self.dpy = self.gdk.gdk_x11_display_get_xdisplay(gtk_display) available = self.xss.XScreenSaverQueryExtension(self.dpy, ctypes.byref(event_base), ctypes.byref(error_base)) if available == 1: self.xss_info = self.xss.XScreenSaverAllocInfo() else: self.xss_info = None def _get_library(self, libname): path = ctypes.util.find_library(libname) if not path: raise ImportError('Could not find library "%s"' % (libname, )) lib = ctypes.cdll.LoadLibrary(path) assert lib return lib def get_idle(self): if not self.xss_info: return 0 # XScreenSaverQueryInfo(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), # GDK_ROOT_WINDOW(), mit_info); drawable = self.gdk.gdk_x11_get_default_root_xwindow() self.xss.XScreenSaverQueryInfo(self.dpy, drawable, self.xss_info) # return (mit_info->idle) / 1000; return self.xss_info.contents.idle / 1000
上面的示例使用gdk via ctypes来访问特定的X11.Xscreensaver API也需要通过ctypes访问.
将它移植到使用PyGI和内省应该很容易.