Viewing file: keybindings.py (5.35 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Orca # # Copyright 2005 Sun Microsystems Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA.
"""Provides support for defining keybindings and matching them to input events."""
__id__ = "$Id: keybindings.py,v 1.8 2006/07/28 17:57:16 richb Exp $" __version__ = "$Revision: 1.8 $" __date__ = "$Date: 2006/07/28 17:57:16 $" __copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc." __license__ = "LGPL"
try: # This can fail due to gtk not being available. We want to # be able to recover from that if possible. The main driver # for this is to allow "orca --text-setup" to work even if # the desktop is not running. # import gtk except: pass
import atspi import debug
_keycodeCache = {}
def _getKeycode(keysym): """Converts an XKeysym string (e.g., 'KP_Enter') to a keycode that should match the event.hw_code for key events.
Arguments: - keysym: a string that is a valid representation of an XKeysym.
Returns an integer representing a key code that should match the event.hw_code for key events. """
if not _keycodeCache.has_key(keysym): keymap = gtk.gdk.keymap_get_default() entries = keymap.get_entries_for_keyval( gtk.gdk.keyval_from_name(keysym)) if entries: _keycodeCache[keysym] = entries[0][0] else: _keycodeCache[keysym] = 0 return _keycodeCache[keysym]
class KeyBinding: """A single key binding, consisting of a keycode, a modifier mask, and the InputEventHandler. """
def __init__(self, keysymstring, modifier_mask, modifiers, handler): """Creates a new key binding.
Arguments: - keysymstring: the keysymstring - this is typically a string from /usr/include/X11/keysymdef.h with the preceding 'XK_' removed (e.g., XK_KP_Enter becomes the string 'KP_Enter'). - modifier_mask: bit mask where a set bit tells us what modifiers we care about (see atspi.Accessibility.MODIFIER_*) - modifiers: the state the modifiers we care about must be in for this key binding to match an input event (see also atspi.Accessibility.MODIFIER_*) - handler: the InputEventHandler for this key binding """
self.keysymstring = keysymstring self.modifier_mask = modifier_mask self.modifiers = modifiers self.handler = handler self.keycode = None
def matches(self, keycode, modifiers): """Returns true if this key binding matches the given keycode and modifier state. """
# We lazily bind the keycode. The primary reason for doing this # is so that atspi does not have to be initialized before setting # keybindings in the user's preferences file. # if not self.keycode: self.keycode = _getKeycode(self.keysymstring)
if self.keycode == keycode: result = modifiers & self.modifier_mask return result == self.modifiers else: return False
class KeyBindings: """Structure that maintains a set of KeyBinding instances. """
def __init__(self): self.keyBindings = []
def add(self, keyBinding): """Adds the given KeyBinding instance to this set of keybindings. """
self.keyBindings.append(keyBinding)
def remove(self, keyBinding): """Removes the given KeyBinding instance from this set of keybindings. """
for i in range(0, len(self.keyBindings)): if keyBinding == self.keyBindings[i]: del self.keyBindings[i]
def getInputHandler(self, keyboardEvent): """Returns the input handler of the key binding that matches the given keycode and modifiers, or None if no match exists. """ handler = None for keyBinding in self.keyBindings: if keyBinding.matches(keyboardEvent.hw_code, \ keyboardEvent.modifiers): handler = keyBinding.handler break return handler
def consumeKeyboardEvent(self, script, keyboardEvent): """Attempts to consume the given keyboard event. If these keybindings have a handler for the given keyboardEvent, it is assumed the event will always be consumed. """
consumed = False handler = self.getInputHandler(keyboardEvent) if handler: consumed = True if keyboardEvent.type == atspi.Accessibility.KEY_PRESSED_EVENT: try: handler.processInputEvent(script, keyboardEvent) except: debug.printException(debug.LEVEL_SEVERE)
return consumed
|