[pyatspi2] Add children-changed event emission for top-level accessibles.
- From: Mark Doffman <markdoffman src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pyatspi2] Add children-changed event emission for top-level accessibles.
- Date: Mon, 11 Jan 2010 18:30:58 +0000 (UTC)
commit cfdf29c41d6e4447cfc79bfe176805da349dcfe3
Author: Mark Doffman <mark doffman codethink co uk>
Date: Mon Jan 11 10:26:21 2010 -0800
Add children-changed event emission for top-level accessibles.
pyatspi/accessible.py | 42 ++++++++++++------------
pyatspi/appevent.py | 83 ++++++++++++++++++++++++++++++++++++++++++++++---
pyatspi/cache.py | 25 +++++++++++++-
pyatspi/registry.py | 2 +-
4 files changed, 123 insertions(+), 29 deletions(-)
---
diff --git a/pyatspi/accessible.py b/pyatspi/accessible.py
index f430f9b..fedf09d 100644
--- a/pyatspi/accessible.py
+++ b/pyatspi/accessible.py
@@ -267,14 +267,14 @@ class Accessible(BaseProxy):
# Cache data --------------------------------------------------------------------
@property
- def cached (self):
+ def _cached (self):
if self._cache is not None:
return (self.app_name, self.acc_path) in self._cache
else:
return False
@property
- def cached_data (self):
+ def _cached_data (self):
if self._cache is not None:
return self._cache[(self.app_name, self.acc_path)]
else:
@@ -287,8 +287,8 @@ class Accessible(BaseProxy):
Get the containing Application for this object.
@return the Application instance to which this object belongs.
"""
- if self.cached:
- return self.acc_factory (*self.cached_data.application)
+ if self._cached:
+ return self.acc_factory (*self._cached_data.application)
else:
func = self.get_dbus_method("GetApplication", dbus_interface=ATSPI_ACCESSIBLE)
name, path = func ()
@@ -336,8 +336,8 @@ class Accessible(BaseProxy):
an in parameter indicating which child is requested (zero-indexed).
@return : the 'nth' Accessible child of this object.
"""
- if self.cached:
- (name, path) = self.cached_data.children[index]
+ if self._cached:
+ (name, path) = self._cached_data.children[index]
else:
count = Int32(self._pgetter(ATSPI_ACCESSIBLE, "ChildCount"))
if index >= count:
@@ -353,7 +353,7 @@ class Accessible(BaseProxy):
@return : a long integer indicating this object's index in the
parent's list.
"""
- if self.cached:
+ if self._cached:
parent = self.get_parent()
if parent == None:
return -1
@@ -396,8 +396,8 @@ class Accessible(BaseProxy):
@return : a Role indicating the type of UI role played by this
object.
"""
- if self.cached:
- return Role(self.cached_data.role)
+ if self._cached:
+ return Role(self._cached_data.role)
else:
func = self.get_dbus_method("GetRole", dbus_interface=ATSPI_ACCESSIBLE)
return Role(func())
@@ -416,8 +416,8 @@ class Accessible(BaseProxy):
@return : a StateSet encapsulating the currently true states
of the object.
"""
- if self.cached:
- return _marshal_state_set(cached_data.state)
+ if self._cached:
+ return _marshal_state_set(_cached_data.state)
else:
func = self.get_dbus_method("GetState", dbus_interface=ATSPI_ACCESSIBLE)
return _marshal_state_set(func())
@@ -437,8 +437,8 @@ class Accessible(BaseProxy):
return self.__eq__(other)
def get_childCount(self):
- if self.cached:
- return len(self.cached_data.children)
+ if self._cached:
+ return len(self._cached_data.children)
else:
return Int32(self._pgetter(ATSPI_ACCESSIBLE, "ChildCount"))
_childCountDoc = \
@@ -450,8 +450,8 @@ class Accessible(BaseProxy):
getChildCount = get_childCount
def get_description(self):
- if self.cached:
- return self.cached_data.description
+ if self._cached:
+ return self._cached_data.description
else:
return self._pgetter(ATSPI_ACCESSIBLE, "Description")
_descriptionDoc = \
@@ -461,8 +461,8 @@ class Accessible(BaseProxy):
description = property(fget=get_description, doc=_descriptionDoc)
def get_name(self):
- if self.cached:
- return self.cached_data.name
+ if self._cached:
+ return self._cached_data.name
else:
return self._pgetter(ATSPI_ACCESSIBLE, "Name")
_nameDoc = \
@@ -472,8 +472,8 @@ class Accessible(BaseProxy):
name = property(fget=get_name, doc=_nameDoc)
def get_parent(self):
- if self.cached:
- name, path = self.cached_data.parent
+ if self._cached:
+ name, path = self._cached_data.parent
else:
name, path = self._pgetter (ATSPI_ACCESSIBLE, "Parent")
return self.acc_factory (name, path, ATSPI_ACCESSIBLE)
@@ -484,8 +484,8 @@ class Accessible(BaseProxy):
parent = property(fget=get_parent, doc=_parentDoc)
def get_interfaces(self):
- if self.cached:
- return self.cached_data.interfaces
+ if self._cached:
+ return self._cached_data.interfaces
else:
func = self.get_dbus_method("GetInterfaces", dbus_interface=ATSPI_ACCESSIBLE)
return func()
diff --git a/pyatspi/appevent.py b/pyatspi/appevent.py
index 6bada85..cc2dafd 100644
--- a/pyatspi/appevent.py
+++ b/pyatspi/appevent.py
@@ -257,8 +257,15 @@ class Event(object):
data = event[3]
- if name == "object_bounds_changed":
+ if self.type.is_subtype (EventType ("object:bounds-changed")):
self.any_data = BoundingBox(*data)
+ elif self.type.is_subtype (EventType ("object:children-changed")):
+ name, path = data;
+ self.any_data = self._acc_factory (name, path, interfaces.ATSPI_ACCESSIBLE)
+ self.any_data = ""
+ elif self.type.is_subtype (EventType ("object:property-change:parent")):
+ name, path = data;
+ self.any_data = self._acc_factory (name, path, interfaces.ATSPI_ACCESSIBLE)
else:
self.any_data = data
@@ -276,9 +283,8 @@ class Event(object):
def source(self):
if not self._source:
try:
- name, path = self._source_application
- self._source = self._acc_factory (name,
- path,
+ self._source = self._acc_factory (self._source_application,
+ self._source_path,
interfaces.ATSPI_ACCESSIBLE)
except AccessibleObjectNoLongerExists:
pass
@@ -314,11 +320,71 @@ class _ApplicationEventRegister (object):
self._event_listeners = {}
+ self._children_changed_type = EventType("object:children-changed")
+ self._children_changed_listeners = {}
+
def _callClients(self, register, event):
for client in register.keys():
client(event)
- def registerEventListener(self, client, *names):
+ def notifyChildrenChange(self, name, path, childref, added):
+ if added:
+ detail = "add"
+ else:
+ detail = "remove"
+ event = Event((detail, 0, 0, childref),
+ self._factory,
+ path,
+ name,
+ "org.freedesktop.atspi.Event.Object",
+ "children-changed")
+
+ self._callClients(self._children_changed_listeners, event)
+
+ def _registerFake(self, type, register, client, *names):
+ """
+ Registers a client from a register of clients
+ for 'Fake' events emitted by the cache.
+ """
+ try:
+ registered = register[client]
+ except KeyError:
+ registered = []
+ register[client] = registered
+
+ for name in names:
+ new_type = EventType(name)
+ if new_type.is_subtype(type):
+ registered.append(new_type.name)
+
+ if registered == []:
+ del(register[client])
+
+ def _deregisterFake(self, type, register, client, *names):
+ """
+ Deregisters a client from a register of clients
+ for 'Fake' events emitted by the cache.
+ """
+ try:
+ registered = register[client]
+ except KeyError:
+ return True
+
+ for name in names:
+ remove_type = EventType(name)
+
+ copy = registered[:]
+ for i in range(0, len(copy)):
+ type_name = copy[i]
+ registered_type = EventType(type_name)
+
+ if remove_type.is_subtype(registered_type):
+ del(registered[i])
+
+ if registered == []:
+ del(register[client])
+
+ def registerEventListener (self, client, *names):
try:
registered = self._event_listeners[client]
except KeyError:
@@ -330,6 +396,8 @@ class _ApplicationEventRegister (object):
registered.append((new_type.name,
event_type_to_signal_reciever(self._bus, self._factory, client, new_type)))
+ self._registerFake(self._children_changed_type, self._children_changed_listeners, client, *names)
+
def deregisterEventListener(self, client, *names):
try:
registered = self._event_listeners[client]
@@ -356,12 +424,17 @@ class _ApplicationEventRegister (object):
if registered == []:
del(self._event_listeners[client])
+ self._deregisterFake(self._children_changed_type, self._children_changed_listeners, client, *names)
+
return missing
#------------------------------------------------------------------------------
class _NullApplicationEventRegister (object):
+ def notifyChildrenChange(self, name, path, added):
+ pass
+
def registerEventListener(self, client, *names):
pass
diff --git a/pyatspi/cache.py b/pyatspi/cache.py
index 53a3615..a95c52c 100644
--- a/pyatspi/cache.py
+++ b/pyatspi/cache.py
@@ -39,10 +39,12 @@ class ApplicationCache(object):
_APPLICATIONS_ADD = 1
_APPLICATIONS_REMOVE = 0
- def __init__(self):
+ def __init__(self, event_dispatcher=None):
self._connection = AccessibilityBus ()
self._factory = None
+ self._event_dispatcher = event_dispatcher
+
self._application_list = []
self._application_cache = {}
@@ -81,7 +83,7 @@ class ApplicationCache(object):
def __getitem__ (self, key):
try:
name, path = key
- return self._application_cache[app_name][key]
+ return self._application_cache[name][key]
except Exception:
raise KeyError ()
@@ -96,10 +98,21 @@ class ApplicationCache(object):
if update_type == ApplicationCache._APPLICATIONS_ADD:
self._application_list.append(bus_name)
self._application_cache[bus_name] = AccessibleCache(bus_name)
+ if self._event_dispatcher:
+ self._event_dispatcher.notifyChildrenChange(ATSPI_REGISTRY_NAME,
+ ATSPI_DESKTOP_PATH,
+ self._application_cache[bus_name].root,
+ True)
elif update_type == ApplicationCache._APPLICATIONS_REMOVE:
+ if self._event_dispatcher:
+ self._event_dispatcher.notifyChildrenChange(ATSPI_REGISTRY_NAME,
+ ATSPI_DESKTOP_PATH,
+ self._application_cache[bus_name].root,
+ False)
self._application_list.remove(bus_name)
del(self._application_cache[bus_name])
+
#------------------------------------------------------------------------------
class _CacheData(object):
@@ -177,6 +190,9 @@ class AccessibleCache(object):
_ATSPI_EVENT_OBJECT_INTERFACE = "org.freedesktop.atspi.Event.Object"
+ _CACHE_PATH = '/org/at_spi/cache'
+ _CACHE_INTERFACE = 'org.freedesktop.atspi.Cache'
+
def __init__(self, bus_name):
"""
Creates a cache.
@@ -211,6 +227,11 @@ class AccessibleCache(object):
sender_keyword="sender",
path_keyword="path")
+ obj = self._connection.get_object (bus_name, self._CACHE_PATH)
+ cache = dbus.Interface (obj, self._CACHE_INTERFACE)
+
+ self.root = cache.GetRoot ()
+
def __getitem__(self, key):
try:
name, path = key
diff --git a/pyatspi/registry.py b/pyatspi/registry.py
index be86e7d..182ad72 100644
--- a/pyatspi/registry.py
+++ b/pyatspi/registry.py
@@ -138,7 +138,7 @@ class Registry(object):
if app_name:
cache = AccessibleCache(app_name)
else:
- cache = ApplicationCache()
+ cache = ApplicationCache(appreg)
factory.set_cache (cache)
factory.set_desktop (desktop)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]