Как определить время простоя дисплея из Python в Windows, Linux и MacOS?

StackOverflow https://stackoverflow.com/questions/217157

Вопрос

Я хотел бы знать, сколько времени прошло с тех пор, как пользователь последний раз нажимал клавишу или перемещал мышь - не только в моем приложении, но и на всем "компьютере" (то есть дисплей), чтобы угадать, находятся ли они еще за компьютером и могут ли они наблюдать уведомления, появляющиеся на экране.

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

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

Это было полезно?

Решение

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

<Ол>
  • также оболочка Python (модуль оболочки) включает код обнаружения простоя Windows, используя GetTickCount с ctypes );
  • модуль на основе Xty11 для получения X (используя XScreenSaverQueryInfo , в старых версиях Gajim был модуль C);
  • модуль Noreferrer"> для noreferrer"> Си время (используется системное свойство 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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top