1 #Copyright (C) 2008 Codethink Ltd
2 #copyright: Copyright (c) 2005, 2007 IBM Corporation
4 #This library is free software; you can redistribute it and/or
5 #modify it under the terms of the GNU Lesser General Public
6 #License version 2 as published by the Free Software Foundation.
8 #This program is distributed in the hope that it will be useful,
9 #but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 #GNU General Public License for more details.
12 #You should have received a copy of the GNU Lesser General Public License
13 #along with this program; if not, write to the Free Software
14 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 #Portions of this code originally licensed and copyright (c) 2005, 2007
17 #IBM Corporation under the BSD license, available at
18 #U{http://www.opensource.org/licenses/bsd-license.php}
20 #authors: Peter Parente, Mark Doffman
32 ATSPI_DEVICE_EVENT_CONTROLLER = 'org.freedesktop.atspi.DeviceEventController'
33 ATSPI_DEVICE_EVENT_LISTENER = 'org.freedesktop.atspi.DeviceEventListener'
37 class _Observer(object):
39 Parent class for all event observers. Dispatches all received events to the
40 L{Registry} that created this L{_Observer}. Provides basic reference counting
41 functionality needed by L{Registry} to determine when an L{_Observer} can be
42 released for garbage collection.
44 The reference counting provided by this class is independent of the reference
45 counting used by CORBA. Keeping the counts separate makes it easier for the
46 L{Registry} to detect when an L{_Observer} can be freed in the
47 L{Registry._unregisterObserver} method.
49 @ivar registry: Reference to the L{Registry} that created this L{_Observer}
50 @type registry: weakref.proxy to L{Registry}
51 @ivar ref_count: Reference count on this L{_Observer}
52 @type ref_count: integer
54 def __init__(self, registry):
56 Stores a reference to the creating L{Registry}. Intializes the reference
57 count on this object to zero.
59 @param registry: The L{Registry} that created this observer
60 @type registry: weakref.proxy to L{Registry}
62 self.registry = weakref.proxy(registry)
67 Increments the Python reference count on this L{_Observer} by one. This
68 method is called when a new client is registered in L{Registry} to receive
69 notification of an event type monitored by this L{_Observer}.
73 def clientUnref(self):
75 Decrements the pyatspi reference count on this L{_Observer} by one. This
76 method is called when a client is unregistered in L{Registry} to stop
77 receiving notifications of an event type monitored by this L{_Observer}.
81 def getClientRefCount(self):
83 @return: Current Python reference count on this L{_Observer}
89 """Required by CORBA. Does nothing."""
93 """Required by CORBA. Does nothing."""
96 class _DeviceObserver(_Observer, Accessibility__POA.DeviceEventListener):
98 Observes keyboard press and release events.
100 @ivar registry: The L{Registry} that created this observer
101 @type registry: L{Registry}
102 @ivar key_set: Set of keys to monitor
103 @type key_set: list of integer
104 @ivar mask: Watch for key events while these modifiers are held
106 @ivar kind: Kind of events to monitor
108 @ivar mode: Keyboard event mode
109 @type mode: Accessibility.EventListenerMode
111 def __init__(self, registry, synchronous, preemptive, global_):
113 Creates a mode object that defines when key events will be received from
114 the system. Stores all other information for later registration.
116 @param registry: The L{Registry} that created this observer
117 @type registry: L{Registry}
118 @param synchronous: Handle the key event synchronously?
119 @type synchronous: boolean
120 @param preemptive: Allow event to be consumed?
121 @type preemptive: boolean
122 @param global_: Watch for events on inaccessible applications too?
123 @type global_: boolean
125 _Observer.__init__(self, registry)
126 self.mode = Accessibility.EventListenerMode()
127 self.mode.preemptive = preemptive
128 self.mode.synchronous = synchronous
129 self.mode._global = global_
131 def register(self, dc, key_set, mask, kind):
133 Starts keyboard event monitoring.
135 @param dc: Reference to a device controller
136 @type dc: Accessibility.DeviceEventController
137 @param key_set: Set of keys to monitor
138 @type key_set: list of integer
139 @param mask: Integer modifier mask or an iterable over multiple masks to
141 @type mask: integer, iterable, or None
142 @param kind: Kind of events to monitor
146 # check if the mask is iterable
149 # register a single integer if not
150 dc.registerKeystrokeListener(self._this(), key_set, mask, kind,
154 dc.registerKeystrokeListener(self._this(), key_set, m, kind, self.mode)
156 def unregister(self, dc, key_set, mask, kind):
158 Stops keyboard event monitoring.
160 @param dc: Reference to a device controller
161 @type dc: Accessibility.DeviceEventController
162 @param key_set: Set of keys to monitor
163 @type key_set: list of integer
164 @param mask: Integer modifier mask or an iterable over multiple masks to
166 @type mask: integer, iterable, or None
167 @param kind: Kind of events to monitor
171 # check if the mask is iterable
174 # unregister a single integer if not
175 dc.deregisterKeystrokeListener(self._this(), key_set, mask, kind)
178 dc.deregisterKeystrokeListener(self._this(), key_set, m, kind)
180 def queryInterface(self, repo_id):
182 Reports that this class only implements the AT-SPI DeviceEventListener
183 interface. Required by AT-SPI.
185 @param repo_id: Request for an interface
186 @type repo_id: string
187 @return: The underlying CORBA object for the device event listener
188 @rtype: Accessibility.EventListener
190 if repo_id == utils.getInterfaceIID(Accessibility.DeviceEventListener):
195 def notifyEvent(self, ev):
197 Notifies the L{Registry} that an event has occurred. Wraps the raw event
198 object in our L{Event} class to support automatic ref and unref calls. An
199 observer can return True to indicate this event should not be allowed to pass
200 to other AT-SPI observers or the underlying application.
202 @param ev: Keyboard event
203 @type ev: Accessibility.DeviceEvent
204 @return: Should the event be consumed (True) or allowed to pass on to other
205 AT-SPI observers (False)?
208 # wrap the device event
209 ev = event.DeviceEvent(ev)
210 return self.registry.handleDeviceEvent(ev, self)
212 class _EventObserver(_Observer, Accessibility__POA.EventListener):
214 Observes all non-keyboard AT-SPI events. Can be reused across event types.
216 def register(self, reg, name):
218 Starts monitoring for the given event.
220 @param name: Name of the event to start monitoring
222 @param reg: Reference to the raw registry object
223 @type reg: Accessibility.Registry
225 reg.registerGlobalEventListener(self._this(), name)
227 def unregister(self, reg, name):
229 Stops monitoring for the given event.
231 @param name: Name of the event to stop monitoring
233 @param reg: Reference to the raw registry object
234 @type reg: Accessibility.Registry
236 reg.deregisterGlobalEventListener(self._this(), name)
238 def queryInterface(self, repo_id):
240 Reports that this class only implements the AT-SPI DeviceEventListener
241 interface. Required by AT-SPI.
243 @param repo_id: Request for an interface
244 @type repo_id: string
245 @return: The underlying CORBA object for the device event listener
246 @rtype: Accessibility.EventListener
248 if repo_id == utils.getInterfaceIID(Accessibility.EventListener):
253 def notifyEvent(self, ev):
255 Notifies the L{Registry} that an event has occurred. Wraps the raw event
256 object in our L{Event} class to support automatic ref and unref calls.
257 Aborts on any exception indicating the event could not be wrapped.
259 @param ev: AT-SPI event signal (anything but keyboard)
260 @type ev: Accessibility.Event
262 # wrap raw event so ref counts are correct before queueing
264 self.registry.handleEvent(ev)
266 class DeviceEvent(object):
268 Wraps an AT-SPI device event with a more Pythonic interface. Primarily adds
269 a consume attribute which can be used to cease propagation of a device event.
271 @ivar consume: Should this event be consumed and not allowed to pass on to
272 observers further down the dispatch chain in this process or possibly
274 @type consume: boolean
275 @ivar type: Kind of event, KEY_PRESSED_EVENT or KEY_RELEASED_EVENT
276 @type type: Accessibility.EventType
277 @ivar id: Serial identifier for this key event
279 @ivar hw_code: Hardware scan code for the key
280 @type hw_code: integer
281 @ivar modifiers: Modifiers held at the time of the key event
282 @type modifiers: integer
283 @ivar timestamp: Time at which the event occurred relative to some platform
284 dependent starting point (e.g. XWindows start time)
285 @type timestamp: integer
286 @ivar event_string: String describing the key pressed (e.g. keysym)
287 @type event_string: string
288 @ivar is_text: Is the event representative of text to be inserted (True), or
289 of a control key (False)?
290 @type is_text: boolean
292 def __init__(self, event):
294 Attaches event data to this object.
296 @param event: Event object
297 @type event: Accessibility.DeviceEvent
300 self.type = event.type
302 self.hw_code = event.hw_code
303 self.modifiers = event.modifiers
304 self.timestamp = event.timestamp
305 self.event_string = event.event_string
306 self.is_text = event.is_text
310 Builds a human readable representation of the event.
312 @return: Event description
315 if self.type == constants.KEY_PRESSED_EVENT:
317 elif self.type == constants.KEY_RELEASED_EVENT:
326 \tis_text: %s""" % (kind, self.hw_code, self.event_string, self.modifiers,
327 self.id, self.timestamp, self.is_text)
331 Wraps an AT-SPI event with a more Pythonic interface managing exceptions,
332 the differences in any_data across versions, and the reference counting of
333 accessibles provided with the event.
335 @note: All unmarked attributes of this class should be considered public
336 readable and writable as the class is acting as a record object.
338 @ivar consume: Should this event be consumed and not allowed to pass on to
339 observers further down the dispatch chain in this process?
340 @type consume: boolean
341 @ivar type: The type of the AT-SPI event
342 @type type: L{EventType}
343 @ivar detail1: First AT-SPI event parameter
344 @type detail1: integer
345 @ivar detail2: Second AT-SPI event parameter
346 @type detail2: integer
347 @ivar any_data: Extra AT-SPI data payload
348 @type any_data: object
349 @ivar host_application: Application owning the event source
350 @type host_application: Accessibility.Application
351 @ivar source_name: Name of the event source at the time of event dispatch
352 @type source_name: string
353 @ivar source_role: Role of the event source at the time of event dispatch
354 @type source_role: Accessibility.Role
355 @ivar source: Source of the event
356 @type source: Accessibility.Accessible
358 def __init__(self, event):
360 Extracts information from the provided event. If the event is a "normal"
361 event, pulls the detail1, detail2, any_data, and source values out of the
362 given object and stores it in this object. If the event is a device event,
363 key ID is stored in detail1, scan code is stored in detail2, key name,
364 key modifiers (e.g. ALT, CTRL, etc.), is text flag, and timestamp are
365 stored as a 4-tuple in any_data, and source is None (since key events are
368 @param event: Event from an AT-SPI callback
369 @type event: Accessibility.Event or Accessibility.DeviceEvent
371 # always start out assuming no consume
373 self.type = EventType(event.type)
374 self.detail1 = event.detail1
375 self.detail2 = event.detail2
376 # store the event source and increase the reference count since event
377 # sources are borrowed references; the AccessibleMixin automatically
378 # decrements it later
381 except AttributeError:
383 self.source = event.source
385 # process any_data in a at-spi version independent manner
386 details = event.any_data.value()
388 # see if we have a "new" any_data object which is an EventDetails struct
389 self.any_data = details.any_data.value()
391 # any kind of error means we have an "old" any_data object and None of
392 # the extra data so set them to None
393 self.any_data = details
394 self.host_application = None
395 self.source_name = None
396 self.source_role = None
398 # the rest of the data should be here, so retrieve it
399 self.host_application = details.host_application
400 self.source_name = details.source_name
401 self.source_role = details.source_role
403 # if we received an accessible, be sure to increment the ref count
405 except AttributeError:
408 # if we received a host application, be sure to increment the ref count
409 self.host_application.ref()
410 except AttributeError:
415 Builds a human readable representation of the event including event type,
416 parameters, and source info.
418 @return: Event description
421 return '%s(%s, %s, %s)\n\tsource: %s\n\thost_application: %s' % \
422 (self.type, self.detail1, self.detail2, self.any_data,
423 self.source, self.host_application)
425 class EventType(str):
427 Wraps the AT-SPI event type string so its components can be accessed
428 individually as klass (can't use the keyword class), major, minor, and detail
429 (klass:major:minor:detail).
431 @note: All attributes of an instance of this class should be considered
432 public readable as it is acting a a struct.
433 @ivar klass: Most general event type identifier (object, window, mouse, etc.)
435 @ivar major: Second level event type description
437 @ivar minor: Third level event type description
439 @ivar detail: Lowest level event type description
441 @ivar name: Full, unparsed event name as received from AT-SPI
443 @cvar format: Names of the event string components
444 @type format: 4-tuple of string
446 format = ('klass', 'major', 'minor', 'detail')
448 def __init__(self, name):
450 Parses the full AT-SPI event name into its components
451 (klass:major:minor:detail). If the provided event name is an integer
452 instead of a string, then the event is really a device event.
454 @param name: Full AT-SPI event name
456 @raise AttributeError: When the given event name is not a valid string
458 # get rid of any leading and trailing ':' separators
459 self.value = name.strip(':')
460 self.name = self.value # Backward compatability
466 # split type according to delimiters
467 split = self.value.split(':', 3)
468 # loop over all the components
469 for i in xrange(len(split)):
470 # store values of attributes in this object
471 setattr(self, self.format[i], split[i])
473 class Registry(object):
475 Wraps the Accessibility.Registry to provide more Pythonic registration for
478 This object should be treated as a singleton, but such treatment is not
479 enforced. You can construct another instance of this object and give it a
480 reference to the Accessibility.Registry singleton. Doing so is harmless and
483 @ivar async: Should event dispatch to local listeners be decoupled from event
484 receiving from the registry?
486 @ivar reg: Reference to the real, wrapped registry object
487 @type reg: Accessibility.Registry
488 @ivar dev: Reference to the device controller
489 @type dev: Accessibility.DeviceEventController
490 @ivar queue: Queue of events awaiting local dispatch
491 @type queue: Queue.Queue
492 @ivar clients: Map of event names to client listeners
493 @type clients: dictionary
494 @ivar observers: Map of event names to AT-SPI L{_Observer} objects
495 @type observers: dictionary
498 _REGISTRY_NAME = 'org.freedesktop.atspi.Registry'
500 def __init__(self, app_name=None):
502 Stores a reference to the AT-SPI registry. Gets and stores a reference
503 to the DeviceEventController.
505 @param reg: Reference to the AT-SPI registry daemon
506 @type reg: Accessibility.Registry
508 self._bus = dbus.SessionBus()
510 self._app_name = app_name
511 self._cache = TestApplicationCache(self._bus, app_name)
515 #self.dev = self.reg.getDeviceEventController()
516 #self.queue = Queue.Queue()
522 @return: This instance of the registry
527 def start(self, async=False, gil=True):
529 Enter the main loop to start receiving and dispatching events.
531 @param async: Should event dispatch be asynchronous (decoupled) from
532 event receiving from the AT-SPI registry?
534 @param gil: Add an idle callback which releases the Python GIL for a few
535 milliseconds to allow other threads to run? Necessary if other threads
536 will be used in this process.
537 Note - No Longer used.
540 self._loop = gobject.MainLoop()
543 def stop(self, *args):
544 """Quits the main loop."""
548 def getDesktopCount(self):
550 Gets the number of available desktops.
552 @return: Number of desktops
557 def getDesktop(self, i):
559 Gets a reference to the i-th desktop.
561 @param i: Which desktop to get
563 @return: Desktop reference
564 @rtype: Accessibility.Desktop
566 return Desktop(self._cache)
568 def registerEventListener(self, client, *names):
570 Registers a new client callback for the given event names. Supports
571 registration for all subevents if only partial event name is specified.
572 Do not include a trailing colon.
574 For example, 'object' will register for all object events,
575 'object:property-change' will register for all property change events,
576 and 'object:property-change:accessible-parent' will register only for the
577 parent property change event.
579 Registered clients will not be automatically removed when the client dies.
580 To ensure the client is properly garbage collected, call
581 L{deregisterEventListener}.
583 @param client: Callable to be invoked when the event occurs
584 @type client: callable
585 @param names: List of full or partial event names
586 @type names: list of string
589 # store the callback for each specific event name
590 self._registerClients(client, name)
592 def deregisterEventListener(self, client, *names):
594 Unregisters an existing client callback for the given event names. Supports
595 unregistration for all subevents if only partial event name is specified.
596 Do not include a trailing colon.
598 This method must be called to ensure a client registered by
599 L{registerEventListener} is properly garbage collected.
601 @param client: Client callback to remove
602 @type client: callable
603 @param names: List of full or partial event names
604 @type names: list of string
605 @return: Were event names specified for which the given client was not
611 # remove the callback for each specific event name
612 missed |= self._unregisterClients(client, name)
615 def registerKeystrokeListener(self, client, key_set=[], mask=0,
616 kind=(constants.KEY_PRESSED_EVENT,
617 constants.KEY_RELEASED_EVENT),
618 synchronous=True, preemptive=True,
621 Registers a listener for key stroke events.
623 @param client: Callable to be invoked when the event occurs
624 @type client: callable
625 @param key_set: Set of hardware key codes to stop monitoring. Leave empty
626 to indicate all keys.
627 @type key_set: list of integer
628 @param mask: When the mask is None, the codes in the key_set will be
629 monitored only when no modifier is held. When the mask is an
630 integer, keys in the key_set will be monitored only when the modifiers in
631 the mask are held. When the mask is an iterable over more than one
632 integer, keys in the key_set will be monitored when any of the modifier
633 combinations in the set are held.
634 @type mask: integer, iterable, None
635 @param kind: Kind of events to watch, KEY_PRESSED_EVENT or
638 @param synchronous: Should the callback notification be synchronous, giving
639 the client the chance to consume the event?
640 @type synchronous: boolean
641 @param preemptive: Should the callback be allowed to preempt / consume the
643 @type preemptive: boolean
644 @param global_: Should callback occur even if an application not supporting
645 AT-SPI is in the foreground? (requires xevie)
646 @type global_: boolean
649 # see if we already have an observer for this client
650 ob = self.clients[client]
652 # create a new device observer for this client
653 ob = _DeviceObserver(self, synchronous, preemptive, global_)
654 # store the observer to client mapping, and the inverse
655 self.clients[ob] = client
656 self.clients[client] = ob
658 # None means all modifier combinations
659 mask = utils.allModifiers()
660 # register for new keystrokes on the observer
661 ob.register(self.dev, key_set, mask, kind)
663 def deregisterKeystrokeListener(self, client, key_set=[], mask=0,
664 kind=(constants.KEY_PRESSED_EVENT,
665 constants.KEY_RELEASED_EVENT)):
667 Deregisters a listener for key stroke events.
669 @param client: Callable to be invoked when the event occurs
670 @type client: callable
671 @param key_set: Set of hardware key codes to stop monitoring. Leave empty
672 to indicate all keys.
673 @type key_set: list of integer
674 @param mask: When the mask is None, the codes in the key_set will be
675 monitored only when no modifier is held. When the mask is an
676 integer, keys in the key_set will be monitored only when the modifiers in
677 the mask are held. When the mask is an iterable over more than one
678 integer, keys in the key_set will be monitored when any of the modifier
679 combinations in the set are held.
680 @type mask: integer, iterable, None
681 @param kind: Kind of events to stop watching, KEY_PRESSED_EVENT or
684 @raise KeyError: When the client isn't already registered for events
686 # see if we already have an observer for this client
687 ob = self.clients[client]
689 # None means all modifier combinations
690 mask = utils.allModifiers()
691 # register for new keystrokes on the observer
692 ob.unregister(self.dev, key_set, mask, kind)
694 def generateKeyboardEvent(self, keycode, keysym, kind):
696 Generates a keyboard event. One of the keycode or the keysym parameters
697 should be specified and the other should be None. The kind parameter is
698 required and should be one of the KEY_PRESS, KEY_RELEASE, KEY_PRESSRELEASE,
699 KEY_SYM, or KEY_STRING.
701 @param keycode: Hardware keycode or None
702 @type keycode: integer
703 @param keysym: Symbolic key string or None
705 @param kind: Kind of event to synthesize
709 self.dev.generateKeyboardEvent(keycode, '', kind)
711 self.dev.generateKeyboardEvent(None, keysym, kind)
713 def generateMouseEvent(self, x, y, name):
715 Generates a mouse event at the given absolute x and y coordinate. The kind
716 of event generated is specified by the name. For example, MOUSE_B1P
717 (button 1 press), MOUSE_REL (relative motion), MOUSE_B3D (butten 3
720 @param x: Horizontal coordinate, usually left-hand oriented
722 @param y: Vertical coordinate, usually left-hand oriented
724 @param name: Name of the event to generate
727 self.dev.generateMouseEvent(x, y, name)
729 def handleDeviceEvent(self, event, ob):
731 Dispatches L{event.DeviceEvent}s to registered clients. Clients are called
732 in the order they were registered for the given AT-SPI event. If any
733 client returns True, callbacks cease for the event for clients of this registry
734 instance. Clients of other registry instances and clients in other processes may
735 be affected depending on the values of synchronous and preemptive used when invoking
736 L{registerKeystrokeListener}.
738 @note: Asynchronous dispatch of device events is not supported.
740 @param event: AT-SPI device event
741 @type event: L{event.DeviceEvent}
742 @param ob: Observer that received the event
743 @type ob: L{_DeviceObserver}
745 @return: Should the event be consumed (True) or allowed to pass on to other
746 AT-SPI observers (False)?
750 # try to get the client registered for this event type
751 client = self.clients[ob]
753 # client may have unregistered recently, ignore event
755 # make the call to the client
757 return client(event) or event.consume
759 # print the exception, but don't let it stop notification
760 traceback.print_exc()
762 def handleEvent(self, event):
764 Handles an AT-SPI event by either queuing it for later dispatch when the
765 L{Registry.async} flag is set, or dispatching it immediately.
767 @param event: AT-SPI event
768 @type event: L{event.Event}
772 self.queue.put_nowait(event)
774 # dispatch immediately
775 self._dispatchEvent(event)
777 def _dispatchEvent(self, event):
779 Dispatches L{event.Event}s to registered clients. Clients are called in
780 the order they were registered for the given AT-SPI event. If any client
781 returns True, callbacks cease for the event for clients of this registry
782 instance. Clients of other registry instances and clients in other processes
785 @param event: AT-SPI event
786 @type event: L{event.Event}
790 # try to get the client registered for this event type
791 clients = self.clients[et.name]
794 # we may not have registered for the complete subtree of events
795 # if our tree does not list all of a certain type (e.g.
796 # object:state-changed:*); try again with klass and major only
797 if et.detail is not None:
798 # Strip the 'detail' field.
799 clients = self.clients['%s:%s:%s' % (et.klass, et.major, et.minor)]
800 elif et.minor is not None:
801 # The event could possibly be object:state-changed:*.
802 clients = self.clients['%s:%s' % (et.klass, et.major)]
804 # client may have unregistered recently, ignore event
806 # make the call to each client
808 for client in clients:
810 consume = client(event) or False
812 # print the exception, but don't let it stop notification
813 traceback.print_exc()
814 if consume or event.consume:
815 # don't allow further processing if a client returns True
818 def flushEvents(self):
820 Flushes the event queue by destroying it and recreating it.
822 self.queue = Queue.Queue()
824 def pumpQueuedEvents(self, num=-1):
826 Provides asynch processing of events in the queue by executeing them with
827 _dispatchEvent() (as is done immediately when synch processing).
828 This method would normally be called from a main loop or idle function.
830 @param num: Number of events to pump. If number is negative it pumps
831 the entire queue. Default is -1.
833 @return: True if queue is not empty after events were pumped.
837 # Dequeue as many events as currently in the queue.
838 num = self.queue.qsize()
839 for i in xrange(num):
841 # get next waiting event
842 event = self.queue.get_nowait()
845 self._dispatchEvent(event)
847 return not self.queue.empty()
849 def _registerClients(self, client, name):
851 Internal method that recursively associates a client with AT-SPI event
852 names. Allows a client to incompletely specify an event name in order to
853 register for subevents without specifying their full names manually.
855 @param client: Client callback to receive event notifications
856 @type client: callable
857 @param name: Partial or full event name
861 # look for an event name in our event tree dictionary
862 events = constants.EVENT_TREE[name]
864 # if the event name doesn't exist, it's a leaf event meaning there are
865 # no subtypes for that event
866 # add this client to the list of clients already in the dictionary
867 # using the event name as the key; if there are no clients yet for this
868 # event, insert an empty list into the dictionary before appending
870 et = event.EventType(name)
871 clients = self.clients.setdefault(et.name, [])
873 # if this succeeds, this client is already registered for the given
874 # event type, so ignore the request
875 clients.index(client)
877 # else register the client
878 clients.append(client)
879 self._registerObserver(name)
881 # if the event name does exist in the tree, there are subevents for
882 # this event; loop through them calling this method again to get to
885 self._registerClients(client, e)
887 def _unregisterClients(self, client, name):
889 Internal method that recursively unassociates a client with AT-SPI event
890 names. Allows a client to incompletely specify an event name in order to
891 unregister for subevents without specifying their full names manually.
893 @param client: Client callback to receive event notifications
894 @type client: callable
895 @param name: Partial or full event name
900 # look for an event name in our event tree dictionary
901 events = constants.EVENT_TREE[name]
904 # if the event name doesn't exist, it's a leaf event meaning there are
905 # no subtypes for that event
906 # get the list of registered clients and try to remove the one provided
907 et = event.EventType(name)
908 clients = self.clients[et.name]
909 clients.remove(client)
910 self._unregisterObserver(name)
911 except (ValueError, KeyError):
912 # ignore any exceptions indicating the client is not registered
915 # if the event name does exist in the tree, there are subevents for this
916 # event; loop through them calling this method again to get to the leaf
919 missed |= self._unregisterClients(client, e)
922 def _registerObserver(self, name):
924 Creates a new L{_Observer} to watch for events of the given type or
925 returns the existing observer if one is already registered. One
926 L{_Observer} is created for each leaf in the L{constants.EVENT_TREE} or
927 any event name not found in the tree.
929 @param name: Raw name of the event to observe
931 @return: L{_Observer} object that is monitoring the event
934 et = event.EventType(name)
936 # see if an observer already exists for this event
937 ob = self.observers[et.name]
939 # build a new observer if one does not exist
940 ob = _EventObserver(self)
941 # we have to register for the raw name because it may be different from
942 # the parsed name determined by EventType (e.g. trailing ':' might be
944 ob.register(self.reg, name)
945 self.observers[et.name] = ob
946 # increase our client ref count so we know someone new is watching for the
951 def _unregisterObserver(self, name):
953 Destroys an existing L{_Observer} for the given event type only if no
954 clients are registered for the events it is monitoring.
956 @param name: Name of the event to observe
958 @raise KeyError: When an observer for the given event is not regist
960 et = event.EventType(name)
961 # see if an observer already exists for this event
962 ob = self.observers[et.name]
964 if ob.getClientRefCount() == 0:
965 ob.unregister(self.reg, name)
966 del self.observers[et.name]
968 class DeviceEvent(list):
969 def __new__(cls, type, id, hw_code, modifiers, timestamp, event_string, is_text):
970 list.__new__(cls, (type, id, hw_code, modifiers, timestamp, event_string, is_text))
971 def __init__(self, type, id, hw_code, modifiers, timestamp, event_string, is_text):
972 list.__init__(self, (type, id, hw_code, modifiers, timestamp, event_string, is_text))
976 def _set_type(self, val):
978 type = property(fget=_get_type, fset=_set_type)
981 def _set_id(self, val):
983 id = property(fget=_get_id, fset=_set_id)
984 def _get_hw_code(self):
986 def _set_hw_code(self, val):
988 hw_code = property(fget=_get_hw_code, fset=_set_hw_code)
989 def _get_modifiers(self):
991 def _set_modifiers(self, val):
993 modifiers = property(fget=_get_modifiers, fset=_set_modifiers)
994 def _get_timestamp(self):
996 def _set_timestamp(self, val):
998 timestamp = property(fget=_get_timestamp, fset=_set_timestamp)
999 def _get_event_string(self):
1001 def _set_event_string(self, val):
1003 event_string = property(fget=_get_event_string, fset=_set_event_string)
1004 def _get_is_text(self):
1006 def _set_is_text(self, val):
1008 is_text = property(fget=_get_is_text, fset=_set_is_text)
1010 class DeviceEventController(_BaseProxy):
1012 The interface via which clients request notification of device
1013 events, and through which device events may be simulated.
1016 def deregisterDeviceEventListener(self, *args, **kwargs):
1018 De-register a previously registered keyboard eventlistener.
1020 a DeviceEventListener which will intercept events.
1022 an EventTypeSeq indicating which event types to stop listening
1025 func = self.get_dbus_method("deregisterDeviceEventListener")
1026 return func(*args, **kwargs)
1028 def deregisterKeystrokeListener(self, *args, **kwargs):
1030 De-register a previously registered keyboard eventlistener.
1032 a DeviceEventListener which will intercept key events.
1034 a KeySet indicating which keys to intercept, or KEYSET_ALL_KEYS.
1036 a ControllerEventMask filtering the intercepted key events.
1038 an EventType mask that may created by ORing event types together.
1040 func = self.get_dbus_method("deregisterKeystrokeListener")
1041 return func(*args, **kwargs)
1043 def generateKeyboardEvent(self, *args, **kwargs):
1045 Synthesize a keyboard event.
1047 a long integer indicating the keycode of the keypress to be synthesized.
1049 an optional UTF-8 string indicating a complex keyboard input
1052 a KeySynthType indicating the type of event(s) to be synthesized:
1053 a key press, release, press-release pair, or a complex input
1054 string (for instance from an internationalized or complex text
1055 input method, or a composed character).
1057 func = self.get_dbus_method("generateKeyboardEvent")
1058 return func(*args, **kwargs)
1060 def generateMouseEvent(self, *args, **kwargs):
1062 Synthesize a mouse event.
1064 a long integer indicating the screen x coord for the mouse event.
1066 a long integer indicating the screen y coord for the mouse event.
1068 a string indicating the type of mouse event, e.g. "button1up"
1070 func = self.get_dbus_method("generateMouseEvent")
1071 return func(*args, **kwargs)
1073 def notifyListenersAsync(self, *args, **kwargs):
1075 Notify the Registry instance that a device event has taken place
1076 in an asynchronous manner. This is the method used by accessibility
1077 bridges to forward "toolkit dependent" device events to the Registry
1078 from the application's process space. If the event in question
1079 is potentially pre-emptible. notifyListenersSync should be used
1082 func = self.get_dbus_method("notifyListenersAsync")
1083 return func(*args, **kwargs)
1085 def notifyListenersSync(self, *args, **kwargs):
1087 Notify the Registry instance that a device event has taken place,
1088 and allow pre-emptive listeners the opportunity to 'consume'
1089 the event and thus prevent its further issuance/forwarding. This
1090 is the method used by accessibility bridges to forward "toolkit
1091 dependent" device events to the Registry from the application's
1093 @return True if the event was consumed by a (pre-emptive) listener,
1094 False if not (in which case the device event will be forwarded
1095 as normal to any application which would normally receive it,
1096 e.g. the currently active application in the case of mouse or
1099 func = self.get_dbus_method("notifyListenersSync")
1100 return func(*args, **kwargs)
1102 def registerDeviceEventListener(self, *args, **kwargs):
1104 Register to intercept events, and either pass them on or consume
1105 them. To listen to keyboard events use registerKeystrokeListener
1108 a DeviceEventListener which will intercept events.
1110 an EventTypeSeq indicating which event types to listen for.
1111 @return True if successful, False if not
1113 func = self.get_dbus_method("registerDeviceEventListener")
1114 return func(*args, **kwargs)
1116 def registerKeystrokeListener(self, *args, **kwargs):
1118 Register to intercept keyboard events, and either pass them on
1121 a DeviceEventListener which will intercept key events.
1123 a KeySet indicating which keys to intercept, or KEYSET_ALL_KEYS.
1125 a ControllerEventMask filtering the intercepted key events.
1127 a KeyEventTypeSeq that may created by ORing event types together.
1129 an EventListenerMode indicating whether the listener should receive
1130 the events synchronously, potentially consuming them, or just
1131 be notified asynchronously of those events that have been generated.
1132 @return True if the DeviceEventListener was successfully registered
1133 for the requested KeySet, ControllerEventMask, event types, and
1134 EventListenerMode; otherwise returns False.
1136 func = self.get_dbus_method("registerKeystrokeListener")
1137 return func(*args, **kwargs)
1139 class DeviceEventListener(_BaseProxy):
1141 This interface should be implemented by AT-SPI clients who wish
1142 to make use of the DeviceEventController to receive device event
1143 notifications. DeviceEvents include keyboard events and mouse
1144 button/motion events.
1147 def notifyEvent(self, *args, **kwargs):
1149 Notify an interested DeviceEventListener that a DeviceEvent has
1151 @return True if the recipient/consumer wishes to consume the
1152 event, i.e. prevent it from being delivered to the desktop, False
1153 if the event should continue to be delivered as normal.
1155 func = self.get_dbus_method("notifyEvent")
1156 return func(*args, **kwargs)
1160 def __new__(cls, type, source, detail1, detail2, any_data):
1161 list.__new__(cls, (type, source, detail1, detail2, any_data))
1162 def __init__(self, type, source, detail1, detail2, any_data):
1163 list.__init__(self, (type, source, detail1, detail2, any_data))
1165 def _get_type(self):
1167 def _set_type(self, val):
1169 type = property(fget=_get_type, fset=_set_type)
1170 def _get_source(self):
1172 def _set_source(self, val):
1174 source = property(fget=_get_source, fset=_set_source)
1175 def _get_detail1(self):
1177 def _set_detail1(self, val):
1179 detail1 = property(fget=_get_detail1, fset=_set_detail1)
1180 def _get_detail2(self):
1182 def _set_detail2(self, val):
1184 detail2 = property(fget=_get_detail2, fset=_set_detail2)
1185 def _get_any_data(self):
1187 def _set_any_data(self, val):
1189 any_data = property(fget=_get_any_data, fset=_set_any_data)
1192 class EventDetails(list):
1193 def __new__(cls, host_application, source_role, source_name, any_data):
1194 list.__new__(cls, (host_application, source_role, source_name, any_data))
1195 def __init__(self, host_application, source_role, source_name, any_data):
1196 list.__init__(self, (host_application, source_role, source_name, any_data))
1198 def _get_host_application(self):
1200 def _set_host_application(self, val):
1202 host_application = property(fget=_get_host_application, fset=_set_host_application)
1203 def _get_source_role(self):
1205 def _set_source_role(self, val):
1207 source_role = property(fget=_get_source_role, fset=_set_source_role)
1208 def _get_source_name(self):
1210 def _set_source_name(self, val):
1212 source_name = property(fget=_get_source_name, fset=_set_source_name)
1213 def _get_any_data(self):
1215 def _set_any_data(self, val):
1217 any_data = property(fget=_get_any_data, fset=_set_any_data)
1219 class EventListener(_BaseProxy):
1221 A generic interface implemented by objects for the receipt of
1222 event notifications. EventListener is the interface from which
1223 Accessibility::Registry is derived, and via which clients of
1224 the Registry receive notification of changes to an application's
1225 user interface and content.
1228 def notifyEvent(self, *args, **kwargs):
1230 Synchronously notify an EventListener that an event has occurred,
1231 by passing it an Event struct.
1233 The Event about which the listener is being notified.
1235 func = self.get_dbus_method("notifyEvent")
1236 return func(*args, **kwargs)
1238 def unImplemented2_(self, *args, **kwargs):
1239 func = self.get_dbus_method("unImplemented2_")
1240 return func(*args, **kwargs)
1242 def unImplemented3_(self, *args, **kwargs):
1243 func = self.get_dbus_method("unImplemented3_")
1244 return func(*args, **kwargs)
1246 def unImplemented4_(self, *args, **kwargs):
1247 func = self.get_dbus_method("unImplemented4_")
1248 return func(*args, **kwargs)
1250 def unImplemented_(self, *args, **kwargs):
1251 func = self.get_dbus_method("unImplemented_")
1252 return func(*args, **kwargs)
1255 class EventListenerMode(list):
1256 def __new__(cls, synchronous, preemptive, global_):
1257 list.__new__(cls, (synchronous, preemptive, global_))
1258 def __init__(self, synchronous, preemptive, global_):
1259 list.__init__(self, (synchronous, preemptive, global_))
1261 def _get_synchronous(self):
1263 def _set_synchronous(self, val):
1265 synchronous = property(fget=_get_synchronous, fset=_set_synchronous)
1266 def _get_preemptive(self):
1268 def _set_preemptive(self, val):
1270 preemptive = property(fget=_get_preemptive, fset=_set_preemptive)
1271 def _get_global_(self):
1273 def _set_global_(self, val):
1275 global_ = property(fget=_get_global_, fset=_set_global_)
1278 class EventType(_Enum):
1280 0:'KEY_PRESSED_EVENT',
1281 1:'KEY_RELEASED_EVENT',
1282 2:'BUTTON_PRESSED_EVENT',
1283 3:'BUTTON_RELEASED_EVENT',
1291 class KeyDefinition(list):
1292 def __new__(cls, keycode, keysym, keystring, unused):
1293 list.__new__(cls, (keycode, keysym, keystring, unused))
1294 def __init__(self, keycode, keysym, keystring, unused):
1295 list.__init__(self, (keycode, keysym, keystring, unused))
1297 def _get_keycode(self):
1299 def _set_keycode(self, val):
1301 keycode = property(fget=_get_keycode, fset=_set_keycode)
1302 def _get_keysym(self):
1304 def _set_keysym(self, val):
1306 keysym = property(fget=_get_keysym, fset=_set_keysym)
1307 def _get_keystring(self):
1309 def _set_keystring(self, val):
1311 keystring = property(fget=_get_keystring, fset=_set_keystring)
1312 def _get_unused(self):
1314 def _set_unused(self, val):
1316 unused = property(fget=_get_unused, fset=_set_unused)
1318 class KeyEventType(_Enum):
1324 class KeySynthType(_Enum):
1328 2:'KEY_PRESSRELEASE',
1335 class ModifierType(_Enum):
1338 1:'MODIFIER_SHIFTLOCK',
1339 2:'MODIFIER_CONTROL',
1344 7:'MODIFIER_NUMLOCK',
1347 class Registry(EventListener):
1349 The Registry is a service through which applications providing
1350 accessibility services (servers) can rendezvous with consumers
1351 of those services (Assistive Technologies). The Registry is the
1352 first "port of call" for accessible applications and for assistive
1353 technologies wishing to query and interact with those applications.
1354 The Registry service provides four basic functions to Assistive
1355 Technology (AT) clients:
1356 it provides a list of the applications who have registered with
1357 the AT-SPI framework, thereby announcing their participation
1358 in the AT-SPI framework;
1359 it allows AT clients to register for notification of changes
1360 in application state (at-spi Events);
1361 it dispatches/relays said events from participating applications
1362 to the registered listeners;
1363 it gives access to system device events via the associated DeviceEventController
1365 From the point of view of accessible applications (i.e. AT-SPI
1366 service producers), the Registry is primarily a registration
1367 and event delivery service. Applications normally only call the
1368 registerApplication and deregisterApplication Registry methods,
1369 and its inherited EventListener::notifyEvent method.
1370 The Registry normally lives in its own process space; communication
1371 via Registry and both application services and AT clients takes
1372 place via IPC. A process space diagram illustrating the relationship
1373 between applications, Registry, and AT is shown below.
1376 def deregisterApplication(self, *args, **kwargs):
1378 De-register an application previously registered with the broker.
1379 deregisterApplication:
1381 a reference to the Application to be deregistered.
1383 func = self.get_dbus_method("deregisterApplication")
1384 return func(*args, **kwargs)
1386 def deregisterGlobalEventListener(self, *args, **kwargs):
1388 deregisterGlobalEventListener:
1390 the requesting EventListener
1392 a string indicating the type of events
1393 Request that a previously registered client stop receiving global
1394 notifications for events of a certain type.
1396 func = self.get_dbus_method("deregisterGlobalEventListener")
1397 return func(*args, **kwargs)
1399 def deregisterGlobalEventListenerAll(self, *args, **kwargs):
1401 deregisterGlobalEventListenerAll:
1403 the requesting EventListener
1404 Request that a previously registered client stop receiving global
1405 notifications for all events for which it was registered.
1407 func = self.get_dbus_method("deregisterGlobalEventListenerAll")
1408 return func(*args, **kwargs)
1410 def getDesktop(self, *args, **kwargs):
1413 : the index of the requested Desktop.
1414 Get the nth accessible desktop.
1415 @return a reference to the requested Desktop.
1417 func = self.get_dbus_method("getDesktop")
1418 return func(*args, **kwargs)
1420 def getDesktopCount(self, *args, **kwargs):
1422 event types: "Window" "Desktop" "Window:Create" "Window:Destroy"
1423 "Window:Iconify" "Window:Restore" "Window:Fullscreen" "Window:Resize"
1424 "Desktop:Create" "Desktop:Destroy" "Desktop:Focus" "Desktop:Defocus"
1425 "Desktop:Reorder" "Focus" "GtkWidget:show" "GObject:notify:<propertyname>"
1426 ( not sure we should allow these last 2 forms, since they are
1427 toolkit-specific, but they're powerful ) getDesktopCount:
1428 Get the current number of desktops.
1429 @return a short integer indicating the current number of Desktops.
1431 func = self.get_dbus_method("getDesktopCount")
1432 return func(*args, **kwargs)
1434 def getDesktopList(self, *args, **kwargs):
1436 Get a list of accessible desktops.
1437 @return : a sequence containing references to the Desktops.
1439 func = self.get_dbus_method("getDesktopList")
1440 return func(*args, **kwargs)
1442 def getDeviceEventController(self, *args, **kwargs):
1444 Obtain an object which can be used to request device event notifications.
1445 @return : an object implementing DeviceEventController
1447 func = self.get_dbus_method("getDeviceEventController")
1448 return func(*args, **kwargs)
1450 def registerApplication(self, *args, **kwargs):
1452 Register a new application with the accessibility broker.
1454 a reference to the requesting Application
1456 func = self.get_dbus_method("registerApplication")
1457 return func(*args, **kwargs)
1459 def registerGlobalEventListener(self, *args, **kwargs):
1461 Register a client's interest in (all) application events of a
1464 a reference to the requesting EventListener.
1466 a string which indicates the type of events about which the client
1467 desires notification.
1469 func = self.get_dbus_method("registerGlobalEventListener")
1470 return func(*args, **kwargs)
1480 class Table(_BaseProxy):
1482 An interface used by containers whose contained data is arranged
1483 in a "tabular" (i.e. row-column) fashion. Tables may resemble
1484 a two-dimensional grid, as in a spreadsheet, or may feature objects
1485 which span multiple rows and/or columns, but whose bounds are
1486 aligned on a row/column matrix. Thus, the Table interface may
1487 be used to represent "spreadsheets" as well as "frames".
1488 Objects within tables are children of the Table instance, and
1489 they may be referenced either via a child index or via a row/column
1490 pair. Their role may be ROLE_TABLE_CELL, but table 'cells' may
1491 have other roles as well. These 'cells' may implement other interfaces,
1492 such as Text, Action, Image, and Component, and should do so
1493 as appropriate to their onscreen representation and/or behavior.
1496 def addColumnSelection(self, *args, **kwargs):
1498 Select the specified column, adding it to the current column
1499 selection, if the table's selection model permits it.
1501 @return True if the specified column was successfully selected,
1504 func = self.get_dbus_method("addColumnSelection")
1505 return func(*args, **kwargs)
1507 def addRowSelection(self, *args, **kwargs):
1509 Select the specified row, adding it to the current row selection,
1510 if the table's selection model permits it.
1512 @return True if the specified row was successfully selected,
1515 func = self.get_dbus_method("addRowSelection")
1516 return func(*args, **kwargs)
1518 def getAccessibleAt(self, *args, **kwargs):
1520 Get the table cell at the specified row and column indices.
1522 the specified table row, zero-indexed.
1524 the specified table column, zero-indexed.
1525 @return an Accessible object representing the specified table
1528 func = self.get_dbus_method("getAccessibleAt")
1529 return func(*args, **kwargs)
1531 def getColumnAtIndex(self, *args, **kwargs):
1533 Get the table column index occupied by the child at a particular
1536 the specified child index, zero-indexed.
1537 @return a long integer indicating the first column spanned by
1538 the child of a table, at the specified 1-D (zero-offset) index.
1540 func = self.get_dbus_method("getColumnAtIndex")
1541 return func(*args, **kwargs)
1543 def getColumnDescription(self, *args, **kwargs):
1545 Get a text description of a particular table column. This differs
1546 from AccessibleTable_getColumnHeader, which returns an Accessible.
1548 the specified table column, zero-indexed.
1549 @return a UTF-8 string describing the specified table column,
1552 func = self.get_dbus_method("getColumnDescription")
1553 return func(*args, **kwargs)
1555 def getColumnExtentAt(self, *args, **kwargs):
1557 Get the number of columns spanned by the table cell at the specific
1558 row and column. (some tables can have cells which span multiple
1559 rows and/or columns).
1561 the specified table row, zero-indexed.
1563 the specified table column, zero-indexed.
1564 @return a long integer indicating the number of columns spanned
1565 by the specified cell.
1567 func = self.get_dbus_method("getColumnExtentAt")
1568 return func(*args, **kwargs)
1570 def getColumnHeader(self, *args, **kwargs):
1572 Get the header associated with a table column, if available,
1573 as an instance of Accessible. This differs from getColumnDescription,
1574 which returns a string.
1576 the specified table column, zero-indexed.
1577 @return an Accessible representatin of the specified table column,
1580 func = self.get_dbus_method("getColumnHeader")
1581 return func(*args, **kwargs)
1583 def getIndexAt(self, *args, **kwargs):
1585 Get the 1-D child index corresponding to the specified 2-D row
1588 the specified table row, zero-indexed.
1590 the specified table column, zero-indexed.
1591 @return a long integer which serves as the index of a specified
1592 cell in the table, in a form usable by Accessible::getChildAtIndex.
1594 func = self.get_dbus_method("getIndexAt")
1595 return func(*args, **kwargs)
1597 def getRowAtIndex(self, *args, **kwargs):
1599 Get the table row index occupied by the child at a particular
1602 the specified child index, zero-indexed.
1603 @return a long integer indicating the first row spanned by the
1604 child of a table, at the specified 1-D (zero-offset) index.
1606 func = self.get_dbus_method("getRowAtIndex")
1607 return func(*args, **kwargs)
1609 def getRowColumnExtentsAtIndex(self, *args, **kwargs):
1611 Given a child index, determine the row and column indices and
1612 extents, and whether the cell is currently selected. If the child
1613 at index is not a cell (for instance, if it is a summary, caption,
1614 etc.), False is returned.
1616 the index of the Table child whose row/column extents are requested.
1618 back-filled with the first table row associated with the cell
1619 with child index index.
1621 back-filled with the first table column associated with the cell
1622 with child index index.
1623 @param : row_extents
1624 back-filled with the number of table rows across which child
1626 @param : col_extents
1627 back-filled with the number of table columns across which child
1629 @param : is_selected
1630 a boolean which is back-filled with True if the child at index
1631 i corresponds to a selected table cell, False otherwise.
1632 Example: If the Table child at index '6' extends across columns
1633 5 and 6 of row 2 of a Table instance, and is currently selected,
1634 then retval=table::getRowColumnExtentsAtIndex(6,row,col,
1638 will return True, and after the call row, col, row_extents,
1639 col_extents, and is_selected will contain 2, 5, 1, 2, and True,
1641 @return True if the index is associated with a valid table cell,
1642 False if the index does not correspond to a cell. If False is
1643 returned, the values of the out parameters are undefined.
1645 func = self.get_dbus_method("getRowColumnExtentsAtIndex")
1646 return func(*args, **kwargs)
1648 def getRowDescription(self, *args, **kwargs):
1650 Get a text description of a particular table row. This differs
1651 from AccessibleTable_getRowHeader, which returns an Accessible.
1653 the specified table row, zero-indexed.
1654 @return a UTF-8 string describing the specified table row, if
1657 func = self.get_dbus_method("getRowDescription")
1658 return func(*args, **kwargs)
1660 def getRowExtentAt(self, *args, **kwargs):
1662 Get the number of rows spanned by the table cell at the specific
1663 row and column. (some tables can have cells which span multiple
1664 rows and/or columns).
1666 the specified table row, zero-indexed.
1668 the specified table column, zero-indexed.
1669 @return a long integer indicating the number of rows spanned
1670 by the specified cell.
1672 func = self.get_dbus_method("getRowExtentAt")
1673 return func(*args, **kwargs)
1675 def getRowHeader(self, *args, **kwargs):
1677 Get the header associated with a table row, if available. This
1678 differs from getRowDescription, which returns a string.
1680 the specified table row, zero-indexed.
1681 @return an Accessible representatin of the specified table row,
1684 func = self.get_dbus_method("getRowHeader")
1685 return func(*args, **kwargs)
1687 def getSelectedColumns(self, *args, **kwargs):
1689 Obtain the indices of all columns which are currently selected.
1690 @return a sequence of integers comprising the indices of columns
1693 func = self.get_dbus_method("getSelectedColumns")
1694 return func(*args, **kwargs)
1696 def getSelectedRows(self, *args, **kwargs):
1698 Obtain the indices of all rows which are currently selected.
1699 @return a sequence of integers comprising the indices of rows
1702 func = self.get_dbus_method("getSelectedRows")
1703 return func(*args, **kwargs)
1705 def isColumnSelected(self, *args, **kwargs):
1707 Determine whether a table column is selected.
1709 the column being queried.
1710 @return True if the specified column is currently selected, False
1713 func = self.get_dbus_method("isColumnSelected")
1714 return func(*args, **kwargs)
1716 def isRowSelected(self, *args, **kwargs):
1718 Determine whether a table row is selected.
1720 the row being queried.
1721 @return True if the specified row is currently selected, False
1724 func = self.get_dbus_method("isRowSelected")
1725 return func(*args, **kwargs)
1727 def isSelected(self, *args, **kwargs):
1729 Determine whether the cell at a specific row and column is selected.
1731 a row occupied by the cell whose state is being queried.
1733 a column occupied by the cell whose state is being queried.
1734 @return True if the specified cell is currently selected, False
1737 func = self.get_dbus_method("isSelected")
1738 return func(*args, **kwargs)
1740 def removeColumnSelection(self, *args, **kwargs):
1742 Remove the specified column from current column selection, if
1743 the table's selection model permits it.
1745 @return True if the specified column was successfully de-selected,
1748 func = self.get_dbus_method("removeColumnSelection")
1749 return func(*args, **kwargs)
1751 def removeRowSelection(self, *args, **kwargs):
1753 Remove the specified row from current row selection, if the table's
1754 selection model permits it.
1756 @return True if the specified row was successfully de-selected,
1759 func = self.get_dbus_method("removeRowSelection")
1760 return func(*args, **kwargs)
1762 def unImplemented(self, *args, **kwargs):
1763 func = self.get_dbus_method("unImplemented")
1764 return func(*args, **kwargs)
1766 def unImplemented2(self, *args, **kwargs):
1767 func = self.get_dbus_method("unImplemented2")
1768 return func(*args, **kwargs)
1770 def unImplemented3(self, *args, **kwargs):
1771 func = self.get_dbus_method("unImplemented3")
1772 return func(*args, **kwargs)
1774 def unImplemented4(self, *args, **kwargs):
1775 func = self.get_dbus_method("unImplemented4")
1776 return func(*args, **kwargs)
1778 def unImplemented5(self, *args, **kwargs):
1779 func = self.get_dbus_method("unImplemented5")
1780 return func(*args, **kwargs)
1782 def unImplemented6(self, *args, **kwargs):
1783 func = self.get_dbus_method("unImplemented6")
1784 return func(*args, **kwargs)
1786 def unImplemented7(self, *args, **kwargs):
1787 func = self.get_dbus_method("unImplemented7")
1788 return func(*args, **kwargs)
1790 def get_caption(self):
1791 self._pgetter(self._dbus_interface, "caption")
1792 def set_caption(self, value):
1793 self._psetter(self._dbus_interface, "caption", value)
1796 An Accessible which represents of a caption for a Table.
1798 caption = property(fget=get_caption, fset=set_caption, doc=_captionDoc)
1800 def get_nColumns(self):
1801 self._pgetter(self._dbus_interface, "nColumns")
1802 def set_nColumns(self, value):
1803 self._psetter(self._dbus_interface, "nColumns", value)
1806 The total number of columns in this table (including empty columns),
1807 exclusive of columns which are programmatically hidden. Columns
1808 which are scrolled out of view or clipped by the current viewport
1811 nColumns = property(fget=get_nColumns, fset=set_nColumns, doc=_nColumnsDoc)
1813 def get_nRows(self):
1814 self._pgetter(self._dbus_interface, "nRows")
1815 def set_nRows(self, value):
1816 self._psetter(self._dbus_interface, "nRows", value)
1819 The total number of rows in this table (including empty rows),
1820 exclusive of any rows which are programmatically hidden. Rows
1821 which are merely scrolled out of view are included.
1823 nRows = property(fget=get_nRows, fset=set_nRows, doc=_nRowsDoc)
1825 def get_nSelectedColumns(self):
1826 self._pgetter(self._dbus_interface, "nSelectedColumns")
1827 def set_nSelectedColumns(self, value):
1828 self._psetter(self._dbus_interface, "nSelectedColumns", value)
1829 _nSelectedColumnsDoc = \
1831 The number of columns currently selected. A selected column is
1832 one in which all included cells are selected.
1834 nSelectedColumns = property(fget=get_nSelectedColumns, fset=set_nSelectedColumns, doc=_nSelectedColumnsDoc)
1836 def get_nSelectedRows(self):
1837 self._pgetter(self._dbus_interface, "nSelectedRows")
1838 def set_nSelectedRows(self, value):
1839 self._psetter(self._dbus_interface, "nSelectedRows", value)
1840 _nSelectedRowsDoc = \
1842 The number of rows currently selected. A selected row is one
1843 in which all included cells are selected.
1845 nSelectedRows = property(fget=get_nSelectedRows, fset=set_nSelectedRows, doc=_nSelectedRowsDoc)
1847 def get_summary(self):
1848 self._pgetter(self._dbus_interface, "summary")
1849 def set_summary(self, value):
1850 self._psetter(self._dbus_interface, "summary", value)
1853 An accessible object which summarizes the contents of a Table.
1854 This object is frequently itself a Table instance, albeit a simplified
1857 summary = property(fget=get_summary, fset=set_summary, doc=_summaryDoc)
1862 BUTTON_PRESSED_EVENT = EventType(2)
1864 BUTTON_RELEASED_EVENT = EventType(3)
1866 KEY_PRESS = KeySynthType(0)
1868 KEY_PRESSED = KeyEventType(0)
1870 KEY_PRESSED_EVENT = EventType(0)
1872 KEY_PRESSRELEASE = KeySynthType(2)
1874 KEY_RELEASE = KeySynthType(1)
1876 KEY_RELEASED = KeyEventType(1)
1878 KEY_RELEASED_EVENT = EventType(1)
1880 KEY_STRING = KeySynthType(4)
1882 KEY_SYM = KeySynthType(3)
1885 MODIFIER_ALT = ModifierType(3)
1887 MODIFIER_CONTROL = ModifierType(2)
1889 MODIFIER_META = ModifierType(4)
1891 MODIFIER_META2 = ModifierType(5)
1893 MODIFIER_META3 = ModifierType(6)
1895 MODIFIER_NUMLOCK = ModifierType(7)
1897 MODIFIER_SHIFT = ModifierType(0)
1899 MODIFIER_SHIFTLOCK = ModifierType(1)