Changeset 78

Show
Ignore:
Timestamp:
12/06/07 12:54:22
Author:
slee
Message:

fixed stability problems with listeners

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • action_groups/trunk/ActionBrowser.py

    r77 r78  
    1414import gobject 
    1515 
    16 from ActionModel import ActionModel 
     16from ActionModel import ActionModel, ActionGroup 
    1717 
    1818_ = lambda x: x 
     
    104104 
    105105  def _onExamine(self, button): 
    106     acc = self.groups_tree.get_selected_acc() 
    107     if acc is not None and self.node is not None: 
    108       self.node.update(acc) 
     106    if self.node is not None: 
     107      acc = self.groups_tree.get_selected_acc() 
     108      if acc is not None : 
     109        self.node.update(acc) 
    109110 
    110111  def _onScan(self, button): 
     
    124125 
    125126  def _onRowActivated(self, treeview, path, column): 
    126     self._onExamine(None) 
    127     #acc = self.groups_tree.get_acc_from_path(path) 
    128     #self.node.update(acc) 
     127    if self.node is not None: 
     128      self._onExamine(None) 
     129      acc = self.groups_tree.get_acc_from_path(path) 
     130      self.node.update(acc) 
     131    else: 
     132      self._onAction(None) 
    129133 
    130134  def _onSelectionChanged(self, selection): 
     
    145149 
    146150class ActionTree(gtk.TreeView): 
     151  EVENTS = ('object', 'window', 'focus') 
     152  EVENTS = ('focus') 
     153   
    147154  def __init__(self): 
    148155    gtk.TreeView.__init__(self) 
    149156    self.connect('row-expanded', self._onExpanded) 
    150157    self.connect('row-collapsed', self._onCollapsed) 
     158    self.connect('destroy', self._onDestroy) 
    151159 
    152160    crt = gtk.CellRendererText() 
     
    161169    self.append_column(tvc) 
    162170 
    163     pyatspi.Registry.registerEventListener(self._onAccEventState, 'object', 'window', 'focus') 
    164     pyatspi.Registry.registerEventListener(self._onAccEventState, 'object:state-changed') 
     171    pyatspi.Registry.registerEventListener(self._onATSPIEvent, *ActionTree.EVENTS) 
    165172    #self.set_property('fixed-height-mode', True) # speed display 
    166173 
     
    203210    self.set_model(model) 
    204211 
    205   def __del__(self): 
    206     self.deRegisterEventListener(self._onAccEventState, 'object:state-changed'
     212  def _onDestroy(self, object): 
     213    pyatspi.Registry.deregisterEventListener(self._onATSPIEvent, *ActionTree.EVENTS
    207214 
    208215  def select(self, iter): 
     
    227234    self.select(nextiter) 
    228235 
    229   def _onAccEventState(self, event): 
    230     ''' 
    231     Callback for accessible state changes. Repopulates the states model. 
    232  
    233     @param event: Event that triggered this callback. 
    234     @type event: Accessibility.Event 
    235     ''' 
     236  def _onATSPIEvent(self, event): 
     237    if event.source.getApplication() == self.get_acc_from_path(0).getApplication(): 
     238      gobject.idle_add(self._processEventOnIdle, event) 
     239 
     240  def _processEventOnIdle(self, event): 
    236241    if not self.get_model(): 
    237       return 
    238     if event.source.getApplication() <> self.get_acc_from_path(0).getApplication(): 
    239242      return 
    240243    model, iter, acc = self._getSelection() 
    241244    if acc is None:  
    242245      return 
    243     #printEvent(event) 
     246 
     247    printEvent(event) 
     248     
    244249    if event.source.getRole() == pyatspi.ROLE_WINDOW \ 
    245250       and event.type in ('object:state-changed:showing'): 
     
    247252      path = model.get_path(iter) 
    248253 
    249       if showing:# \ 
    250         # and not model.iter_has_child(iter): 
    251         model.makeExpandable(iter) 
    252         #model.addSubTree(event.source, None) 
    253         model.popLevel(iter) 
    254         self.expand_row(path, False) 
    255         acc.is_group = True 
     254      if showing: 
     255        if acc.hasRoleIn(pyatspi.ROLE_MENU): 
     256          model.makeExpandable(iter) 
     257          model.popLevel(iter) 
     258          self.expand_row(path, False) 
     259          acc.is_group = True 
     260          self.next() 
     261          #dumpAcc(event.source) 
    256262         
    257263      elif not showing: 
     
    265271              self.get_selection().select_iter(menu_iter) 
    266272 
     273    return False  # remove this from idle processing 
     274     
    267275  def do_action(self): 
    268276    model, iter, acc = self._getSelection() 
     
    270278    path = model.get_path(iter) 
    271279    acc.grabFocus() 
    272  
     280  
    273281    if acc.isEditable(): 
    274282      try: 
     
    283291          acc.generateClick() 
    284292        else: 
    285           acc.doAction() 
     293          acc.generateClick() 
     294          #acc.doAction() 
    286295 
    287296      if acc.isHyperlink(): 
     
    294303        print 'zzz' + str(path) 
    295304        model.popToPath(path) 
    296         self.expandToPath(path) 
    297         selection.select_path(path) 
     305        goToPath(path) 
     306        return 
    298307           
    299308    elif acc.isSelectable(): 
     309      print 'selectable' 
    300310      acc.toggleSectable() 
    301311              
    302     if getattr(acc, 'is_group', False) and acc.is_group: 
     312#    if getattr(acc, 'is_group', False) and acc.is_group: 
     313    if acc.is_group: 
    303314      if self.row_expanded(path): 
    304315        if acc.getRole() == pyatspi.ROLE_MENU: 
     
    311322        self.next() 
    312323 
    313   def expandToPath(self, path): 
    314     for i in xrange(1, len(path)): 
    315       self.expand_row(path[:i], False) 
    316  
     324  def goToPath(self, path): 
     325    if len(path) > 1: 
     326      self.expand_to_path(path[:-1]) 
     327    self.scroll_to_cell(path) 
     328    selection = self.get_selection() 
     329    selection.select_path(path) 
     330  
    317331class MessageBox(): 
    318332  def __init__(self, parent, message): 
     
    375389    print '\t', ad.x, ad.y, ad.width, ad.height 
    376390 
     391def dumpAcc(acc, level=0): 
     392  #if level == 0: 
     393  #  print 'Dumping' 
     394  #print ' ' * level + str(acc) 
     395  level += 1 
     396  for child_acc in acc: 
     397    if child_acc is None: continue 
     398    dumpAcc(child_acc, level) 
  • action_groups/trunk/atspi.py

    r73 r78  
    11import pyatspi 
    2 import time 
     2from os import times 
     3from gobject import idle_add 
     4 
     5def dumpAccTree(acc, level=0): 
     6  if level == 0: 
     7    print 'Dumping' 
     8  print ' ' * level + str(acc) 
     9  level += 1 
     10  for child_acc in acc: 
     11    if child_acc is None: continue 
     12    dumpAccTree(child_acc, level) 
    313 
    414def eventCallback(event): 
    5         app = event.source.getApplication() 
    6         if app is not None and app.name not in ('gedit', 'zgnome-terminal', 'zMinefield', 'rhythmbox', 'nautilus'): 
    7                 return 
    8          
    9         t = time.localtime() 
    10         ts = '%s:%s' % (t[4], t[5]) 
    11         print ts, event.type, event.detail1, event.detail2, \ 
    12                                 (str(event.any_data) if event.any_data else ''), \ 
    13                                 '\n\t', event.host_application, event.source, repr(event.source_role)  
    14         if isinstance(event.any_data, pyatspi.Accessibility.BoundingBox): 
    15                 ad = event.any_data 
    16                 print '\t', ad.x, ad.y, ad.width, ad.height 
     15  acc = event.source 
     16  app = acc.getApplication() 
     17  if app is not None and app.name not in ('gedit', 'zgnome-terminal', 'zMinefield', 'rhythmbox', 'nautilus'): 
     18    return 
    1719 
    18 #pyatspi.Registry.registerEventListener(eventCallback, 'object:state-changed') 
    19 pyatspi.Registry.registerEventListener(eventCallback, 'object', 'window') 
     20  def printEvent(): 
     21    ts = int(times()[-1] % 10000) 
     22    print ts, event.type, event.detail1, event.detail2, \ 
     23          (str(event.any_data) if event.any_data else ''), \ 
     24          '\n\t', event.host_application, event.source, repr(event.source_role)  
     25    if isinstance(event.any_data, pyatspi.Accessibility.BoundingBox): 
     26      ad = event.any_data 
     27      print '\t', ad.x, ad.y, ad.width, ad.height 
     28    if event.source.getRole() == pyatspi.ROLE_WINDOW \ 
     29       and event.type.startswith(('object:state-changed:showing',)): 
     30      showing = bool(event.detail1) 
     31      if showing: 
     32        dumpAccTree(event.source) 
     33  #     if event.type.startswith('object:children-changed:add'): 
     34  #       print acc.childCount, len(acc) 
     35  #       a = acc[event.detail1] 
     36  #       dumpAccTree(a) 
     37 
     38    return False 
     39 
     40  idle_add(printEvent) 
     41 
     42EVENTS = ('document', 'focus', 'object', 'window', 'terminal') 
     43pyatspi.Registry.registerEventListener(eventCallback, *EVENTS) 
    2044 
    2145try: 
    22        pyatspi.Registry.start() 
     46  pyatspi.Registry.start() 
    2347except KeyboardInterrupt: 
    24         pass 
    25  
    26 pyatspi.printCache() 
     48  pass 
    2749 
    2850#cleanup 
    2951pyatspi.Registry.stop() 
    30 pyatspi.Registry.deregisterEventListener(eventCallback, 'object', 'window') 
     52pyatspi.Registry.deregisterEventListener(eventCallback, *EVENTS) 
     53