[orca: 1/2] Support synthesizing caps lock for double-orca support



commit 2583a7e5a81c3873ac918656b6a8e28b673e8402
Author: Samuel Thibault <samuel thibault ens-lyon org>
Date:   Wed Jun 13 18:40:27 2018 +0200

    Support synthesizing caps lock for double-orca support
    
    Fixes #2.

 help/C/howto_toggling_caps_lock.page |  4 +++-
 src/orca/input_event.py              | 28 +++++++++++++++++++++++++++-
 src/orca/orca.py                     |  4 ++--
 3 files changed, 32 insertions(+), 4 deletions(-)
---
diff --git a/help/C/howto_toggling_caps_lock.page b/help/C/howto_toggling_caps_lock.page
index d1d56cb0e..9f3e43adf 100644
--- a/help/C/howto_toggling_caps_lock.page
+++ b/help/C/howto_toggling_caps_lock.page
@@ -18,7 +18,9 @@
     impacts which key is used as the Orca Modifier. If you are using the Laptop
     layout, the default Orca Modifier will be <key>CapsLock</key>. If you are
     using <app>Orca</app>'s Laptop Layout and want to lock or unlock
-    <key>CapsLock</key>, you can do so by performing the following steps:
+    <key>CapsLock</key>, you can do so by either typing <key>CapsLock</key>
+    twice (requires at-spi2 version 2.30 or later), or by performing the
+    following steps:
   </p>
   <steps>
     <title>Toggling CapsLock in Laptop Layout</title>
diff --git a/src/orca/input_event.py b/src/orca/input_event.py
index 151e9565b..5e6f0ea48 100644
--- a/src/orca/input_event.py
+++ b/src/orca/input_event.py
@@ -341,7 +341,7 @@ class KeyboardEvent(InputEvent):
         if not self.event_string in lockingKeys:
             return False
 
-        if not orca_state.bypassNextCommand:
+        if not orca_state.bypassNextCommand and not self._bypassOrca:
             return not self.event_string in settings.orcaModifierKeys
 
         return True
@@ -635,6 +635,11 @@ class KeyboardEvent(InputEvent):
         """Processes this input event."""
 
         if self._bypassOrca:
+            if self.event_string == "Caps_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
@@ -675,6 +680,27 @@ class KeyboardEvent(InputEvent):
 
         return False, 'Unaddressed case'
 
+    def _lock_mod(self):
+        def lock_mod(modifiers):
+            def lockit():
+                try:
+                    modifier = (1 << pyatspi.MODIFIER_SHIFTLOCK)
+                    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.30 is needed for triggering capslock", True)
+                    pass
+            return lockit
+        debug.println(debug.LEVEL_INFO, "Scheduling capslock", True)
+        GLib.timeout_add(1, lock_mod(self.modifiers))
+
     def _consume(self):
         startTime = time.time()
         data = "'%s' (%d)" % (self.event_string, self.hw_code)
diff --git a/src/orca/orca.py b/src/orca/orca.py
index 6ab39224d..7057a0e90 100644
--- a/src/orca/orca.py
+++ b/src/orca/orca.py
@@ -249,11 +249,11 @@ def _setCapsLockAsOrcaModifier(enable):
     interpretCapsLineProg = re.compile(
         r'^\s*interpret\s+Caps[_+]Lock[_+]AnyOfOrNone\s*\(all\)\s*{\s*$', re.I)
     capsModLineProg = re.compile(
-        r'^\s*action\s*=\s*SetMods\s*\(\s*modifiers\s*=\s*Lock\s*,\s*clearLocks\s*\)\s*;\s*$', re.I)
+        r'^\s*action\s*=\s*NoAction\s*\(\s*\)\s*;\s*$', re.I)
     normalCapsLineProg = re.compile(
         r'^\s*action\s*=\s*LockMods\s*\(\s*modifiers\s*=\s*Lock\s*\)\s*;\s*$', re.I)
     normalCapsLine = '        action= LockMods(modifiers=Lock);'
-    capsModLine =    '        action= SetMods(modifiers=Lock,clearLocks);'
+    capsModLine =    '        action= NoAction();'
     lines = _originalXmodmap.decode('UTF-8').split('\n')
     foundCapsInterpretSection = False
     for i, line in enumerate(lines):


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]