[pyatspi2] Changes to properly update the cache and fix orca performance issues by caching data about the deskt



commit 79ffafd051159310b2657ced75da947682410444
Author: Mark Doffman <mark doffman codethink co uk>
Date:   Thu Jan 28 00:14:37 2010 -0800

    Changes to properly update the cache and fix orca performance issues
    by caching data about the desktop object.

 pyatspi/appevent.py     |    4 +-
 pyatspi/busutils/bus.py |   43 ++++++++++++++++++---
 pyatspi/cache.py        |   96 +++++++++++++++++++++++++++++++----------------
 pyatspi/deviceevent.py  |    4 +-
 pyatspi/factory.py      |    4 +-
 pyatspi/registry.py     |    5 +-
 6 files changed, 110 insertions(+), 46 deletions(-)
---
diff --git a/pyatspi/appevent.py b/pyatspi/appevent.py
index 7ba9b46..6c4fa10 100644
--- a/pyatspi/appevent.py
+++ b/pyatspi/appevent.py
@@ -17,8 +17,8 @@ import interfaces
 from accessible import BoundingBox
 from exceptions import *
 
-from busutils import AccessibilityBus
 from factory import AccessibleFactory
+from busutils import *
 
 __all__ = [
                 "Event",
@@ -300,7 +300,7 @@ class Event(object):
 class _ApplicationEventRegister (object):
 
         def __init__ (self, factory):
-                self._bus = AccessibilityBus ()
+                self._bus = AsyncAccessibilityBus ()
                 self._factory = factory
 
                 self._event_listeners = {}
diff --git a/pyatspi/busutils/bus.py b/pyatspi/busutils/bus.py
index 63ceebf..5a84d6a 100644
--- a/pyatspi/busutils/bus.py
+++ b/pyatspi/busutils/bus.py
@@ -87,26 +87,57 @@ class _AccessibilityBus (_bus.BusConnection):
 		#return AccessibilityProxy (self, name, path, introspect=False)
 
 
-class AccessibilityBus (_AccessibilityBus):
+class AsyncAccessibilityBus (_AccessibilityBus):
 	"""
 	Shared instance of the D-Bus bus used for accessibility.
+
+        Events are queued and later delivered from main loop.
+        D-Bus calls are made asyncronously.
 	"""
 
 	_shared_instance = None
 	
 	def __new__ (cls):
-		if AccessibilityBus._shared_instance:
-			return AccessibilityBus._shared_instance
+		if AsyncAccessibilityBus._shared_instance:
+			return AsyncAccessibilityBus._shared_instance
 		else:
 			try:
-				AccessibilityBus._shared_instance = _AccessibilityBus.__new__ (cls, _get_accessibility_bus_address(), None)
+				AsyncAccessibilityBus._shared_instance = \
+                                        _AccessibilityBus.__new__ (cls, _get_accessibility_bus_address(), None)
 			except Exception:
-				AccessibilityBus._shared_instance = _AccessibilityBus.__new__ (cls, _bus.BusConnection.TYPE_SESSION, None)
+				AsyncAccessibilityBus._shared_instance = \
+                                        _AccessibilityBus.__new__ (cls, _bus.BusConnection.TYPE_SESSION, None)
 			
-			return AccessibilityBus._shared_instance
+			return AsyncAccessibilityBus._shared_instance
 
 	def __init__ (self):
 		try:
 			_AccessibilityBus.__init__ (self, _get_accessibility_bus_address(), None)
 		except Exception:
 			_AccessibilityBus.__init__ (self, _bus.BusConnection.TYPE_SESSION, None)
+
+class SyncAccessibilityBus (_bus.BusConnection):
+	"""
+	Shared instance of the D-Bus bus used for accessibility.
+	"""
+
+	_shared_instance = None
+	
+	def __new__ (cls):
+		if SyncAccessibilityBus._shared_instance:
+			return SyncAccessibilityBus._shared_instance
+		else:
+			try:
+				SyncAccessibilityBus._shared_instance = \
+                                        _bus.BusConnection.__new__ (cls, _get_accessibility_bus_address(), None)
+			except Exception:
+				SyncAccessibilityBus._shared_instance = \
+                                        _bus.BusConnection.__new__ (cls, _bus.BusConnection.TYPE_SESSION, None)
+			
+			return SyncAccessibilityBus._shared_instance
+
+	def __init__ (self):
+		try:
+			_bus.BusConnection.__init__ (self, _get_accessibility_bus_address(), None)
+		except Exception:
+			_bus.BusConnection.__init__ (self, _bus.BusConnection.TYPE_SESSION, None)
diff --git a/pyatspi/cache.py b/pyatspi/cache.py
index 7c07cf9..b6c2353 100644
--- a/pyatspi/cache.py
+++ b/pyatspi/cache.py
@@ -15,11 +15,11 @@
 import os
 import dbus
 
-from appevent import Event
-
 from interfaces import *
+from role import ROLE_INVALID
+
+from busutils import *
 
-from busutils import AccessibilityBus
 
 __all__ = [
            "AccessibleCache"
@@ -75,19 +75,22 @@ class DesktopCacheManager (object):
         """
         Responsible for keeping track of applications as they are added or removed
         from the desktop object.
+
+        Also places a cache item that represents the Desktop object.
         """
  
         def __init__(self, cache):
-                bus = AccessibilityBus ()
+                bus = SyncAccessibilityBus ()
 
                 self._cache = cache
                 self._application_list = {}
 
                 bus.add_signal_receiver(self._children_changed_handler,
-                                        bus_name=ATSPI_REGISTRY_NAME,
-                                        path=ATSPI_ROOT_PATH,
+                                        #bus_name=ATSPI_REGISTRY_NAME,
+                                        #path=ATSPI_ROOT_PATH,
                                         dbus_interface=_ATSPI_EVENT_OBJECT_INTERFACE,
                                         signal_name="ChildrenChanged",
+                                        interface_keyword="interface",
                                         member_keyword="member",
                                         sender_keyword="sender",
                                         path_keyword="path")
@@ -96,19 +99,44 @@ class DesktopCacheManager (object):
                 desktop = dbus.Interface(obj, ATSPI_ACCESSIBLE)
                 apps    = desktop.GetChildren()
 
+                #TODO This is ugly. Perhaps the desktop object should implement the
+                #     cache interface also?
+                bus_object = bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus")
+                self._unique_name = bus_object.GetNameOwner (ATSPI_REGISTRY_NAME)
+                self._cache[(self._unique_name, ATSPI_ROOT_PATH)] = \
+                        _CacheData ( 
+                                     ( (self._unique_name, ATSPI_ROOT_PATH),    #Reference
+                                       (self._unique_name, ATSPI_NULL_PATH),    #Application
+                                       (self._unique_name, ATSPI_NULL_PATH),    #Parent
+                                       apps,                                    #Children 
+                                       [ATSPI_ACCESSIBLE, ATSPI_COMPONENT],     #Interfaces
+                                       "main",                                  #Name
+                                       ROLE_INVALID,                            #Role
+                                       "",                                      #Description
+                                       []                                       #State
+                                     )
+                                   )
+
                 for bus_name, object_path in apps:
                                 self._application_list[bus_name] = ApplicationCacheManager (cache, bus_name)
 
 	def _children_changed_handler (self, 
                                        app, minor, detail1, detail2, any_data,
-				       sender=None, member=None, path=None):
-		if minor == "add":
-                        bus_name, object_path = any_data
-                        self._application_list[bus_name] = ApplicationCacheManager(cache, bus_name)
-		elif minor == "remove":
-                        bus_name, object_path = any_data
-                        self._application_list[bus_name].remove_all()
-                        del(self._application_list[bus_name])
+				       interface=None, sender=None, member=None, path=None):
+                if interface==_ATSPI_EVENT_OBJECT_INTERFACE and sender == self._unique_name and path == ATSPI_ROOT_PATH:
+		        if minor == "add":
+                                bus_name, object_path = any_data
+                                self._application_list[bus_name] = ApplicationCacheManager(self._cache, bus_name)
+		        elif minor == "remove":
+                                bus_name, object_path = any_data
+                                self._application_list[bus_name].remove_all()
+                                del(self._application_list[bus_name])
+
+			item = self._cache[(sender, path)]
+			if minor == "add":
+				item.children.insert (detail1, any_data)
+			elif minor == "remove":
+				del (item.children[detail1])
 
 #------------------------------------------------------------------------------
 
@@ -126,7 +154,7 @@ class ApplicationCacheManager (object):
                 connection - DBus connection.
                 busName    - Name of DBus connection where cache interface resides.
                 """
-                bus = AccessibilityBus()
+                bus = SyncAccessibilityBus()
 
                 self._cache = cache
 		self._bus_name = bus_name
@@ -137,9 +165,10 @@ class ApplicationCacheManager (object):
 
                 self._property_change =  \
                         bus.add_signal_receiver(self._property_change_handler,
-				                bus_name=self._bus_name,
+                                                bus_name=self._bus_name,
                                                 dbus_interface=_ATSPI_EVENT_OBJECT_INTERFACE,
                                                 signal_name="PropertyChange",
+                                                interface_keyword="interface",
                                                 member_keyword="member",
                                                 sender_keyword="sender",
                                                 path_keyword="path")
@@ -149,6 +178,7 @@ class ApplicationCacheManager (object):
                                                 bus_name=self._bus_name,
                                                 dbus_interface=_ATSPI_EVENT_OBJECT_INTERFACE,
                                                 signal_name="ChildrenChanged",
+                                                interface_keyword="interface",
                                                 member_keyword="member",
                                                 sender_keyword="sender",
                                                 path_keyword="path")
@@ -183,25 +213,27 @@ class ApplicationCacheManager (object):
 
 	def _property_change_handler (self,
                                       app, minor, detail1, detail2, any_data,
-				      sender=None, member=None, path=None):
-                if (sender, path) in self._cache:
-			item = self._cache[(sender, path)]
-			if minor == "accessible-name":
-				item.name = any_data
-			elif minor == "accessible-description":
-				item.description = any_data
-			elif minor == "accessible-parent":
-				item.parent = any_data
+				      interface=None, sender=None, member=None, path=None):
+                if interface==_ATSPI_EVENT_OBJECT_INTERFACE:
+                        if (sender, path) in self._cache:
+			        item = self._cache[(sender, path)]
+			        if minor == "accessible-name":
+				        item.name = any_data
+			        elif minor == "accessible-description":
+				        item.description = any_data
+			        elif minor == "accessible-parent":
+				        item.parent = any_data
 
 	def _children_changed_handler (self,
                                        app, minor, detail1, detail2, any_data,
-				       sender=None, member=None, path=None):
-		if (sender, path) in self._cache:
-			item = self._cache[(sender, path)]
-			if minor == "add":
-				item.children.insert (detail1, any_data)
-			elif minor == "remove":
-				del (item.children[detail1])
+				       interface=None, sender=None, member=None, path=None):
+                if interface==_ATSPI_EVENT_OBJECT_INTERFACE:
+		        if (sender, path) in self._cache:
+			        item = self._cache[(sender, path)]
+			        if minor == "add":
+				        item.children.insert (detail1, any_data)
+			        elif minor == "remove":
+				        del (item.children[detail1])
 
         def remove_all (self):
                 for bus_name, object_path in self._cache.keys():
diff --git a/pyatspi/deviceevent.py b/pyatspi/deviceevent.py
index ad795a8..c17e0fb 100644
--- a/pyatspi/deviceevent.py
+++ b/pyatspi/deviceevent.py
@@ -18,7 +18,7 @@ import dbus as _dbus
 import dbus.service as _service
 
 from enum import Enum as _Enum
-from busutils import AccessibilityBus
+from busutils import *
 
 import traceback
 
@@ -534,7 +534,7 @@ class KeyboardDeviceEventListener(_service.Object):
 class _DeviceEventRegister (object):
         
         def __init__ (self):
-                self._bus = AccessibilityBus ()
+                self._bus = SyncAccessibilityBus ()
                 self.dev = DeviceEventController (self._bus)
                 self.deviceClients = {}
 
diff --git a/pyatspi/factory.py b/pyatspi/factory.py
index 78ae11f..621eaf2 100644
--- a/pyatspi/factory.py
+++ b/pyatspi/factory.py
@@ -32,7 +32,7 @@ from value import *
 
 import dbus
 
-from busutils import AccessibilityBus
+from busutils import *
 
 __all__ = [
            "AccessibleFactory"
@@ -47,7 +47,7 @@ class AccessibleFactory (object):
 
         def __init__ (self, cache):
 
-                self._connection = AccessibilityBus() 
+                self._connection = AsyncAccessibilityBus() 
 
                 self._interfaces = { 
                         interfaces.ATSPI_ACCESSIBLE:Accessible,
diff --git a/pyatspi/registry.py b/pyatspi/registry.py
index 6a437fc..042395f 100644
--- a/pyatspi/registry.py
+++ b/pyatspi/registry.py
@@ -24,10 +24,11 @@
 import dbus
 import os as _os
 
+from busutils import *
+
 from factory import AccessibleFactory
 from appevent import _ApplicationEventRegister, _NullApplicationEventRegister
 from deviceevent import _DeviceEventRegister, _NullDeviceEventRegister
-from busutils import AccessibilityBus
 from cache import AccessibleCache
 
 from deviceevent import KEY_PRESSED_EVENT as _KEY_PRESSED_EVENT
@@ -124,7 +125,7 @@ class Registry(object):
 		factory = AccessibleFactory(cache)
 
                 # Set up the device event controllers
-                _connection = AccessibilityBus ()
+                _connection = SyncAccessibilityBus ()
                 _bus_object = _connection.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus")
 
                 if app_name:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]