X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=pyatspi%2Fregistry.py;h=de37259873a5043ec83c8f74273dc9f53b20145c;hb=4a674680808b73499b947cf95d36012eef5fb394;hp=f1eafdccc9027a5d0e9a73ab07b04d6cd1c806a3;hpb=86c482930c5191f70e4142a8eeeab2018cc6d022;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/pyatspi/registry.py b/pyatspi/registry.py index f1eafdc..de37259 100644 --- a/pyatspi/registry.py +++ b/pyatspi/registry.py @@ -204,9 +204,8 @@ class _DeviceObserver(_Observer, Accessibility__POA.DeviceEventListener): ''' Notifies the L{Registry} that an event has occurred. Wraps the raw event object in our L{Event} class to support automatic ref and unref calls. An - observer can set the L{Event} consume flag to True to indicate this event - should not be allowed to pass to other AT-SPI observers or the underlying - application. + observer can return True to indicate this event should not be allowed to pass + to other AT-SPI observers or the underlying application. @param ev: Keyboard event @type ev: Accessibility.DeviceEvent @@ -216,8 +215,7 @@ class _DeviceObserver(_Observer, Accessibility__POA.DeviceEventListener): ''' # wrap the device event ev = event.DeviceEvent(ev) - self.registry.handleDeviceEvent(ev, self) - return ev.consume + return self.registry.handleDeviceEvent(ev, self) class _EventObserver(_Observer, Accessibility__POA.EventListener): ''' @@ -349,9 +347,6 @@ class Registry(object): # enter the main loop try: bonobo.main() - except KeyboardInterrupt, e: - # re-raise the keyboard interrupt - raise e finally: # clear all observers for name, ob in self.observers.items(): @@ -359,7 +354,7 @@ class Registry(object): if gil: gobject.source_remove(i) if releaseGIL.keyboard_exception is not None: - # re-raise the keyboard interrupt we got during the GIL release + # raise an keyboard exception we may have gotten earlier raise releaseGIL.keyboard_exception def stop(self, *args): @@ -369,6 +364,7 @@ class Registry(object): except RuntimeError: # ignore errors when quitting (probably already quitting) pass + self.flushEvents() def getDesktopCount(self): ''' @@ -563,10 +559,9 @@ class Registry(object): ''' Dispatches L{event.DeviceEvent}s to registered clients. Clients are called in the order they were registered for the given AT-SPI event. If any - client sets the L{event.DeviceEvent.consume} flag to True, callbacks cease - for the event for clients of this registry instance. Clients of other - registry instances and clients in other processes may be affected - depending on the values of synchronous and preemptive used when invoking + client returns True, callbacks cease for the event for clients of this registry + instance. Clients of other registry instances and clients in other processes may + be affected depending on the values of synchronous and preemptive used when invoking L{registerKeystrokeListener}. @note: Asynchronous dispatch of device events is not supported. @@ -575,16 +570,20 @@ class Registry(object): @type event: L{event.DeviceEvent} @param ob: Observer that received the event @type ob: L{_DeviceObserver} + + @return: Should the event be consumed (True) or allowed to pass on to other + AT-SPI observers (False)? + @rtype: boolean ''' try: # try to get the client registered for this event type client = self.clients[ob] except KeyError: # client may have unregistered recently, ignore event - return + return False # make the call to the client try: - client(event) + return client(event) or event.consume except Exception: # print the exception, but don't let it stop notification traceback.print_exc() @@ -608,30 +607,74 @@ class Registry(object): ''' Dispatches L{event.Event}s to registered clients. Clients are called in the order they were registered for the given AT-SPI event. If any client - sets the L{Event} consume flag to True, callbacks cease for the event for - clients of this registry instance. Clients of other registry instances and - clients in other processes are unaffected. + returns True, callbacks cease for the event for clients of this registry + instance. Clients of other registry instances and clients in other processes + are unaffected. @param event: AT-SPI event @type event: L{event.Event} ''' + et = event.type try: # try to get the client registered for this event type - clients = self.clients[event.type.name] + clients = self.clients[et.name] except KeyError: - # client may have unregistered recently, ignore event - return + try: + # we may not have registered for the complete subtree of events + # if our tree does not list all of a certain type (e.g. + # object:state-changed:*); try again with klass and major only + if et.detail is not None: + # Strip the 'detail' field. + clients = self.clients['%s:%s:%s' % (et.klass, et.major, et.minor)] + elif et.minor is not None: + # The event could possibly be object:state-changed:*. + clients = self.clients['%s:%s' % (et.klass, et.major)] + except KeyError: + # client may have unregistered recently, ignore event + return # make the call to each client + consume = False for client in clients: try: - client(event) + consume = client(event) or False except Exception: # print the exception, but don't let it stop notification traceback.print_exc() - if event.consume: - # don't allow further processing if the consume flag is set + if consume or event.consume: + # don't allow further processing if a client returns True break + def flushEvents(self): + ''' + Flushes the event queue by destroying it and recreating it. + ''' + self.queue = Queue.Queue() + + def pumpQueuedEvents(self, num=-1): + ''' + Provides asynch processing of events in the queue by executeing them with + _dispatchEvent() (as is done immediately when synch processing). + This method would normally be called from a main loop or idle function. + + @param num: Number of events to pump. If number is negative it pumps + the entire queue. Default is -1. + @type num: integer + @return: True if queue is not empty after events were pumped. + @rtype: boolean + ''' + if num < 0: + # Dequeue as many events as currently in the queue. + num = self.queue.qsize() + for i in xrange(num): + try: + # get next waiting event + event = self.queue.get_nowait() + except Queue.Empty: + break + self._dispatchEvent(event) + + return not self.queue.empty() + def _registerClients(self, client, name): ''' Internal method that recursively associates a client with AT-SPI event