Como posso determinar o tempo de apresentação ociosa de Python no Windows, Linux e MacOS?

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

Pergunta

Gostaria de saber quanto tempo passou desde o último usuário pressionar uma tecla ou mover o mouse - e não apenas na minha candidatura, mas em toda a "computador" (ie visor), a fim de adivinhar se eles são ainda no computador e capaz de observar notificações que aparecem na tela.

Eu gostaria de fazer isso puramente de (Py) GTK +, mas eu sou passível de chamar funções específicas de plataforma. Idealmente, eu gostaria de chamar funções que já foram embrulhadas de Python, mas se isso não for possível, não estou acima de um pouco de código C ou ctypes, enquanto eu sei o que estou realmente procurando.

No Windows eu acho que a função que eu quero é GetLastInputInfo , mas que não parece ser envolvido por pywin32; Espero que eu estou faltando alguma coisa.

Foi útil?

Solução

Gajim faz isso dessa maneira no Windows, OS X e GNU / Linux (e outros nixes *) :

  1. Python invólucro módulo (também inclui código de detecção do Windows tempo ocioso, usando GetTickCount com ctypes);
  2. módulo para obter X11 tempo ocioso Ctypes baseada (usando XScreenSaverQueryInfo, foi um módulo C em versões antigas Gajim);
  3. C módulo para obter OS X ocioso tempo (usando propriedade do sistema HIDIdleTime).

Esses links são bastante datada 0,12 versão, então você pode querer verificar fonte de corrente para possíveis novas melhorias e mudanças.

Outras dicas

Se você usar PyGTK e X11 no Linux, você pode fazer algo como este, que é baseado no que Pidgin faz:

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

O exemplo acima usa GDK via ctypes para ser capaz de acessar o específica X11. Xscreensaver APIs também precisam ser acessado através ctypes.

Deve ser muito fácil para a porta-lo para usar pygi e introspecção.

Eu tenho uma resposta sobre cliques do mouse sugerindo usar pyHook :

Detectando mouse clica em janelas usando python

Eis algum outro código que eu fiz para detectar mouse posição através ctypes: http://monkut.webfactional.com/ blogue / Arquivo / 2008/10/2 / python-win-rato-position

A mais-redonda sobre método para alcançar este objetivo seria através de captura de tela e comparando qualquer mudança em imagens usando PIL.

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top