aboutsummaryrefslogtreecommitdiffstats
path: root/build/scripts-2.7/sniff
diff options
context:
space:
mode:
Diffstat (limited to 'build/scripts-2.7/sniff')
-rwxr-xr-xbuild/scripts-2.7/sniff798
1 files changed, 798 insertions, 0 deletions
diff --git a/build/scripts-2.7/sniff b/build/scripts-2.7/sniff
new file mode 100755
index 00000000000..f55adfa9663
--- /dev/null
+++ b/build/scripts-2.7/sniff
@@ -0,0 +1,798 @@
+#!/usr/bin/python
+# -*- coding: UTF8 -*-
+"""
+http://en.wikipedia.org/wiki/Model-view-controller
+
+The SniffApp class sets up all of sniff's widgets.
+
+Data storage is handled by the SniffModel class.
+There is no SniffView class; we just use a GtkTreeView.
+Data display is handled by the SniffController class.
+"""
+import gi
+gi.require_version('Gtk', '3.0')
+gi.require_version('Gdk', '3.0')
+import sys
+from dogtail.config import config
+
+if config.checkForA11y:
+ from dogtail.utils import checkForA11yInteractively
+ checkForA11yInteractively()
+
+config.logDebugToFile = False
+config.childrenLimit = 100000
+
+import pyatspi
+import Accessibility
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Gio
+from gi.repository import GdkPixbuf
+from gi.repository import GObject
+from gi.repository import GLib
+
+builder = Gtk.Builder()
+
+
+class SniffApp(object):
+ appName = 'Sniff'
+ appAuthors = ['Zack Cerza <zcerza@redhat.com>',
+ 'David Malcolm <dmalcolm@redhat.com']
+
+ def __init__(self):
+ self.builder = builder
+ import os
+ if os.path.exists('sniff.ui'):
+ self.builder.add_from_file('sniff.ui')
+ else:
+ import os
+ path = os.path.abspath(
+ os.path.join(__file__, os.path.pardir, os.path.pardir))
+ if path is '/': # in case the path is /bin/sniff
+ path = '/usr'
+ self.builder.add_from_file(path +
+ '/share/dogtail/glade/sniff.ui')
+ self.app = self.builder.get_object(self.appName)
+ try:
+ self.app.set_icon_from_file('../icons/dogtail-head.svg')
+ except Exception:
+ import os
+ path = os.path.abspath(
+ os.path.join(__file__, os.path.pardir, os.path.pardir))
+ if path is '/':
+ path = '/usr'
+ self.app.set_icon_from_file(os.path.join(path,
+ 'share/icons/hicolor/scalable/apps/dogtail-head.svg'))
+ self.setUpWidgets()
+ self.connectSignals()
+ self.app.show_all()
+ Gtk.main()
+
+ def setUpWidgets(self):
+ self.quit1 = self.builder.get_object('quit1')
+ self.expand_all1 = self.builder.get_object('expand_all1')
+ self.collapse_all1 = self.builder.get_object('collapse_all1')
+ self.about1 = self.builder.get_object('about1')
+ self.refreshMenuItem = self.builder.get_object('refresh1')
+ self.autoRefreshMenuItem = self.builder.get_object('autorefresh')
+ self.setRootMenuItem = self.builder.get_object('setRootMenuItem')
+ self.unsetRootMenuItem = self.builder.get_object('unsetRootMenuItem')
+ self.about = None
+
+ self.tree = SniffController()
+
+ def connectSignals(self):
+ self.app.connect('delete_event', self.quit, self)
+ self.quit1.connect('activate', self.quit, self)
+ self.expand_all1.connect('activate', self.tree.expandAll, True)
+ self.collapse_all1.connect('activate', self.tree.expandAll, False)
+ self.about1.connect('activate', self.showAbout, self)
+ self.refreshMenuItem.connect('activate', self.tree.refresh)
+ self.autoRefreshMenuItem.connect(
+ 'toggled', self.tree.toggleAutoRefresh)
+ self.setRootMenuItem.connect('activate', self.tree.changeRoot, True)
+ self.unsetRootMenuItem.connect('activate', self.tree.changeRoot, False)
+
+ self.setStartupAutoRefresh()
+
+ def setStartupAutoRefresh(self):
+ import os
+ if not os.path.exists('/tmp/sniff_refresh.lock'):
+ self.autoRefreshMenuItem.set_active(True)
+
+ def showAbout(self, *args):
+ if not self.about:
+ self.about = Gtk.AboutDialog()
+ self.about.set_name(self.appName)
+ self.about.set_authors(self.appAuthors)
+ self.about.set_comments('Explore your desktop with Dogtail')
+ self.about.set_website('http://people.redhat.com/zcerza/dogtail/')
+ self.about.connect("response", self.hideAbout)
+ self.about.show_all()
+
+ def hideAbout(self, window, response):
+ if response == Gtk.ResponseType.CANCEL:
+ window.hide()
+
+ def quit(self, *args):
+ Gtk.main_quit()
+
+
+class SniffController(object):
+ invalidBufferCallbackID = None
+
+ def __init__(self):
+ self.builder = builder
+ self.nameTextLabel = self.builder.get_object('nameTextLabel')
+ self.nameTextLabel.set_text('')
+ self.roleNameTextLabel = self.builder.get_object('roleNameTextLabel')
+ self.roleNameTextLabel.set_text('')
+ self.descTextLabel = self.builder.get_object('descTextLabel')
+ self.descTextLabel.set_text('')
+ self.actionsTextLabel = self.builder.get_object('actionsTextLabel')
+ self.actionsTextLabel.set_text('')
+ self.textTextView = self.builder.get_object('textTextView')
+ self.textTextViewBufferCallbackID = self.invalidBufferCallbackID
+ self.textTextView.set_sensitive(False)
+ self.textTextView.get_buffer().set_text('')
+ self.labelerButton = self.builder.get_object('labelerButton')
+ self.labelerButton.set_sensitive(False)
+ self.labeleeButton = self.builder.get_object('labeleeButton')
+ self.labeleeButton.set_sensitive(False)
+ self.stateView = self.builder.get_object('stateTreeView')
+ self.highlight1 = self.builder.get_object('highlight1')
+ self.autorefresh = self.builder.get_object('autorefresh')
+ self.stateModel = StateModel()
+ self.setUpStateView()
+ self.treeView = self.builder.get_object('treeTreeView')
+ self.treeSelection = self.treeView.get_selection()
+ self.treeModel = SniffModel()
+ self.setUpTreeView()
+ self.connectSignals()
+ self.refresh()
+
+ def setUpStateView(self):
+ self.stateView.set_model(self.stateModel)
+ cellRenderer = Gtk.CellRendererText()
+ col = Gtk.TreeViewColumn('Present States', cellRenderer,
+ text=self.stateModel.stateColumn)
+ col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ self.stateView.insert_column(col, -1)
+
+ def setUpTreeView(self):
+ self.treeView.set_enable_tree_lines(True)
+
+ self.treeView.set_model(self.treeModel)
+
+ col = Gtk.TreeViewColumn()
+ cellRenderer = Gtk.CellRendererPixbuf()
+ col.pack_start(cellRenderer, expand=False)
+ col.add_attribute(cellRenderer, 'pixbuf', self.treeModel.pixbufColumn)
+
+ cellRenderer = Gtk.CellRendererText()
+ col.pack_end(cellRenderer, expand=False)
+ col.add_attribute(cellRenderer, 'text', self.treeModel.nameColumn)
+
+ col.set_title('Name')
+
+ self.treeView.insert_column(col, -1)
+
+ for column in self.treeView.get_columns():
+ column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ column.set_resizable(True)
+ self.treeView.show()
+ path = 0
+ self.treeView.expand_all()
+ #self.rowExpanded(self.treeView, self.treeModel.get_iter(path), path)
+
+ def changeRoot(self, menuItem, toSelected=True, *args):
+ if toSelected:
+ node = self.getSelectedNode()
+ if toSelected and node:
+ self.treeModel.changeRoot(node)
+ elif not toSelected:
+ self.treeModel.reset()
+ else:
+ return
+ self.refresh(refreshModel=False)
+
+ def refresh(self, menuItem=None, refreshModel=True, *args):
+ if refreshModel:
+ self.treeModel.refresh()
+ rootPath = self.treeModel.get_path(self.treeModel.get_iter_first())
+ self.treeView.expand_all()
+ self.treeView.expand_row(rootPath, False)
+
+ def toggleAutoRefresh(self, *args):
+ if self.autorefresh.get_active() is True:
+ pyatspi.Registry.registerEventListener(self.treeModel.nodeChanged,
+ 'object:children-changed')
+ pyatspi.Registry.registerEventListener(self.treeModel.nodeChanged,
+ 'object:property-change:accessible-name')
+ pyatspi.Registry.registerEventListener(self.treeModel.nodeChanged,
+ 'object:property-change:accessible-state')
+ pyatspi.Registry.registerEventListener(self.treeModel.nodeChanged,
+ 'object:state-changed')
+ self.refresh()
+ else:
+ pyatspi.Registry.deregisterEventListener(
+ self.treeModel.nodeChanged,
+ 'object:children-changed')
+ pyatspi.Registry.deregisterEventListener(
+ self.treeModel.nodeChanged,
+ 'object:property-change:accessible-name')
+ pyatspi.Registry.deregisterEventListener(
+ self.treeModel.nodeChanged,
+ 'object:property-change:accessible-state')
+ pyatspi.Registry.deregisterEventListener(
+ self.treeModel.nodeChanged,
+ 'object:state-changed')
+
+ def connectSignals(self):
+ self.labelerButton.connect('clicked', self.showRelationTarget,
+ 'labeler')
+ self.labeleeButton.connect('clicked', self.showRelationTarget,
+ 'labelee')
+ self.treeView.connect('button-press-event', self.buttonPress)
+ self.treeView.connect('key-press-event', self.keyPress)
+ self.treeView.connect('row-expanded', self.rowExpanded, self.treeModel)
+ self.treeView.connect('row-collapsed', self.rowCollapsed)
+ self.treeSelection.connect('changed', self.selectionChanged)
+ self.refresh()
+
+ def selectionChanged(self, treeSelection):
+ node = self.getSelectedNode()
+ if node:
+ self.setUpBottomPane(node)
+ if self.highlight1.get_active() is True:
+ node.blink()
+
+ def getSelectedNode(self):
+ (store, iter) = self.treeView.get_selection().get_selected()
+ if not iter:
+ node = None
+ else:
+ node = self.treeModel.getNode(iter)
+ return node
+
+ def expandAll(self, widget, *args):
+ if args[0] == True:
+ self.treeView.expand_all()
+ elif args[0] == False:
+ self.treeView.collapse_all()
+
+ def rowExpanded(self, treeview, iter, path, *userParams):
+ row = self.treeModel[path]
+ childRows = row.iterchildren()
+ while True:
+ try:
+ childRow = childRows.next()
+ self.treeModel.populateChildren(childRow.iter)
+ except StopIteration:
+ break
+
+ def rowCollapsed(self, treeview, iter, path, *userParams):
+ row = self.treeModel[path]
+ childRows = row.iterchildren()
+ try:
+ while True:
+ childRow = childRows.next()
+ grandChildRows = childRow.iterchildren()
+ try:
+ while True:
+ grandChildRow = grandChildRows.next()
+ self.treeModel.remove(grandChildRow.iter)
+ except StopIteration:
+ pass
+ except StopIteration:
+ pass
+
+ def menuItemActivate(self, menuItem, *userParams):
+ if len(userParams) < 2:
+ return
+ method = userParams[0]
+ arg = userParams[1]
+ method(arg)
+
+ def keyPress(self, widget, event, *userParams):
+ if event.keyval == Gdk.KEY_Return:
+ path = self.treeSelection.get_selected_rows()[1][0]
+ if self.treeView.row_expanded(path):
+ self.treeView.collapse_row(path)
+ else:
+ self.treeView.expand_row(path, False)
+ return False
+
+ def buttonPress(self, widget, event, *userParams):
+ try:
+ path, treeViewCol, relX, relY = \
+ self.treeView.get_path_at_pos(int(event.x),
+ int(event.y))
+ except TypeError:
+ return
+ node = self.treeModel.getNode(self.treeModel.get_iter(path))
+ if node == None:
+ return
+
+ if event.button == 3:
+ self.menu = Gtk.Menu()
+ menuItem = None
+ if node.actions:
+ for action in node.actions.keys():
+ menuItem = Gtk.MenuItem(action.capitalize())
+ menuItem.connect(
+ 'activate', self.menuItemActivate, node.doActionNamed, action)
+ menuItem.show()
+ self.menu.append(menuItem)
+ if not menuItem:
+ return
+ self.menu.show_all()
+ self.menu.popup(None, None, None, None, event.button, event.time)
+
+ def showRelationTarget(self, button, relation, *args):
+ target = getattr(self.getSelectedNode(), relation)
+ if not target:
+ return
+ try:
+ target.blink()
+ except:
+ import traceback
+ traceback.print_exc()
+
+ def setUpBottomPane(self, node):
+ """Generic code for setting up the table under the TreeView"""
+ if node == None:
+ return
+ self.nameTextLabel.set_text(node.name)
+ self.roleNameTextLabel.set_text(node.roleName)
+ self.descTextLabel.set_text(node.description)
+ str = ''
+ if node.actions:
+ str = ' '.join(node.actions.keys())
+ self.actionsTextLabel.set_text(str)
+
+ # Have we connected this signal yet?
+ # If so, disconnect it before proceeding.
+ if self.textTextViewBufferCallbackID != self.invalidBufferCallbackID:
+ self.textTextView.get_buffer().disconnect(
+ self.textTextViewBufferCallbackID)
+ self.textTextViewBufferCallbackID = self.invalidBufferCallbackID
+
+ if node.text is not None:
+ buffer = self.textTextView.get_buffer()
+ buffer.set_text(node.text)
+ try:
+ node.queryEditableText()
+ # Remember the handler ID of this connection.
+ self.textTextView.set_sensitive(True)
+ self.textTextViewBufferCallbackID = \
+ buffer.connect('changed', self.changeText, node)
+ except NotImplementedError:
+ self.textTextView.set_sensitive(False)
+ else:
+ self.textTextView.get_buffer().set_text('')
+ self.textTextView.set_sensitive(False)
+
+ if node.labeler and not node.labeler.dead:
+ self.labelerButton.set_sensitive(True)
+ self.labelerButton.show()
+ # elif node.labeler and node.labeler.dead:
+ # print "labeler is dead", node.labeler
+ else:
+ self.labelerButton.set_sensitive(False)
+ self.labelerButton.hide()
+ if node.labelee and not node.labelee.dead:
+ self.labeleeButton.set_sensitive(True)
+ self.labeleeButton.show()
+ # elif node.labelee and node.labelee.dead:
+ # print "labelee is dead", node.labelee
+ else:
+ self.labeleeButton.set_sensitive(False)
+ self.labeleeButton.hide()
+
+ self.stateModel.setNode(node)
+
+ def changeText(self, textBuffer, node):
+ if node == None:
+ return
+ node.text = textBuffer.get_text(textBuffer.get_start_iter(),
+ textBuffer.get_end_iter())
+
+
+class SniffModel(Gtk.TreeStore):
+ nodeColumn = 0
+ nameColumn = 1
+ pixbufColumn = 2
+ eventQueue = []
+ cache = {}
+
+ def __init__(self):
+ self.builder = builder
+ #self.autorefresh = self.builder.get_object('autorefresh')
+ Gtk.TreeStore.__init__(self, GObject.TYPE_PYOBJECT,
+ GObject.TYPE_STRING, GdkPixbuf.Pixbuf)
+ root = pyatspi.Registry.getDesktop(0)
+ self.rootNode = self.initialRootNode = root
+ self.appendAndPopulate(None, self.rootNode)
+
+ def __contains__(self, item):
+ from dogtail.tree import Node
+ if isinstance(item, Node):
+ if item in self.cache:
+ row = self.cache[item]
+ # If row is None, we need to call getPath() to be sure
+ if not row:
+ path = self.getPath(item)
+ return path is not None
+ elif row in self:
+ return True
+ return False
+ elif isinstance(item, Gtk.TreeIter):
+ return self.iter_is_valid(item)
+ elif isinstance(item, list) or isinstance(item, tuple):
+ try:
+ iter = self.get_iter(item)
+ except ValueError:
+ return False
+ return iter in self
+ elif isinstance(item, Gtk.TreeRowReference):
+ return item.valid() and item.get_path() in self
+ else:
+ raise TypeError
+
+ def changeRoot(self, node):
+ self.rootNode = node
+ self.refresh()
+
+ def reset(self):
+ self.rootNode = self.initialRootNode
+ self.refresh()
+
+ def refresh(self):
+ self.cache.clear()
+ self.clear()
+ self.appendAndPopulate(None, self.rootNode)
+
+ def append(self, parentIter, node):
+ if node:
+ self.cache[node] = None
+ pb = self.getPixbufForNode(node)
+ return Gtk.TreeStore.append(self, parentIter, (node, node.name, pb))
+
+ def remove(self, iter):
+ node = self.getNode(iter)
+ try:
+ del self.cache[node]
+ finally:
+ return Gtk.TreeStore.remove(self, iter)
+
+ def populateChildren(self, iter):
+ if not iter in self:
+ return False
+ result = True
+ node = self.getNode(iter)
+ try:
+ for child in node.children:
+ if child in self:
+ continue
+ result = result and self.append(iter, child)
+ except GLib.GError as e:
+ if 'name :1.0 was not provided' in e.message:
+ print("Dogtail: warning: omiting possibly broken at-spi application record")
+ return result
+
+ def appendAndPopulate(self, iter, node):
+ childIter = self.append(iter, node)
+ return self.populateChildren(childIter)
+
+ def getNode(self, iter):
+ if not iter in self:
+ return None
+ return self.get_value(iter, self.nodeColumn)
+
+ def getPath(self, node):
+ if not node:
+ raise ValueError
+ try:
+ indexInParent = node.indexInParent
+ except LookupError:
+ return None
+ root = pyatspi.Registry.getDesktop(0)
+ row = self.cache.get(node, None)
+ path = []
+ needParent = True
+ if row:
+ if row in self:
+ path = row.get_path()
+ else:
+ del self.cache[node]
+ elif node == self.rootNode:
+ indexInParent = 0
+ needParent = False
+ elif node.role == pyatspi.ROLE_APPLICATION or node.roleName == \
+ 'application':
+ path = [0]
+ indexInParent = list(root.children).index(node)
+ needParent = False
+ elif not node.parent:
+ return None
+ elif (0 <= indexInParent <= (len(node.parent) - 1)) and \
+ node.parent[indexInParent] != node:
+ return None
+ siblings = node.parent.children
+ sibIndex = siblings.index(node)
+ try:
+ if siblings[sibIndex] != node:
+ return None
+ else:
+ indexInParent = sibIndex
+ except ValueError:
+ return None
+ if type(path) == list:
+ if needParent:
+ parentPath = self.getPath(node.parent)
+ if parentPath is None:
+ return None
+ else:
+ path = list(parentPath)
+ path.append(indexInParent)
+
+ path = tuple(path)
+ try:
+ nodeByPath = self.getNode(self.get_iter(path))
+ if node != nodeByPath:
+ # print "%s is not %s!" % (node, nodeByPath)
+ return None
+ except ValueError:
+ # print "I smell a bug in %s..." % node.getApplication()
+ return None
+
+ #self.cache[node] = Gtk.TreeRowReference(self, path)
+ return path
+
+ def processEvents(self):
+ if not len(self.eventQueue):
+ return
+ queueCopy = self.eventQueue[:]
+ for event in queueCopy:
+ self.processChangedNode(event)
+ self.eventQueue.remove(event)
+ return False
+
+ def nodeChanged(self, event):
+ # if self.autorefresh.get_active() is False: return
+ node = event.source
+ if not node or not node in self:
+ return
+ app = event.host_application
+ if app and app.name == 'sniff':
+ return
+ self.eventQueue.append(event)
+ GObject.idle_add(self.processEvents)
+
+ def processChangedNode(self, event):
+ node = event.source
+ if not node or not node in self:
+ return
+ path = self.getPath(node)
+ try:
+ iter = self.get_iter(path)
+ except (ValueError, TypeError):
+ return
+ if event.type.major == "property-change":
+ if event.type.minor == "accessible-name":
+ node = self.getNode(iter)
+ self.set_value(iter, self.nameColumn, node.name)
+ elif event.type.minor == "accessible-state":
+ print str(event)
+ elif event.type.major == "state-changed":
+ print str(event)
+ elif event.type.major == "children-changed":
+ if event.type.minor == 'add':
+ for child in node.children:
+ if not child in self:
+ if len(child) > 0:
+ self.appendAndPopulate(iter, child)
+ else:
+ # If it has no children now, give it a sec
+ # to come up with some.
+ GObject.timeout_add(1000,
+ self.__addNodeCB, iter, child)
+ elif event.type.minor == 'remove':
+ self.__removeNodeCB(iter, node, path)
+
+ def __addNodeCB(self, iter, parent):
+ self.appendAndPopulate(iter, parent)
+ return False
+
+ def __removeNodeCB(self, iter, parent, path):
+ childRow = self.iter_children(iter)
+ while childRow is not None:
+ node = self.getNode(childRow)
+ if node is None:
+ break
+ if node and self.getNode(childRow) not in parent:
+ self.remove(childRow)
+ else:
+ childRow = self.iter_next(childRow)
+
+ def __populateCB(self, iter):
+ self.populateChildren(iter)
+ return False
+
+ def getPixbufForNode(self, node):
+ theme = Gtk.IconTheme().get_default()
+ try:
+ if node.role == pyatspi.ROLE_APPLICATION:
+ # FIXME: Use the pixbuf from libwcnk (if available):
+ # wnckApp = Application(node).getWnckApplication()
+ # if wnckApp
+ try:
+ return theme.load_icon(node.name, 24,
+ Gtk.IconLookupFlags.USE_BUILTIN)
+ except GObject.GError:
+ try:
+ return theme.load_icon(node.name.lower(), 24,
+ Gtk.IconLookupFlags.USE_BUILTIN)
+ except GObject.GError:
+ return None
+ elif node.parent:
+ return iconForRole[node.role]
+ else:
+ return theme.load_icon("user-desktop", 24,
+ Gtk.IconLookupFlags.USE_BUILTIN)
+ except Exception:
+ return theme.load_icon("dialog-error", 24,
+ Gtk.IconLookupFlags.USE_BUILTIN)
+
+
+class StateModel(Gtk.ListStore):
+ stateColumn = 0
+ statesSupported = ['checked', 'focusable', 'focused', 'sensitive',
+ 'showing']
+
+ def __init__(self):
+ Gtk.ListStore.__init__(self, GObject.TYPE_STRING)
+
+ def setNode(self, node):
+ self.clear()
+ for stateName in self.statesSupported:
+ if getattr(node, stateName) is True:
+ self.append((stateName.capitalize(),))
+
+
+def loadIcon(iconName):
+ try:
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file('icons/' + iconName)
+ except GObject.GError:
+ import os
+ path = os.path.abspath(
+ os.path.join(__file__, os.path.pardir, os.path.pardir))
+ if path is '/':
+ path = '/usr'
+ iconName = os.path.join(path, 'share/dogtail/icons/', iconName)
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file(iconName)
+ return pixbuf
+
+button_xpm = loadIcon("button.xpm")
+checkbutton_xpm = loadIcon("checkbutton.xpm")
+checkmenuitem_xpm = loadIcon("checkmenuitem.xpm")
+colorselection_xpm = loadIcon("colorselection.xpm")
+combo_xpm = loadIcon("combo.xpm")
+dialog_xpm = loadIcon("dialog.xpm")
+image_xpm = loadIcon("image.xpm")
+label_xpm = loadIcon("label.xpm")
+menubar_xpm = loadIcon("menubar.xpm")
+menuitem_xpm = loadIcon("menuitem.xpm")
+notebook_xpm = loadIcon("notebook.xpm")
+scrolledwindow_xpm = loadIcon("scrolledwindow.xpm")
+spinbutton_xpm = loadIcon("spinbutton.xpm")
+statusbar_xpm = loadIcon("statusbar.xpm")
+table_xpm = loadIcon("table.xpm")
+text_xpm = loadIcon("text.xpm")
+toolbar_xpm = loadIcon("toolbar.xpm")
+tree_xpm = loadIcon("tree.xpm")
+treeitem_xpm = loadIcon("treeitem.xpm")
+unknown_xpm = loadIcon("unknown.xpm")
+viewport_xpm = loadIcon("viewport.xpm")
+vscrollbar_xpm = loadIcon("vscrollbar.xpm")
+vseparator_xpm = loadIcon("vseparator.xpm")
+window_xpm = loadIcon("window.xpm")
+
+iconForRole = {
+ pyatspi.ROLE_INVALID: None,
+ # pyatspi doesn't have the following... not even sure if it exists
+ # anywhere.
+ # atspi.SPI_ROLE_ACCEL_LABEL : label_xpm,
+ pyatspi.ROLE_ALERT: None,
+ pyatspi.ROLE_ANIMATION: None,
+ pyatspi.ROLE_ARROW: None,
+ pyatspi.ROLE_CALENDAR: None,
+ pyatspi.ROLE_CANVAS: None,
+ pyatspi.ROLE_CHECK_BOX: checkbutton_xpm,
+ pyatspi.ROLE_CHECK_MENU_ITEM: checkmenuitem_xpm,
+ pyatspi.ROLE_COLOR_CHOOSER: colorselection_xpm,
+ pyatspi.ROLE_COLUMN_HEADER: None,
+ pyatspi.ROLE_COMBO_BOX: combo_xpm,
+ pyatspi.ROLE_DATE_EDITOR: None,
+ pyatspi.ROLE_DESKTOP_ICON: None,
+ pyatspi.ROLE_DESKTOP_FRAME: None,
+ pyatspi.ROLE_DIAL: None,
+ pyatspi.ROLE_DIALOG: dialog_xpm,
+ pyatspi.ROLE_DIRECTORY_PANE: None,
+ pyatspi.ROLE_DRAWING_AREA: None,
+ pyatspi.ROLE_FILE_CHOOSER: None,
+ pyatspi.ROLE_FILLER: None,
+ pyatspi.ROLE_FONT_CHOOSER: None,
+ pyatspi.ROLE_FRAME: window_xpm,
+ pyatspi.ROLE_GLASS_PANE: None,
+ pyatspi.ROLE_HTML_CONTAINER: None,
+ pyatspi.ROLE_ICON: image_xpm,
+ pyatspi.ROLE_IMAGE: image_xpm,
+ pyatspi.ROLE_INTERNAL_FRAME: None,
+ pyatspi.ROLE_LABEL: label_xpm,
+ pyatspi.ROLE_LAYERED_PANE: viewport_xpm,
+ pyatspi.ROLE_LIST: None,
+ pyatspi.ROLE_LIST_ITEM: None,
+ pyatspi.ROLE_MENU: menuitem_xpm,
+ pyatspi.ROLE_MENU_BAR: menubar_xpm,
+ pyatspi.ROLE_MENU_ITEM: menuitem_xpm,
+ pyatspi.ROLE_OPTION_PANE: None,
+ pyatspi.ROLE_PAGE_TAB: notebook_xpm,
+ pyatspi.ROLE_PAGE_TAB_LIST: notebook_xpm,
+ pyatspi.ROLE_PANEL: viewport_xpm,
+ pyatspi.ROLE_PASSWORD_TEXT: None,
+ pyatspi.ROLE_POPUP_MENU: None,
+ pyatspi.ROLE_PROGRESS_BAR: None,
+ pyatspi.ROLE_PUSH_BUTTON: button_xpm,
+ pyatspi.ROLE_RADIO_BUTTON: None,
+ pyatspi.ROLE_RADIO_MENU_ITEM: None,
+ pyatspi.ROLE_ROOT_PANE: viewport_xpm,
+ pyatspi.ROLE_ROW_HEADER: None,
+ pyatspi.ROLE_SCROLL_BAR: vscrollbar_xpm,
+ pyatspi.ROLE_SCROLL_PANE: scrolledwindow_xpm,
+ pyatspi.ROLE_SEPARATOR: vseparator_xpm,
+ pyatspi.ROLE_SLIDER: None,
+ pyatspi.ROLE_SPIN_BUTTON: spinbutton_xpm,
+ pyatspi.ROLE_SPLIT_PANE: None,
+ pyatspi.ROLE_STATUS_BAR: statusbar_xpm,
+ pyatspi.ROLE_TABLE: table_xpm,
+ pyatspi.ROLE_TABLE_CELL: treeitem_xpm,
+ pyatspi.ROLE_TABLE_COLUMN_HEADER: None,
+ pyatspi.ROLE_TABLE_ROW_HEADER: None,
+ pyatspi.ROLE_TEAROFF_MENU_ITEM: None,
+ pyatspi.ROLE_TERMINAL: None,
+ pyatspi.ROLE_TEXT: text_xpm,
+ pyatspi.ROLE_TOGGLE_BUTTON: None,
+ pyatspi.ROLE_TOOL_BAR: toolbar_xpm,
+ pyatspi.ROLE_TOOL_TIP: None,
+ pyatspi.ROLE_TREE: tree_xpm,
+ pyatspi.ROLE_TREE_TABLE: tree_xpm,
+ pyatspi.ROLE_UNKNOWN: unknown_xpm,
+ pyatspi.ROLE_VIEWPORT: viewport_xpm,
+ pyatspi.ROLE_WINDOW: window_xpm,
+ pyatspi.ROLE_EXTENDED: None,
+ pyatspi.ROLE_HEADER: None,
+ pyatspi.ROLE_FOOTER: None,
+ pyatspi.ROLE_PARAGRAPH: None,
+ pyatspi.ROLE_RULER: None,
+ pyatspi.ROLE_APPLICATION: None,
+ pyatspi.ROLE_AUTOCOMPLETE: None,
+ pyatspi.ROLE_EDITBAR: None,
+ pyatspi.ROLE_EMBEDDED: None,
+ pyatspi.ROLE_LAST_DEFINED: None}
+
+
+def main():
+ from dogtail.utils import Lock
+ # We need this to prohibit sniff making(and removing on exit)
+ # sniff_refresh lock when importing Node
+ sniff_running = Lock(lockname='sniff_running.lock', randomize=False)
+ try:
+ sniff_running.lock()
+ except OSError:
+ pass
+ sniff = SniffApp()
+
+if __name__ == '__main__':
+ main()