#!/usr/bin/python

import pyatspi
from gi.repository import Gtk

class Tester:

    def __init__(self, roles):
        self.roles = roles
        self.eventCount = 0

    def start(self):
        pyatspi.Registry.registerKeystrokeListener(
            self.onKeyboardEvent,
            mask=range(255),
            kind=(pyatspi.KEY_PRESSED_EVENT,))
        pyatspi.Registry.registerEventListener(
            self.onPropertyChange, "object:property-change")
        pyatspi.Registry.start()

    def stop(self):
        pyatspi.Registry.deregisterEventListener(
            self.onPropertyChange, "object:property-change")
        pyatspi.Registry.stop()
        Gtk.main_quit()

    def findActiveWindow(self):
        apps = [x for x in pyatspi.Registry.getDesktop(0)]
        apps = filter(lambda x: x.childCount, apps)
        windows = []
        for app in apps:
            windows.extend(child for child in app)
        windows = filter(
            lambda x: x.getState().contains(pyatspi.STATE_ACTIVE), windows)

        return windows

    def drillDown(self, *roles):
        # There should only be one active window, but bugs happen.
        activeWindows = self.findActiveWindow()
        for window in activeWindows:
            print "Drilling down in %s" % window.name
            pyatspi.utils.findAllDescendants(window, roles)

    def onPropertyChange(self, event):
        try:
            role = event.source.getRole()
        except LookupError:
            return

        if not role in self.roles:
            return

        self.eventCount += 1
        print "Accessible Event #%s: %s" % (self.eventCount, event.type)

    def onKeyboardEvent(self, event):
        key = event.event_string
        if key == 'F11':
            self.drillDown()
        if key == 'F12':
            self.stop()
        return key in ['F11', 'F12']

if __name__ == '__main__':
    print "\n  F11: Drill down in the focused app\n  F12: Exit\n"
    tester = Tester([pyatspi.ROLE_PROGRESS_BAR])
    tester.start()
    Gtk.main()
