2008-10-19 5 views
15

Я хотел бы знать, сколько времени прошло с тех пор, как пользователь последний раз нажал клавишу или переместил мышь - не только в мое приложение, но и на весь «компьютер» (т.е. дисплей), чтобы угадать, все ли они все еще на компьютере и в состоянии наблюдать уведомления, которые появляются на экране.Как определить время простоя дисплея с Python в Windows, Linux и MacOS?

Я хотел бы сделать это исключительно из (Py) GTK +, но я могу назвать функции, специфичные для платформы. В идеале я бы хотел вызвать функции, которые уже были завернуты из Python, но если это невозможно, я не над небольшим количеством кода C или ctypes, если знаю, что я на самом деле ищу.

В Windows я думаю, что функция, которую я хочу, это GetLastInputInfo, но это, кажется, не обернуто pywin32; Надеюсь, я что-то упустил.

ответ

11

Gajim делает это таким образом на Windows, OS X и GNU/Linux (и другие * nixes):

  1. Python wrapper module (также включает в себя код обнаружения Windows, время простоя, используя GetTickCount с ctypes);
  2. Ctypes-based module to get X11 idle time (с использованием XScreenSaverQueryInfo, был модулем C в старых версиях Гаджима);
  3. C module to get OS X idle time (используя HIDIdleTime system свойство).

Эти ссылки должны быть датированы версией 0.12, поэтому вы можете проверить текущий источник на предмет возможных дальнейших улучшений и изменений.

2

я получил ответ о щелчками мыши предполагая использовать pyHook:

Detecting Mouse clicks in windows using python

Вот какой-то другой код, который я сделал для обнаружения мыши-позиции через ctypes: http://monkut.webfactional.com/blog/archive/2008/10/2/python-win-mouse-position

Более округло о методе достижения этого было бы через захват экрана и сравнение любого изменения изображений с использованием PIL.

http://www.wellho.net/forum/Programming-in-Python-and-Ruby/Python-Imaging-Library-PIL.html

5

При использовании 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 

В приведенном выше примере использует ГДК через ctypes, чтобы иметь возможность получить доступ к X11 конкретных , API-интерфейсы Xscreensaver также должны быть доступны через ctypes.

Должно быть довольно легко перенести его, чтобы использовать PyGI и интроспекцию.

+0

Возможно, было бы интересно перенести эти интерфейсы `ctypes` на https://pypi.python.org/pypi/cffi. – Glyph 2013-05-28 04:38:53

 Смежные вопросы

  • Нет связанных вопросов^_^