Файловый менеджер - Редактировать - /usr/lib/python3/dist-packages/orca/input_event.py
Назад
# Orca # # Copyright 2005-2008 Sun Microsystems Inc. # Copyright 2011-2016 Igalia, S.L. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 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 # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., Franklin Street, Fifth Floor, # Boston MA 02110-1301 USA. """Provides support for handling input events.""" __id__ = "$Id$" __version__ = "$Revision$" __date__ = "$Date$" __copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ "Copyright (c) 2011-2016 Igalia, S.L." __license__ = "LGPL" import math import pyatspi import time from gi.repository import Gdk from gi.repository import GLib from . import debug from . import keybindings from . import keynames from . import messages from . import orca_state from . import script_manager from . import settings KEYBOARD_EVENT = "keyboard" BRAILLE_EVENT = "braille" MOUSE_BUTTON_EVENT = "mouse:button" class InputEvent: def __init__(self, eventType): """Creates a new KEYBOARD_EVENT, BRAILLE_EVENT, or MOUSE_BUTTON_EVENT.""" self.type = eventType self.time = time.time() self._clickCount = 0 def getClickCount(self): """Return the count of the number of clicks a user has made.""" return self._clickCount def setClickCount(self): """Updates the count of the number of clicks a user has made.""" pass class KeyboardEvent(InputEvent): duplicateCount = 0 orcaModifierPressed = False # Whether last press of the Orca modifier was alone lastOrcaModifierAlone = False lastOrcaModifierAloneTime = None # Whether the current press of the Orca modifier is alone currentOrcaModifierAlone = False currentOrcaModifierAloneTime = None # When the second orca press happened secondOrcaModifierTime = None TYPE_UNKNOWN = "unknown" TYPE_PRINTABLE = "printable" TYPE_MODIFIER = "modifier" TYPE_LOCKING = "locking" TYPE_FUNCTION = "function" TYPE_ACTION = "action" TYPE_NAVIGATION = "navigation" TYPE_DIACRITICAL = "diacritical" TYPE_ALPHABETIC = "alphabetic" TYPE_NUMERIC = "numeric" TYPE_PUNCTUATION = "punctuation" TYPE_SPACE = "space" GDK_PUNCTUATION_KEYS = [Gdk.KEY_acute, Gdk.KEY_ampersand, Gdk.KEY_apostrophe, Gdk.KEY_asciicircum, Gdk.KEY_asciitilde, Gdk.KEY_asterisk, Gdk.KEY_at, Gdk.KEY_backslash, Gdk.KEY_bar, Gdk.KEY_braceleft, Gdk.KEY_braceright, Gdk.KEY_bracketleft, Gdk.KEY_bracketright, Gdk.KEY_brokenbar, Gdk.KEY_cedilla, Gdk.KEY_cent, Gdk.KEY_colon, Gdk.KEY_comma, Gdk.KEY_copyright, Gdk.KEY_currency, Gdk.KEY_degree, Gdk.KEY_diaeresis, Gdk.KEY_dollar, Gdk.KEY_EuroSign, Gdk.KEY_equal, Gdk.KEY_exclam, Gdk.KEY_exclamdown, Gdk.KEY_grave, Gdk.KEY_greater, Gdk.KEY_guillemotleft, Gdk.KEY_guillemotright, Gdk.KEY_hyphen, Gdk.KEY_less, Gdk.KEY_macron, Gdk.KEY_minus, Gdk.KEY_notsign, Gdk.KEY_numbersign, Gdk.KEY_paragraph, Gdk.KEY_parenleft, Gdk.KEY_parenright, Gdk.KEY_percent, Gdk.KEY_period, Gdk.KEY_periodcentered, Gdk.KEY_plus, Gdk.KEY_plusminus, Gdk.KEY_question, Gdk.KEY_questiondown, Gdk.KEY_quotedbl, Gdk.KEY_quoteleft, Gdk.KEY_quoteright, Gdk.KEY_registered, Gdk.KEY_section, Gdk.KEY_semicolon, Gdk.KEY_slash, Gdk.KEY_sterling, Gdk.KEY_underscore, Gdk.KEY_yen] GDK_ACCENTED_LETTER_KEYS = [Gdk.KEY_Aacute, Gdk.KEY_aacute, Gdk.KEY_Acircumflex, Gdk.KEY_acircumflex, Gdk.KEY_Adiaeresis, Gdk.KEY_adiaeresis, Gdk.KEY_Agrave, Gdk.KEY_agrave, Gdk.KEY_Aring, Gdk.KEY_aring, Gdk.KEY_Atilde, Gdk.KEY_atilde, Gdk.KEY_Ccedilla, Gdk.KEY_ccedilla, Gdk.KEY_Eacute, Gdk.KEY_eacute, Gdk.KEY_Ecircumflex, Gdk.KEY_ecircumflex, Gdk.KEY_Ediaeresis, Gdk.KEY_ediaeresis, Gdk.KEY_Egrave, Gdk.KEY_egrave, Gdk.KEY_Iacute, Gdk.KEY_iacute, Gdk.KEY_Icircumflex, Gdk.KEY_icircumflex, Gdk.KEY_Idiaeresis, Gdk.KEY_idiaeresis, Gdk.KEY_Igrave, Gdk.KEY_igrave, Gdk.KEY_Ntilde, Gdk.KEY_ntilde, Gdk.KEY_Oacute, Gdk.KEY_oacute, Gdk.KEY_Ocircumflex, Gdk.KEY_ocircumflex, Gdk.KEY_Odiaeresis, Gdk.KEY_odiaeresis, Gdk.KEY_Ograve, Gdk.KEY_ograve, Gdk.KEY_Ooblique, Gdk.KEY_ooblique, Gdk.KEY_Otilde, Gdk.KEY_otilde, Gdk.KEY_Uacute, Gdk.KEY_uacute, Gdk.KEY_Ucircumflex, Gdk.KEY_ucircumflex, Gdk.KEY_Udiaeresis, Gdk.KEY_udiaeresis, Gdk.KEY_Ugrave, Gdk.KEY_ugrave, Gdk.KEY_Yacute, Gdk.KEY_yacute] def __init__(self, event): """Creates a new InputEvent of type KEYBOARD_EVENT. Arguments: - event: the AT-SPI keyboard event """ super().__init__(KEYBOARD_EVENT) self.id = event.id self.type = event.type self.hw_code = event.hw_code self.modifiers = event.modifiers self.event_string = event.event_string self.keyval_name = Gdk.keyval_name(event.id) self.timestamp = event.timestamp self.is_duplicate = self in [orca_state.lastInputEvent, orca_state.lastNonModifierKeyEvent] self._script = orca_state.activeScript self._app = None self._window = orca_state.activeWindow self._obj = orca_state.locusOfFocus self._handler = None self._consumer = None self._should_consume = None self._consume_reason = None self._did_consume = None self._result_reason = None self._bypassOrca = None # Some implementors don't populate this field at all. More often than not, # the event_string and the keyval_name coincide for input events. if not self.event_string: self.event_string = self.keyval_name # Some implementors do populate the field, but with the keyname rather than # the printable character. This messes us up with punctuation and other symbols. if len(self.event_string) > 1 \ and (self.id in KeyboardEvent.GDK_PUNCTUATION_KEYS or \ self.id in KeyboardEvent.GDK_ACCENTED_LETTER_KEYS): self.event_string = chr(self.id) if self._script: self._app = self._script.app if not self._window: self._window = orca_state.activeWindow = self._script.utilities.activeWindow() msg = 'INPUT EVENT: Updated window and active window to %s' % self._window debug.println(debug.LEVEL_INFO, msg, True) if self._window and self._app != self._window.getApplication(): self._script = script_manager.getManager().getScript(self._window.getApplication()) self._app = self._script.app msg = 'INPUT EVENT: Updated script to %s' % self._script debug.println(debug.LEVEL_INFO, msg, True) if self.is_duplicate: KeyboardEvent.duplicateCount += 1 else: KeyboardEvent.duplicateCount = 0 self.keyType = None _isPressed = event.type == pyatspi.KEY_PRESSED_EVENT try: role = self._obj.getRole() except: role = None _mayEcho = _isPressed or role == pyatspi.ROLE_TERMINAL if not self.isOrcaModifier(): if KeyboardEvent.orcaModifierPressed: KeyboardEvent.currentOrcaModifierAlone = False KeyboardEvent.currentOrcaModifierAloneTime = None else: KeyboardEvent.lastOrcaModifierAlone = False KeyboardEvent.lastOrcaModifierAloneTime = None if self.isNavigationKey(): self.keyType = KeyboardEvent.TYPE_NAVIGATION self.shouldEcho = _mayEcho and settings.enableNavigationKeys elif self.isActionKey(): self.keyType = KeyboardEvent.TYPE_ACTION self.shouldEcho = _mayEcho and settings.enableActionKeys elif self.isModifierKey(): self.keyType = KeyboardEvent.TYPE_MODIFIER self.shouldEcho = _mayEcho and settings.enableModifierKeys if self.isOrcaModifier(): now = time.time() if KeyboardEvent.lastOrcaModifierAlone: if _isPressed: KeyboardEvent.secondOrcaModifierTime = now if KeyboardEvent.secondOrcaModifierTime < KeyboardEvent.lastOrcaModifierAloneTime + 0.5: # double-orca, let the real action happen self._bypassOrca = True if not _isPressed: KeyboardEvent.lastOrcaModifierAlone = False KeyboardEvent.lastOrcaModifierAloneTime = False else: KeyboardEvent.orcaModifierPressed = _isPressed if _isPressed: KeyboardEvent.currentOrcaModifierAlone = True KeyboardEvent.currentOrcaModifierAloneTime = now else: KeyboardEvent.lastOrcaModifierAlone = KeyboardEvent.currentOrcaModifierAlone KeyboardEvent.lastOrcaModifierAloneTime = KeyboardEvent.currentOrcaModifierAloneTime elif self.isFunctionKey(): self.keyType = KeyboardEvent.TYPE_FUNCTION self.shouldEcho = _mayEcho and settings.enableFunctionKeys elif self.isDiacriticalKey(): self.keyType = KeyboardEvent.TYPE_DIACRITICAL self.shouldEcho = _mayEcho and settings.enableDiacriticalKeys elif self.isLockingKey(): self.keyType = KeyboardEvent.TYPE_LOCKING self.shouldEcho = settings.presentLockingKeys if self.shouldEcho is None: self.shouldEcho = not settings.onlySpeakDisplayedText self.shouldEcho = self.shouldEcho and _isPressed elif self.isAlphabeticKey(): self.keyType = KeyboardEvent.TYPE_ALPHABETIC self.shouldEcho = _mayEcho \ and (settings.enableAlphabeticKeys or settings.enableEchoByCharacter) elif self.isNumericKey(): self.keyType = KeyboardEvent.TYPE_NUMERIC self.shouldEcho = _mayEcho \ and (settings.enableNumericKeys or settings.enableEchoByCharacter) elif self.isPunctuationKey(): self.keyType = KeyboardEvent.TYPE_PUNCTUATION self.shouldEcho = _mayEcho \ and (settings.enablePunctuationKeys or settings.enableEchoByCharacter) elif self.isSpace(): self.keyType = KeyboardEvent.TYPE_SPACE self.shouldEcho = _mayEcho \ and (settings.enableSpace or settings.enableEchoByCharacter) else: self.keyType = KeyboardEvent.TYPE_UNKNOWN self.shouldEcho = False if not self.isLockingKey(): self.shouldEcho = self.shouldEcho and settings.enableKeyEcho if not self.isModifierKey(): self.setClickCount() if orca_state.bypassNextCommand and _isPressed: KeyboardEvent.orcaModifierPressed = False if KeyboardEvent.orcaModifierPressed: self.modifiers |= keybindings.ORCA_MODIFIER_MASK self._should_consume, self._consume_reason = self.shouldConsume() def setClickCount(self): """Updates the count of the number of clicks a user has made.""" lastEvent = orca_state.lastNonModifierKeyEvent if not isinstance(lastEvent, KeyboardEvent) \ or lastEvent.event_string != self.event_string \ or self.time - lastEvent.time > settings.doubleClickTimeout: self._clickCount = 1 return self._clickCount = lastEvent.getClickCount() if self.is_duplicate: return if self.type == pyatspi.KEY_RELEASED_EVENT: return if self._clickCount < 3: self._clickCount += 1 return self._clickCount = 1 def __eq__(self, other): if not other: return False if self.type == other.type and self.hw_code == other.hw_code: return self.timestamp == other.timestamp return False def __str__(self): return ("KEYBOARD_EVENT: type=%d\n" % self.type) \ + (" id=%d\n" % self.id) \ + (" hw_code=%d\n" % self.hw_code) \ + (" modifiers=%d\n" % self.modifiers) \ + (" event_string=(%s)\n" % self.event_string) \ + (" keyval_name=(%s)\n" % self.keyval_name) \ + (" timestamp=%d\n" % self.timestamp) \ + (" time=%f\n" % time.time()) \ + (" keyType=%s\n" % self.keyType) \ + (" clickCount=%s\n" % self._clickCount) \ + (" shouldEcho=%s\n" % self.shouldEcho) def _isReleaseForLastNonModifierKeyEvent(self): last = orca_state.lastNonModifierKeyEvent if not last: return False if not last.isPressedKey() or self.isPressedKey(): return False if self.id == last.id and self.hw_code == last.hw_code: return self.modifiers == last.modifiers return False def isReleaseFor(self, other): """Return True if this is the release event for other.""" if not other: return False if not other.isPressedKey() or self.isPressedKey(): return False return self.id == other.id \ and self.hw_code == other.hw_code \ and self.modifiers == other.modifiers \ and self.event_string == other.event_string \ and self.keyval_name == other.keyval_name \ and self.keyType == other.keyType \ and self._clickCount == other._clickCount def isNavigationKey(self): """Return True if this is a navigation key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_NAVIGATION return self.event_string in \ ["Left", "Right", "Up", "Down", "Home", "End"] def isActionKey(self): """Return True if this is an action key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_ACTION return self.event_string in \ ["Return", "Escape", "Tab", "BackSpace", "Delete", "Page_Up", "Page_Down"] def isAlphabeticKey(self): """Return True if this is an alphabetic key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_ALPHABETIC if not len(self.event_string) == 1: return False return self.event_string.isalpha() def isDiacriticalKey(self): """Return True if this is a non-spacing diacritical key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_DIACRITICAL return self.event_string.startswith("dead_") def isFunctionKey(self): """Return True if this is a function key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_FUNCTION return self.event_string in \ ["F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"] def isLockingKey(self): """Return True if this is a locking key.""" if self.keyType: return self.keyType in KeyboardEvent.TYPE_LOCKING lockingKeys = ["Caps_Lock", "Shift_Lock", "Num_Lock", "Scroll_Lock"] if not self.event_string in lockingKeys: return False if not orca_state.bypassNextCommand and not self._bypassOrca: return not self.event_string in settings.orcaModifierKeys return True def isModifierKey(self): """Return True if this is a modifier key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_MODIFIER if self.isOrcaModifier(): return True return self.event_string in \ ['Alt_L', 'Alt_R', 'Control_L', 'Control_R', 'Shift_L', 'Shift_R', 'Meta_L', 'Meta_R', 'ISO_Level3_Shift'] def isNumericKey(self): """Return True if this is a numeric key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_NUMERIC if not len(self.event_string) == 1: return False return self.event_string.isnumeric() def isOrcaModifier(self, checkBypassMode=True): """Return True if this is the Orca modifier key.""" if checkBypassMode and orca_state.bypassNextCommand: return False if self.event_string in settings.orcaModifierKeys: return True if self.keyval_name == "KP_0" \ and "KP_Insert" in settings.orcaModifierKeys \ and self.modifiers & keybindings.SHIFT_MODIFIER_MASK: return True return False def isOrcaModified(self): """Return True if this key is Orca modified.""" if orca_state.bypassNextCommand: return False return self.modifiers & keybindings.ORCA_MODIFIER_MASK def isPrintableKey(self): """Return True if this is a printable key.""" if self.event_string in ["space", " "]: return True if not len(self.event_string) == 1: return False return self.event_string.isprintable() def isPressedKey(self): """Returns True if the key is pressed""" return self.type == pyatspi.KEY_PRESSED_EVENT def isPunctuationKey(self): """Return True if this is a punctuation key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_PUNCTUATION if not len(self.event_string) == 1: return False if self.isAlphabeticKey() or self.isNumericKey(): return False return self.event_string.isprintable() and not self.event_string.isspace() def isSpace(self): """Return True if this is the space key.""" if self.keyType: return self.keyType == KeyboardEvent.TYPE_SPACE return self.event_string in ["space", " "] def isFromApplication(self, app): """Return True if this is associated with the specified app.""" return self._app == app def isCharacterEchoable(self): """Returns True if the script will echo this event as part of character echo. We do this to not double-echo a given printable character.""" if not self.isPrintableKey(): return False if orca_state.learnModeEnabled: return False script = orca_state.activeScript return script and script.utilities.willEchoCharacter(self) def getLockingState(self): """Returns True if the event locked a locking key, False if the event unlocked a locking key, and None if we do not know or this is not a locking key.""" if not self.isLockingKey(): return None if self.event_string == "Caps_Lock": mod = pyatspi.MODIFIER_SHIFTLOCK elif self.event_string == "Shift_Lock": mod = pyatspi.MODIFIER_SHIFT elif self.event_string == "Num_Lock": mod = pyatspi.MODIFIER_NUMLOCK else: return None return not self.modifiers & (1 << mod) def getLockingStateString(self): """Returns the string which reflects the locking state we wish to include when presenting a locking key.""" locked = self.getLockingState() if locked is None: return '' if not locked: return messages.LOCKING_KEY_STATE_OFF return messages.LOCKING_KEY_STATE_ON def getKeyName(self): """Returns the string to be used for presenting the key to the user.""" return keynames.getKeyName(self.event_string) def getObject(self): """Returns the object believed to be associated with this key event.""" return self._obj def _getUserHandler(self): # TODO - JD: This should go away once plugin support is in place. try: bindings = settings.keyBindingsMap.get(self._script.__module__) except: bindings = None if not bindings: try: bindings = settings.keyBindingsMap.get("default") except: bindings = None try: handler = bindings.getInputHandler(self) except: handler = None return handler def shouldConsume(self): """Returns True if this event should be consumed.""" if not self.timestamp: return False, 'No timestamp' if not self._script: return False, 'No active script when received' if self.is_duplicate: return False, 'Is duplicate' if orca_state.capturingKeys: return False, 'Capturing keys' if orca_state.bypassNextCommand: return False, 'Bypass next command' self._handler = self._getUserHandler() \ or self._script.keyBindings.getInputHandler(self) # TODO - JD: Right now we need to always call consumesKeyboardEvent() # because that method is updating state, even in instances where there # is no handler. scriptConsumes = self._script.consumesKeyboardEvent(self) if self._isReleaseForLastNonModifierKeyEvent(): return scriptConsumes, 'Is release for last non-modifier keyevent' if orca_state.learnModeEnabled: if self.event_string == 'Escape': self._consumer = self._script.exitLearnMode return True, 'Exiting Learn Mode' if self.event_string == 'F1' and not self.modifiers: self._consumer = self._script.showHelp return True, 'Showing Help' if self.event_string in ['F2', 'F3'] and not self.modifiers: self._consumer = self._script.listOrcaShortcuts return True, 'Listing shortcuts' self._consumer = self._presentHandler return True, 'In Learn Mode' if self.isModifierKey(): if not self.isOrcaModifier(): return False, 'Non-Orca modifier not in Learn Mode' return True, 'Orca modifier' if orca_state.listNotificationsModeEnabled: self._consumer = self._script.listNotifications return True, 'Listing notifications' if not self._handler: return False, 'No handler' return scriptConsumes, 'Script indication' def didConsume(self): """Returns True if this event was consumed.""" if self._did_consume is not None: return self._did_consume return False def isHandledBy(self, method): if not self._handler: return False return method.__func__ == self._handler.function def _present(self, inputEvent=None): if self.isPressedKey(): self._script.presentationInterrupt() return self._script.presentKeyboardEvent(self) def _presentHandler(self, input_event=None): if not self._handler: return False if self._handler.learnModeEnabled and self._handler.description: self._script.presentMessage(self._handler.description) return True def process(self): """Processes this input event.""" startTime = time.time() data = "'%s' (%d)" % (self.event_string, self.hw_code) if self.is_duplicate: data = '%s DUPLICATE EVENT #%i' % (data, KeyboardEvent.duplicateCount) msg = '\nvvvvv PROCESS %s: %s vvvvv' % (self.type.value_name.upper(), data) debug.println(debug.LEVEL_INFO, msg, False) msg = 'HOST_APP: %s' % self._app debug.println(debug.LEVEL_INFO, msg, True) msg = 'WINDOW: %s' % self._window debug.println(debug.LEVEL_INFO, msg, True) msg = 'LOCATION: %s' % self._obj debug.println(debug.LEVEL_INFO, msg, True) msg = 'CONSUME: %s (%s)' % (self._should_consume, self._consume_reason) debug.println(debug.LEVEL_INFO, msg, True) self._did_consume, self._result_reason = self._process() if self._should_consume != self._did_consume: msg = 'CONSUMED: %s (%s)' % (self._did_consume, self._result_reason) debug.println(debug.LEVEL_INFO, msg, True) msg = 'TOTAL PROCESSING TIME: %.4f' % (time.time() - startTime) debug.println(debug.LEVEL_INFO, msg, True) msg = '^^^^^ PROCESS %s: %s ^^^^^\n' % (self.type.value_name.upper(), data) debug.println(debug.LEVEL_INFO, msg, False) return self._did_consume def _process(self): """Processes this input event.""" if self._bypassOrca: if (self.event_string == "Caps_Lock" \ or self.event_string == "Shift_Lock") \ and self.type == pyatspi.KEY_PRESSED_EVENT: self._lock_mod() self.keyType = KeyboardEvent.TYPE_LOCKING self._present() return False, 'Bypassed orca modifier' orca_state.lastInputEvent = self if not self.isModifierKey(): orca_state.lastNonModifierKeyEvent = self if not self._script: return False, 'No active script' if self.is_duplicate: return False, 'Is duplicate' self._present() if not self.isPressedKey(): return self._should_consume, 'Consumed based on handler' if orca_state.capturingKeys: return False, 'Capturing keys' if self.isOrcaModifier(): return True, 'Orca modifier' if orca_state.bypassNextCommand: if not self.isModifierKey(): orca_state.bypassNextCommand = False return False, 'Bypass next command' if not self._should_consume: return False, 'Should not consume' if not (self._consumer or self._handler): return False, 'No consumer or handler' if self._consumer or self._handler.function: GLib.timeout_add(1, self._consume) return True, 'Will be consumed' return False, 'Unaddressed case' def _lock_mod(self): def lock_mod(modifiers, modifier): def lockit(): try: if modifiers & modifier: lock = pyatspi.KEY_UNLOCKMODIFIERS debug.println(debug.LEVEL_INFO, "Locking capslock", True) else: lock = pyatspi.KEY_LOCKMODIFIERS debug.println(debug.LEVEL_INFO, "Unlocking capslock", True) pyatspi.Registry.generateKeyboardEvent(modifier, None, lock) debug.println(debug.LEVEL_INFO, "Done with capslock", True) except: debug.println(debug.LEVEL_INFO, "Could not trigger capslock, " \ "at-spi2-core >= 2.32 is needed for triggering capslock", True) pass return lockit if self.event_string == "Caps_Lock": modifier = 1 << pyatspi.MODIFIER_SHIFTLOCK elif self.event_string == "Shift_Lock": modifier = 1 << pyatspi.MODIFIER_SHIFT else: msg = "Unknown locking key %s" % self.event_string debug.println(debug.LEVEL_WARNING, msg, True) return debug.println(debug.LEVEL_INFO, "Scheduling capslock", True) GLib.timeout_add(1, lock_mod(self.modifiers, modifier)) def _consume(self): startTime = time.time() data = "'%s' (%d)" % (self.event_string, self.hw_code) msg = 'vvvvv CONSUME %s: %s vvvvv' % (self.type.value_name.upper(), data) debug.println(debug.LEVEL_INFO, msg, False) if self._consumer: msg = 'INFO: Consumer is %s' % self._consumer.__name__ debug.println(debug.LEVEL_INFO, msg, True) self._consumer(self) elif self._handler.function: msg = 'INFO: Handler is %s' % self._handler.description debug.println(debug.LEVEL_INFO, msg, True) self._handler.function(self._script, self) else: msg = 'INFO: No handler or consumer' debug.println(debug.LEVEL_INFO, msg, True) msg = 'TOTAL PROCESSING TIME: %.4f' % (time.time() - startTime) debug.println(debug.LEVEL_INFO, msg, True) msg = '^^^^^ CONSUME %s: %s ^^^^^' % (self.type.value_name.upper(), data) debug.println(debug.LEVEL_INFO, msg, False) return False class BrailleEvent(InputEvent): def __init__(self, event): """Creates a new InputEvent of type BRAILLE_EVENT. Arguments: - event: the integer BrlTTY command for this event. """ super().__init__(BRAILLE_EVENT) self.event = event class MouseButtonEvent(InputEvent): try: display = Gdk.Display.get_default() seat = Gdk.Display.get_default_seat(display) _pointer = seat.get_pointer() except: _pointer = None def __init__(self, event): """Creates a new InputEvent of type MOUSE_BUTTON_EVENT.""" super().__init__(MOUSE_BUTTON_EVENT) self.x = event.detail1 self.y = event.detail2 self.pressed = event.type.endswith('p') self.button = event.type[len("mouse:button:"):-1] self._script = orca_state.activeScript self.window = orca_state.activeWindow self.obj = None if self.pressed: self._validateCoordinates() if not self._script: return if not self._script.utilities.canBeActiveWindow(self.window): self.window = self._script.utilities.activeWindow() if not self.window: return self.obj = self._script.utilities.descendantAtPoint( self.window, self.x, self.y, event.any_data) def _validateCoordinates(self): if not self._pointer: return screen, x, y = self._pointer.get_position() if math.sqrt((self.x - x)**2 + (self.y - y)**2) < 25: return msg = "WARNING: Event coordinates (%i, %i) may be bogus. " \ "Updating to (%i, %i)." % (self.x, self.y, x, y) debug.println(debug.LEVEL_INFO, msg, True) self.x, self.y = x, y def setClickCount(self): """Updates the count of the number of clicks a user has made.""" if not self.pressed: return lastInputEvent = orca_state.lastInputEvent if not isinstance(lastInputEvent, MouseButtonEvent): self._clickCount = 1 return if self.time - lastInputEvent.time < settings.doubleClickTimeout \ and lastInputEvent.button == self.button: if self._clickCount < 2: self._clickCount += 1 return self._clickCount = 1 class InputEventHandler: def __init__(self, function, description, learnModeEnabled=True): """Creates a new InputEventHandler instance. All bindings (e.g., key bindings and braille bindings) will be handled by an instance of an InputEventHandler. Arguments: - function: the function to call with an InputEvent instance as its sole argument. The function is expected to return True if it consumes the event; otherwise it should return False - description: a localized string describing what this InputEvent does - learnModeEnabled: if True, the description will be spoken and brailled if learn mode is enabled. If False, the function will be called no matter what. """ self.function = function self.description = description self.learnModeEnabled = learnModeEnabled def __eq__(self, other): """Compares one input handler to another.""" if not other: return False return (self.function == other.function) def processInputEvent(self, script, inputEvent): """Processes an input event. If learnModeEnabled is True, this will merely present the description of the input event via If learnModeEnabled is False, this will call the function bound to this InputEventHandler instance, passing the inputEvent as the sole argument to the function. This function is expected to return True if it consumes the event; otherwise it is expected to return False. Arguments: - script: the script (if any) associated with this event - inputEvent: the input event to pass to the function bound to this InputEventHandler instance. """ consumed = False if orca_state.learnModeEnabled and self._learnModeEnabled: if self.description: script.presentMessage(self.description) consumed = True else: try: consumed = self.function(script, inputEvent) except: debug.printException(debug.LEVEL_SEVERE) return consumed
| ver. 1.4 |
Github
|
.
| PHP 7.4.3-4ubuntu2.28 | Генерация страницы: 0.02 |
proxy
|
phpinfo
|
Настройка