Comment déterminer le temps d'inactivité d'affichage à partir de Python sous Windows, Linux et MacOS?

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

Question

Je voudrais savoir combien de temps s'est écoulé depuis que l'utilisateur a appuyé sur une touche ou déplacé la souris - pas seulement dans mon application, mais dans l'ensemble "ordinateur". (i.e. display), afin de deviner s’ils sont toujours sur l’ordinateur et capables d’observer les notifications qui apparaissent à l’écran.

J'aimerais faire cela uniquement à partir de (Py) GTK +, mais je suis disposé à appeler des fonctions spécifiques à la plate-forme. Dans l’idéal, j’aimerais appeler des fonctions qui ont déjà été intégrées à Python, mais si cela n’est pas possible, je ne suis pas au-dessus d’un peu de code C ou ctypes , à condition que je sache ce que je sais. cherche réellement.

Sous Windows, je pense que la fonction que je veux utiliser est GetLastInputInfo , mais cela ne semble pas être enveloppé par pywin32; J'espère que je manque quelque chose.

Était-ce utile?

La solution

Gajim le fait de cette façon sous Windows, OS X et GNU / Linux (et autres * nixes) :

  1. Python En savoir plus inclut le code de détection du temps d’inactivité de Windows, en utilisant GetTickCount avec ctypes );
  2. défenderesse (en utilisant XScreenSaverQueryInfo , était un module C dans les anciennes versions de Gajim);
  3. c heure (utilisation de la propriété système HIDIdleTime ).

Ces liens sont datés de la version 0.12, vous pouvez donc vérifier la source actuelle pour d’autres améliorations et modifications éventuelles.

Autres conseils

Si vous utilisez PyGTK et X11 sous Linux, vous pouvez faire quelque chose comme ceci, basé sur ce que fait 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

L'exemple ci-dessus utilise gdk via ctypes pour pouvoir accéder au spécifique X11. Les API Xscreensaver doivent également être accessibles via ctypes.

Il devrait être assez facile de le porter pour utiliser PyGI et l’introspection.

J'ai obtenu une réponse concernant les clics de souris suggérant d'utiliser pyHook :

Détection de clics de souris dans des fenêtres à l'aide de python

Voici un autre code que j'ai créé pour détecter la position de la souris via des ctypes: http://monkut.webfactional.com/ blog / archive / 2008/10/2 / python-win-mouse-position

Une méthode plus souple pour ce faire consisterait à effectuer une capture d’écran et à comparer tout changement dans les images à l’aide de PIL.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top