Как определить время простоя дисплея из Python в Windows, Linux и MacOS?
Вопрос
Я хотел бы знать, сколько времени прошло с тех пор, как пользователь последний раз нажимал клавишу или перемещал мышь - не только в моем приложении, но и на всем "компьютере" (то есть дисплей), чтобы угадать, находятся ли они еще за компьютером и могут ли они наблюдать уведомления, появляющиеся на экране.
Я хотел бы сделать это исключительно из (Py) GTK +, но я подхожу для вызова платформо-зависимых функций. В идеале я хотел бы вызывать функции, которые уже были перенесены из Python, но если это невозможно, я не разбираюсь в коде C или ctypes
, если я знаю, что я на самом деле ищу.
В Windows я думаю, что мне нужна функция GetLastInputInfo
, но это не похоже на завершение pywin32; Я надеюсь, что что-то упустил.
Решение
Gajim делает это таким образом в Windows, OS X и GNU / Linux (и других * nixes)
<Ол> GetTickCount
с ctypes
); XScreenSaverQueryInfo
, в старых версиях Gajim был модуль C); HIDIdleTime
). Эти ссылки имеют весьма устаревшую версию 0.12, поэтому вы можете проверить текущий источник на предмет возможных дальнейших улучшений и изменений.
Другие советы
Если вы используете PyGTK и X11 в Linux, вы можете сделать что-то вроде этого, основываясь на том, что делает 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
В приведенном выше примере для доступа к конкретному X11 используется gdk через ctypes. К API Xscreensaver также нужно обращаться через ctypes.
Должно быть довольно легко портировать его, чтобы использовать PyGI и самоанализ.
Я получил ответ о щелчках мышью, предлагающий использовать pyHook :
Обнаружение щелчков мыши в окнах с помощью Python
Вот еще один код, который я сделал для определения положения мыши с помощью ctypes: http://monkut.webfactional.com/ блог / Архив / 2008/10/2 / питон выигрыша мышиного положение
Более обходным методом для этого будет захват экрана и сравнение любых изменений в изображениях с помощью PIL.
http: / /www.wellho.net/forum/Programming-in-Python-and-Ruby/Python-Imaging-Library-PIL.html р>