Attempt to handle capslock as modifier better.
This commit is contained in:
+5
-141
@@ -186,9 +186,7 @@ class APIHelper:
|
||||
import gi
|
||||
import importlib
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
gi.require_version("Atspi", "2.0")
|
||||
@@ -212,6 +210,7 @@ from . import logger
|
||||
from . import messages
|
||||
from . import notification_presenter
|
||||
from . import focus_manager
|
||||
from . import cthulhu_modifier_manager
|
||||
from . import cthulhu_state
|
||||
from . import cthulhu_platform
|
||||
from . import script_manager
|
||||
@@ -280,14 +279,6 @@ EXIT_CODE_HANG = 50
|
||||
#
|
||||
_userSettings = None
|
||||
|
||||
# A subset of the original Xmodmap info prior to our stomping on it.
|
||||
# Right now, this is just for the user's chosen Cthulhu modifier(s).
|
||||
#
|
||||
_originalXmodmap = ""
|
||||
_cthulhuModifiers = settings.DESKTOP_MODIFIER_KEYS + settings.LAPTOP_MODIFIER_KEYS
|
||||
_capsLockCleared = False
|
||||
_restoreCthulhuKeys = False
|
||||
|
||||
########################################################################
|
||||
# #
|
||||
# METHODS TO HANDLE APPLICATION LIST AND FOCUSED OBJECTS #
|
||||
@@ -382,125 +373,7 @@ def deviceChangeHandler(deviceManager, device):
|
||||
if source == Gdk.InputSource.KEYBOARD:
|
||||
msg = "CTHULHU: Keyboard change detected, re-creating the xmodmap"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
_createCthulhuXmodmap()
|
||||
|
||||
def updateKeyMap(keyboardEvent):
|
||||
"""Unsupported convenience method to call sad hacks which should go away."""
|
||||
|
||||
global _restoreCthulhuKeys
|
||||
if keyboardEvent.is_pressed_key():
|
||||
return
|
||||
|
||||
if keyboardEvent.event_string in settings.cthulhuModifierKeys \
|
||||
and cthulhu_state.bypassNextCommand:
|
||||
_restoreXmodmap()
|
||||
_restoreCthulhuKeys = True
|
||||
return
|
||||
|
||||
if _restoreCthulhuKeys and not cthulhu_state.bypassNextCommand:
|
||||
_createCthulhuXmodmap()
|
||||
_restoreCthulhuKeys = False
|
||||
|
||||
def _setXmodmap(xkbmap):
|
||||
"""Set the keyboard map using xkbcomp."""
|
||||
p = subprocess.Popen(['xkbcomp', '-w0', '-', os.environ['DISPLAY']],
|
||||
stdin=subprocess.PIPE, stdout=None, stderr=None)
|
||||
p.communicate(xkbmap)
|
||||
|
||||
def _setCapsLockAsCthulhuModifier(enable):
|
||||
"""Enable or disable use of the caps lock key as an Cthulhu modifier key."""
|
||||
interpretCapsLineProg = re.compile(
|
||||
r'^\s*interpret\s+Caps[_+]Lock[_+]AnyOfOrNone\s*\(all\)\s*{\s*$', re.I)
|
||||
normalCapsLineProg = re.compile(
|
||||
r'^\s*action\s*=\s*LockMods\s*\(\s*modifiers\s*=\s*Lock\s*\)\s*;\s*$', re.I)
|
||||
interpretShiftLineProg = re.compile(
|
||||
r'^\s*interpret\s+Shift[_+]Lock[_+]AnyOf\s*\(\s*Shift\s*\+\s*Lock\s*\)\s*{\s*$', re.I)
|
||||
normalShiftLineProg = re.compile(
|
||||
r'^\s*action\s*=\s*LockMods\s*\(\s*modifiers\s*=\s*Shift\s*\)\s*;\s*$', re.I)
|
||||
disabledModLineProg = re.compile(
|
||||
r'^\s*action\s*=\s*NoAction\s*\(\s*\)\s*;\s*$', re.I)
|
||||
normalCapsLine = ' action= LockMods(modifiers=Lock);'
|
||||
normalShiftLine = ' action= LockMods(modifiers=Shift);'
|
||||
disabledModLine = ' action= NoAction();'
|
||||
lines = _originalXmodmap.decode('UTF-8').split('\n')
|
||||
foundCapsInterpretSection = False
|
||||
foundShiftInterpretSection = False
|
||||
modified = False
|
||||
for i, line in enumerate(lines):
|
||||
if not foundCapsInterpretSection and not foundShiftInterpretSection:
|
||||
if interpretCapsLineProg.match(line):
|
||||
foundCapsInterpretSection = True
|
||||
elif interpretShiftLineProg.match(line):
|
||||
foundShiftInterpretSection = True
|
||||
elif foundCapsInterpretSection:
|
||||
if enable:
|
||||
if normalCapsLineProg.match(line):
|
||||
lines[i] = disabledModLine
|
||||
modified = True
|
||||
else:
|
||||
if disabledModLineProg.match(line):
|
||||
lines[i] = normalCapsLine
|
||||
modified = True
|
||||
if line.find('}'):
|
||||
foundCapsInterpretSection = False
|
||||
else: # foundShiftInterpretSection
|
||||
if enable:
|
||||
if normalShiftLineProg.match(line):
|
||||
lines[i] = disabledModLine
|
||||
modified = True
|
||||
else:
|
||||
if disabledModLineProg.match(line):
|
||||
lines[i] = normalShiftLine
|
||||
modified = True
|
||||
if line.find('}'):
|
||||
foundShiftInterpretSection = False
|
||||
if modified:
|
||||
_setXmodmap(bytes('\n'.join(lines), 'UTF-8'))
|
||||
|
||||
def _createCthulhuXmodmap():
|
||||
"""Makes an Cthulhu-specific Xmodmap so that the keys behave as we
|
||||
need them to do. This is especially the case for the Cthulhu modifier.
|
||||
"""
|
||||
|
||||
global _capsLockCleared
|
||||
|
||||
if "Caps_Lock" in settings.cthulhuModifierKeys \
|
||||
or "Shift_Lock" in settings.cthulhuModifierKeys:
|
||||
_setCapsLockAsCthulhuModifier(True)
|
||||
_capsLockCleared = True
|
||||
elif _capsLockCleared:
|
||||
_setCapsLockAsCthulhuModifier(False)
|
||||
_capsLockCleared = False
|
||||
|
||||
def _storeXmodmap(keyList):
|
||||
"""Save the original xmodmap for the keys in keyList before we alter it.
|
||||
|
||||
Arguments:
|
||||
- keyList: A list of named keys to look for.
|
||||
"""
|
||||
|
||||
global _originalXmodmap
|
||||
_originalXmodmap = subprocess.check_output(['xkbcomp', os.environ['DISPLAY'], '-'])
|
||||
|
||||
def _restoreXmodmap(keyList=[]):
|
||||
"""Restore the original xmodmap values for the keys in keyList.
|
||||
|
||||
Arguments:
|
||||
- keyList: A list of named keys to look for. An empty list means
|
||||
to restore the entire saved xmodmap.
|
||||
"""
|
||||
|
||||
msg = "CTHULHU: Attempting to restore original xmodmap"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
global _capsLockCleared
|
||||
_capsLockCleared = False
|
||||
p = subprocess.Popen(['xkbcomp', '-w0', '-', os.environ['DISPLAY']],
|
||||
stdin=subprocess.PIPE, stdout=None, stderr=None)
|
||||
p.communicate(_originalXmodmap)
|
||||
|
||||
msg = "CTHULHU: Original xmodmap restored"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
cthulhu_modifier_manager.getManager().refreshCthulhuModifiers("Keyboard change detected.")
|
||||
|
||||
def setKeyHandling(new):
|
||||
"""Toggle use of the new vs. legacy key handling mode.
|
||||
@@ -588,16 +461,7 @@ def loadUserSettings(script=None, inputEvent=None, skipReloadMessage=False):
|
||||
if _settingsManager.getSetting('enableSound'):
|
||||
player.init()
|
||||
|
||||
global _cthulhuModifiers
|
||||
custom = [k for k in settings.cthulhuModifierKeys if k not in _cthulhuModifiers]
|
||||
_cthulhuModifiers += custom
|
||||
# Handle the case where a change was made in the Cthulhu Preferences dialog.
|
||||
#
|
||||
if _originalXmodmap:
|
||||
_restoreXmodmap(_cthulhuModifiers)
|
||||
|
||||
_storeXmodmap(_cthulhuModifiers)
|
||||
_createCthulhuXmodmap()
|
||||
cthulhu_modifier_manager.getManager().refreshCthulhuModifiers("Loading user settings.")
|
||||
|
||||
# Activate core systems FIRST before loading plugins
|
||||
_scriptManager.activate()
|
||||
@@ -894,7 +758,7 @@ def shutdown(script=None, inputEvent=None):
|
||||
signal.alarm(0)
|
||||
|
||||
_initialized = False
|
||||
_restoreXmodmap(_cthulhuModifiers)
|
||||
cthulhu_modifier_manager.getManager().unsetCthulhuModifiers("Shutting down.")
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Quitting Atspi main event loop', True)
|
||||
Atspi.event_quit()
|
||||
@@ -948,7 +812,7 @@ def crashOnSignal(signum, frame):
|
||||
msg = f"CTHULHU: Shutting down and exiting due to signal={signum} {signalString}"
|
||||
debug.printMessage(debug.LEVEL_SEVERE, msg, True)
|
||||
debug.printStack(debug.LEVEL_SEVERE)
|
||||
_restoreXmodmap(_cthulhuModifiers)
|
||||
cthulhu_modifier_manager.getManager().unsetCthulhuModifiers("Crashed")
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2026 Stormux
|
||||
# Copyright (c) 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Forked from Orca screen reader.
|
||||
# Cthulhu project: https://git.stormux.org/storm/cthulhu
|
||||
|
||||
"""Manages the Cthulhu modifier key(s)."""
|
||||
|
||||
__id__ = "$Id$"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2026 Stormux"
|
||||
__license__ = "LGPL"
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import gi
|
||||
gi.require_version("Atspi", "2.0")
|
||||
from gi.repository import Atspi
|
||||
from gi.repository import GLib
|
||||
|
||||
import cthulhu.debug as debug
|
||||
import cthulhu.settings as settings
|
||||
|
||||
class CthulhuModifierManager:
|
||||
"""Manages the Cthulhu modifier."""
|
||||
|
||||
def __init__(self):
|
||||
self._originalXmodmap = b""
|
||||
self._capsLockCleared = False
|
||||
|
||||
def refreshCthulhuModifiers(self, reason=""):
|
||||
"""Refreshes the Cthulhu modifier keys."""
|
||||
|
||||
msg = "CTHULHU MODIFIER MANAGER: Refreshing Cthulhu modifiers"
|
||||
if reason:
|
||||
msg += f": {reason}"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
display = os.environ.get("DISPLAY")
|
||||
if not display:
|
||||
msg = "CTHULHU MODIFIER MANAGER: DISPLAY not set, skipping xkbcomp operations"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
return
|
||||
|
||||
self.unsetCthulhuModifiers(reason)
|
||||
with subprocess.Popen(["xkbcomp", display, "-"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) as process:
|
||||
self._originalXmodmap, _ = process.communicate()
|
||||
self._createCthulhuXmodmap()
|
||||
|
||||
def unsetCthulhuModifiers(self, reason=""):
|
||||
"""Turns the Cthulhu modifiers back into their original purpose."""
|
||||
|
||||
msg = "CTHULHU MODIFIER MANAGER: Attempting to restore original xmodmap"
|
||||
if reason:
|
||||
msg += f": {reason}"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
if not self._originalXmodmap:
|
||||
msg = "CTHULHU MODIFIER MANAGER: No stored xmodmap found"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
return
|
||||
|
||||
display = os.environ.get("DISPLAY")
|
||||
if not display:
|
||||
msg = "CTHULHU MODIFIER MANAGER: DISPLAY not set, skipping xmodmap restoration"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
return
|
||||
|
||||
self._capsLockCleared = False
|
||||
with subprocess.Popen(["xkbcomp", "-w0", "-", display],
|
||||
stdin=subprocess.PIPE, stdout=None, stderr=None) as process:
|
||||
process.communicate(self._originalXmodmap)
|
||||
|
||||
msg = "CTHULHU MODIFIER MANAGER: Original xmodmap restored"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
def _createCthulhuXmodmap(self):
|
||||
"""Makes a Cthulhu-specific Xmodmap so that the modifier works."""
|
||||
|
||||
msg = "CTHULHU MODIFIER MANAGER: Creating Cthulhu xmodmap"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
if "Caps_Lock" in settings.cthulhuModifierKeys \
|
||||
or "Shift_Lock" in settings.cthulhuModifierKeys:
|
||||
self.setCapsLockAsCthulhuModifier(True)
|
||||
self._capsLockCleared = True
|
||||
elif self._capsLockCleared:
|
||||
self.setCapsLockAsCthulhuModifier(False)
|
||||
self._capsLockCleared = False
|
||||
|
||||
def setCapsLockAsCthulhuModifier(self, enable):
|
||||
"""Enable or disable use of the caps lock key as a Cthulhu modifier key."""
|
||||
|
||||
msg = "CTHULHU MODIFIER MANAGER: Setting caps lock as the Cthulhu modifier"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
display = os.environ.get("DISPLAY")
|
||||
if not display:
|
||||
msg = "CTHULHU MODIFIER MANAGER: DISPLAY not set, cannot modify caps lock"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
return
|
||||
|
||||
if not self._originalXmodmap:
|
||||
msg = "CTHULHU MODIFIER MANAGER: No xmodmap available, cannot modify caps lock"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
return
|
||||
|
||||
interpretCapsLineProg = re.compile(
|
||||
r'^\s*interpret\s+Caps[_+]Lock[_+]AnyOfOrNone\s*\(all\)\s*{\s*$', re.I)
|
||||
normalCapsLineProg = re.compile(
|
||||
r'^\s*action\s*=\s*LockMods\s*\(\s*modifiers\s*=\s*Lock\s*\)\s*;\s*$', re.I)
|
||||
interpretShiftLineProg = re.compile(
|
||||
r'^\s*interpret\s+Shift[_+]Lock[_+]AnyOf\s*\(\s*Shift\s*\+\s*Lock\s*\)\s*{\s*$', re.I)
|
||||
normalShiftLineProg = re.compile(
|
||||
r'^\s*action\s*=\s*LockMods\s*\(\s*modifiers\s*=\s*Shift\s*\)\s*;\s*$', re.I)
|
||||
disabledModLineProg = re.compile(
|
||||
r'^\s*action\s*=\s*NoAction\s*\(\s*\)\s*;\s*$', re.I)
|
||||
normalCapsLine = ' action= LockMods(modifiers=Lock);'
|
||||
normalShiftLine = ' action= LockMods(modifiers=Shift);'
|
||||
disabledModLine = ' action= NoAction();'
|
||||
lines = self._originalXmodmap.decode('UTF-8').split('\n')
|
||||
foundCapsInterpretSection = False
|
||||
foundShiftInterpretSection = False
|
||||
modified = False
|
||||
for i, line in enumerate(lines):
|
||||
if not foundCapsInterpretSection and not foundShiftInterpretSection:
|
||||
if interpretCapsLineProg.match(line):
|
||||
foundCapsInterpretSection = True
|
||||
elif interpretShiftLineProg.match(line):
|
||||
foundShiftInterpretSection = True
|
||||
elif foundCapsInterpretSection:
|
||||
if enable:
|
||||
if normalCapsLineProg.match(line):
|
||||
lines[i] = disabledModLine
|
||||
modified = True
|
||||
else:
|
||||
if disabledModLineProg.match(line):
|
||||
lines[i] = normalCapsLine
|
||||
modified = True
|
||||
if line.find('}'):
|
||||
foundCapsInterpretSection = False
|
||||
elif foundShiftInterpretSection:
|
||||
if enable:
|
||||
if normalShiftLineProg.match(line):
|
||||
lines[i] = disabledModLine
|
||||
modified = True
|
||||
else:
|
||||
if disabledModLineProg.match(line):
|
||||
lines[i] = normalShiftLine
|
||||
modified = True
|
||||
if line.find('}'):
|
||||
foundShiftInterpretSection = False
|
||||
if modified:
|
||||
msg = "CTHULHU MODIFIER MANAGER: Updating xmodmap"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
with subprocess.Popen(["xkbcomp", "-w0", "-", display],
|
||||
stdin=subprocess.PIPE, stdout=None, stderr=None) as process:
|
||||
process.communicate(bytes('\n'.join(lines), 'UTF-8'))
|
||||
else:
|
||||
msg = "CTHULHU MODIFIER MANAGER: Not updating xmodmap"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
def toggleModifier(self, keyboardEvent):
|
||||
"""Toggles the modifier to enable double-clicking causing normal behavior."""
|
||||
|
||||
if keyboardEvent.keyval_name in ["Caps_Lock", "Shift_Lock"]:
|
||||
self._toggleModifierLock(keyboardEvent)
|
||||
return
|
||||
|
||||
def _toggleModifierLock(self, keyboardEvent):
|
||||
"""Toggles the lock for a modifier to enable double-clicking causing normal behavior."""
|
||||
|
||||
if not keyboardEvent.is_pressed_key():
|
||||
return
|
||||
|
||||
def toggle(modifiers, modifier):
|
||||
if modifiers & modifier:
|
||||
lock = Atspi.KeySynthType.UNLOCKMODIFIERS
|
||||
msg = "CTHULHU MODIFIER MANAGER: Unlocking CapsLock"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
else:
|
||||
lock = Atspi.KeySynthType.LOCKMODIFIERS
|
||||
msg = "CTHULHU MODIFIER MANAGER: Locking CapsLock"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
Atspi.generate_keyboard_event(modifier, "", lock)
|
||||
|
||||
if keyboardEvent.keyval_name == "Caps_Lock":
|
||||
modifier = 1 << Atspi.ModifierType.SHIFTLOCK
|
||||
elif keyboardEvent.keyval_name == "Shift_Lock":
|
||||
modifier = 1 << Atspi.ModifierType.SHIFT
|
||||
else:
|
||||
return
|
||||
|
||||
msg = "CTHULHU MODIFIER MANAGER: Scheduling lock change"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
GLib.timeout_add(1, toggle, keyboardEvent.modifiers, modifier)
|
||||
|
||||
_manager = CthulhuModifierManager()
|
||||
|
||||
def getManager():
|
||||
"""Returns the CthulhuModifierManager singleton."""
|
||||
return _manager
|
||||
@@ -47,6 +47,7 @@ from . import keybindings
|
||||
from . import keynames
|
||||
from . import messages
|
||||
from . import cthulhu
|
||||
from . import cthulhu_modifier_manager
|
||||
from . import cthulhu_state
|
||||
from . import script_manager
|
||||
from . import settings
|
||||
@@ -347,7 +348,10 @@ class KeyboardEvent(InputEvent):
|
||||
KeyboardEvent.secondCthulhuModifierTime <
|
||||
KeyboardEvent.lastCthulhuModifierAloneTime + 0.5):
|
||||
# double-cthulhu, let the real action happen
|
||||
self._bypassCthulhu = True
|
||||
if self.event_string in ["Caps_Lock", "Shift_Lock"]:
|
||||
cthulhu_modifier_manager.getManager().toggleModifier(self)
|
||||
else:
|
||||
self._bypassCthulhu = True
|
||||
if not _isPressed:
|
||||
KeyboardEvent.lastCthulhuModifierAlone = False
|
||||
KeyboardEvent.lastCthulhuModifierAloneTime = False
|
||||
@@ -955,7 +959,6 @@ class KeyboardEvent(InputEvent):
|
||||
if (self.event_string == "Caps_Lock" \
|
||||
or self.event_string == "Shift_Lock") \
|
||||
and self.type == Atspi.EventType.KEY_PRESSED_EVENT:
|
||||
self._lock_mod()
|
||||
self.keyType = KeyboardEvent.TYPE_LOCKING
|
||||
self._present()
|
||||
return False, 'Bypassed cthulhu modifier'
|
||||
@@ -984,6 +987,7 @@ class KeyboardEvent(InputEvent):
|
||||
if cthulhu_state.bypassNextCommand:
|
||||
if not self.is_modifier_key():
|
||||
cthulhu_state.bypassNextCommand = False
|
||||
cthulhu_modifier_manager.getManager().refreshCthulhuModifiers("Bypass next command disabled")
|
||||
self._script.addKeyGrabs()
|
||||
return False, 'Bypass next command'
|
||||
|
||||
@@ -999,34 +1003,6 @@ class KeyboardEvent(InputEvent):
|
||||
|
||||
return False, 'Unaddressed case'
|
||||
|
||||
def _lock_mod(self):
|
||||
def lock_mod(modifiers, modifier):
|
||||
def lockit():
|
||||
try:
|
||||
if modifiers & modifier:
|
||||
lock = Atspi.KeySynthType.UNLOCKMODIFIERS
|
||||
debug.printMessage(debug.LEVEL_INFO, "Unlocking capslock", True)
|
||||
else:
|
||||
lock = Atspi.KeySynthType.LOCKMODIFIERS
|
||||
debug.printMessage(debug.LEVEL_INFO, "Locking capslock", True)
|
||||
Atspi.generate_keyboard_event(modifier, "", lock)
|
||||
debug.printMessage(debug.LEVEL_INFO, "Done with capslock", True)
|
||||
except Exception:
|
||||
debug.printMessage(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 << Atspi.ModifierType.SHIFTLOCK
|
||||
elif self.event_string == "Shift_Lock":
|
||||
modifier = 1 << Atspi.ModifierType.SHIFT
|
||||
else:
|
||||
tokens = ["Unknown locking key", self.event_string]
|
||||
debug.printTokens(debug.LEVEL_WARNING, tokens, True)
|
||||
return
|
||||
debug.printMessage(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)
|
||||
|
||||
@@ -34,6 +34,7 @@ cthulhu_python_sources = files([
|
||||
'colornames.py',
|
||||
'common_keyboardmap.py',
|
||||
'cthulhuVersion.py',
|
||||
'cthulhu_modifier_manager.py',
|
||||
'cthulhu_state.py',
|
||||
'date_and_time_presenter.py',
|
||||
'dbus_service.py',
|
||||
|
||||
@@ -55,6 +55,7 @@ import cthulhu.input_event_manager as input_event_manager
|
||||
import cthulhu.keybindings as keybindings
|
||||
import cthulhu.messages as messages
|
||||
import cthulhu.cthulhu as cthulhu
|
||||
import cthulhu.cthulhu_modifier_manager as cthulhu_modifier_manager
|
||||
import cthulhu.cthulhu_state as cthulhu_state
|
||||
import cthulhu.phonnames as phonnames
|
||||
import cthulhu.script as script
|
||||
@@ -834,6 +835,7 @@ class Script(script.Script):
|
||||
|
||||
self.presentMessage(messages.BYPASS_MODE_ENABLED)
|
||||
cthulhu_state.bypassNextCommand = True
|
||||
cthulhu_modifier_manager.getManager().unsetCthulhuModifiers("Bypass next command enabled")
|
||||
self.removeKeyGrabs()
|
||||
return True
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ __license__ = "LGPL"
|
||||
|
||||
import cthulhu.scripts.default as default
|
||||
import cthulhu.debug as debug
|
||||
import cthulhu.cthulhu_modifier_manager as cthulhu_modifier_manager
|
||||
import cthulhu.sleep_mode_manager as sleep_mode_manager
|
||||
|
||||
class Script(default.Script):
|
||||
@@ -55,6 +56,7 @@ class Script(default.Script):
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE SCRIPT: Activating", True)
|
||||
super().activate()
|
||||
cthulhu_modifier_manager.getManager().unsetCthulhuModifiers("Entering sleep mode.")
|
||||
|
||||
# Get the manager and add its bindings and handlers
|
||||
manager = sleep_mode_manager.getManager()
|
||||
@@ -76,6 +78,7 @@ class Script(default.Script):
|
||||
|
||||
# Restore key grabs
|
||||
self.addKeyGrabs()
|
||||
cthulhu_modifier_manager.getManager().refreshCthulhuModifiers("Exiting sleep mode.")
|
||||
|
||||
super().deactivate()
|
||||
|
||||
@@ -153,4 +156,4 @@ class Script(default.Script):
|
||||
|
||||
def get_script(app):
|
||||
"""Returns the script for the given application."""
|
||||
return Script(app)
|
||||
return Script(app)
|
||||
|
||||
Reference in New Issue
Block a user