1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
from accerciser.plugin import Plugin
from accerciser.i18n import N_, _
import gtk
import pyatspi
import wnck
class QuickSelect(Plugin):
'''
Plugin class for quick select.
'''
plugin_name = N_('Quick Select')
plugin_name_localized = _(plugin_name)
plugin_description = \
N_('Plugin with various methods of selecting accessibles quickly.')
def init(self):
'''
Initialize plugin.
'''
self.global_hotkeys = [(N_('Inspect last focused accessible'),
self._inspectLastFocused,
gtk.keysyms.a,
gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK),
(N_('Inspect accessible under mouse'),
self._inspectUnderMouse,
gtk.keysyms.question,
gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK)]
pyatspi.Registry.registerEventListener(self._accEventFocusChanged,
'focus')
self.last_focused = None
def _accEventFocusChanged(self, event):
'''
Hold a reference for the last focused accessible. This is used when a certain
global hotkey is pressed to select this accessible.
@param event: The event that is being handled.
@type event: L{pyatspi.event.Event}
'''
if not self.isMyApp(event.source):
self.last_focused = event.source
def _inspectLastFocused(self):
'''
Inspect the last focused widget's accessible.
'''
if self.last_focused:
self.node.update(self.last_focused)
def _inspectUnderMouse(self):
'''
Inspect accessible of widget under mouse.
'''
# Inspect accessible under mouse
display = gtk.gdk.Display(gtk.gdk.get_display())
screen, x, y, flags = display.get_pointer()
desktop = pyatspi.Registry.getDesktop(0)
wnck_screen = wnck.screen_get_default()
window_order = [w.get_name() for w in wnck_screen.get_windows_stacked()]
top_window = (None, -1)
for app in desktop:
if not app or self.isMyApp(app):
continue
for frame in app:
if not frame:
continue
acc = self._getChildAccAtCoords(frame, x, y)
if acc:
try:
z_order = window_order.index(frame.name)
except ValueError:
continue
if z_order > top_window[1]:
top_window = (acc, z_order)
if top_window[0]:
self.node.update(top_window[0])
def _getChildAccAtCoords(self, parent, x, y):
'''
Gets any child accessible that resides under given desktop coordinates.
@param parent: Top-level accessible.
@type parent: L{Accessibility.Accessible}
@param x: X coordinate.
@type x: integer
@param y: Y coordinate.
@type y: integer
@return: Child accessible at given coordinates, or None.
@rtype: L{Accessibility.Accessible}
'''
container = parent
while True:
try:
ci = container.queryComponent()
except:
return None
else:
inner_container = container
container = ci.getAccessibleAtPoint(x, y, pyatspi.DESKTOP_COORDS)
if not container or container.queryComponent() == ci:
# The gecko bridge simply has getAccessibleAtPoint return itself
# if there are no further children
break
if inner_container == parent:
return None
else:
return inner_container
|