Request to be able to use the numpad if numlock is on and only process fenrir commands if numlock is off. This should work, let me know if anything breaks.

This commit is contained in:
Storm Dragon 2025-04-14 18:57:10 -04:00
parent f68a1af223
commit 2dda73ac87
15 changed files with 93 additions and 63 deletions

View File

@ -105,7 +105,7 @@ class attributeManager():
cursorPos = cursor.copy() cursorPos = cursor.copy()
try: try:
attribute = self.getAttributeByXY( cursorPos['x'], cursorPos['y']) attribute = self.getAttributeByXY( cursorPos['x'], cursorPos['y'])
if update: if update:
self.setLastCursorAttribute(attribute) self.setLastCursorAttribute(attribute)
if not self.isLastCursorAttributeChange(): if not self.isLastCursorAttributeChange():
@ -155,13 +155,13 @@ class attributeManager():
attributeFormatString = attributeFormatString.replace('fenrirFGColor', _(attribute[0])) attributeFormatString = attributeFormatString.replace('fenrirFGColor', _(attribute[0]))
except Exception as e: except Exception as e:
attributeFormatString = attributeFormatString.replace('fenrirFGColor', '') attributeFormatString = attributeFormatString.replace('fenrirFGColor', '')
# 1 BG color (name) # 1 BG color (name)
try: try:
attributeFormatString = attributeFormatString.replace('fenrirBGColor', _(attribute[1])) attributeFormatString = attributeFormatString.replace('fenrirBGColor', _(attribute[1]))
except Exception as e: except Exception as e:
attributeFormatString = attributeFormatString.replace('fenrirBGColor', '') attributeFormatString = attributeFormatString.replace('fenrirBGColor', '')
# 2 bold (True/ False) # 2 bold (True/ False)
try: try:
if attribute[2]: if attribute[2]:
@ -169,7 +169,7 @@ class attributeManager():
except Exception as e: except Exception as e:
pass pass
attributeFormatString = attributeFormatString.replace('fenrirBold', '') attributeFormatString = attributeFormatString.replace('fenrirBold', '')
# 3 italics (True/ False) # 3 italics (True/ False)
try: try:
if attribute[3]: if attribute[3]:
@ -177,7 +177,7 @@ class attributeManager():
except Exception as e: except Exception as e:
pass pass
attributeFormatString = attributeFormatString.replace('fenrirItalics', '') attributeFormatString = attributeFormatString.replace('fenrirItalics', '')
# 4 underline (True/ False) # 4 underline (True/ False)
try: try:
if attribute[4]: if attribute[4]:
@ -185,7 +185,7 @@ class attributeManager():
except Exception as e: except Exception as e:
pass pass
attributeFormatString = attributeFormatString.replace('fenrirUnderline', '') attributeFormatString = attributeFormatString.replace('fenrirUnderline', '')
# 5 strikethrough (True/ False) # 5 strikethrough (True/ False)
try: try:
if attribute[5]: if attribute[5]:
@ -193,7 +193,7 @@ class attributeManager():
except Exception as e: except Exception as e:
pass pass
attributeFormatString = attributeFormatString.replace('fenrirStrikethrough', '') attributeFormatString = attributeFormatString.replace('fenrirStrikethrough', '')
# 6 reverse (True/ False) # 6 reverse (True/ False)
try: try:
if attribute[6]: if attribute[6]:
@ -201,7 +201,7 @@ class attributeManager():
except Exception as e: except Exception as e:
pass pass
attributeFormatString = attributeFormatString.replace('fenrirReverse', '') attributeFormatString = attributeFormatString.replace('fenrirReverse', '')
# 7 blink (True/ False) # 7 blink (True/ False)
try: try:
if attribute[7]: if attribute[7]:
@ -209,7 +209,7 @@ class attributeManager():
except Exception as e: except Exception as e:
pass pass
attributeFormatString = attributeFormatString.replace('fenrirBlink', '') attributeFormatString = attributeFormatString.replace('fenrirBlink', '')
# 8 font size (int/ string) # 8 font size (int/ string)
try: try:
try: try:
@ -223,14 +223,14 @@ class attributeManager():
except Exception as e: except Exception as e:
pass pass
attributeFormatString = attributeFormatString.replace('fenrirFontSize', _('default')) attributeFormatString = attributeFormatString.replace('fenrirFontSize', _('default'))
# 9 font family (string) # 9 font family (string)
try: try:
attributeFormatString = attributeFormatString.replace('fenrirFont', attribute[9]) attributeFormatString = attributeFormatString.replace('fenrirFont', attribute[9])
except Exception as e: except Exception as e:
pass pass
attributeFormatString = attributeFormatString.replace('fenrirFont', _('default')) attributeFormatString = attributeFormatString.replace('fenrirFont', _('default'))
return attributeFormatString return attributeFormatString
def trackHighlights(self): def trackHighlights(self):
result = '' result = ''
@ -287,4 +287,4 @@ class attributeManager():
useful = True useful = True
return useful return useful

View File

@ -18,7 +18,7 @@ class barrierManager():
def updateBarrierChange(self, isBarrier): def updateBarrierChange(self, isBarrier):
self.prefIsBarrier = self.currIsBarrier self.prefIsBarrier = self.currIsBarrier
self.currIsBarrier = isBarrier self.currIsBarrier = isBarrier
def resetBarrierChange(self): def resetBarrierChange(self):
self.currIsBarrier = False self.currIsBarrier = False
self.prefIsBarrier = False self.prefIsBarrier = False
@ -38,7 +38,7 @@ class barrierManager():
self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierStart', interrupt=doInterrupt) self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierStart', interrupt=doInterrupt)
else: else:
self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierEnd', interrupt=doInterrupt) self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierEnd', interrupt=doInterrupt)
if not isBarrier: if not isBarrier:
sayLine = '' sayLine = ''
return isBarrier, sayLine return isBarrier, sayLine

View File

@ -27,7 +27,7 @@ class commandManager():
# scripts for scriptKey # scripts for scriptKey
self.env['runtime']['commandManager'].loadScriptCommands() self.env['runtime']['commandManager'].loadScriptCommands()
def shutdown(self): def shutdown(self):
for commandFolder in self.env['general']['commandFolderList']: for commandFolder in self.env['general']['commandFolderList']:
self.env['runtime']['commandManager'].shutdownCommands(commandFolder) self.env['runtime']['commandManager'].shutdownCommands(commandFolder)
@ -99,7 +99,7 @@ class commandManager():
self.env['runtime']['debug'].writeDebugOut("loadCommands: Loading command:" + command ,debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut("loadCommands: Loading command:" + command ,debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
continue continue
def loadScriptCommands(self, section='commands', scriptPath=''): def loadScriptCommands(self, section='commands', scriptPath=''):
if scriptPath =='': if scriptPath =='':
scriptPath = self.env['runtime']['settingsManager'].getSetting('general', 'scriptPath') scriptPath = self.env['runtime']['settingsManager'].getSetting('general', 'scriptPath')
@ -165,7 +165,7 @@ class commandManager():
if section not in self.env['commands']: if section not in self.env['commands']:
self.env['runtime']['debug'].writeDebugOut("shutdownCommands: section not found:" + section, debug.debugLevel.WARNING) self.env['runtime']['debug'].writeDebugOut("shutdownCommands: section not found:" + section, debug.debugLevel.WARNING)
return return
for command in sorted(self.env['commands'][section]): for command in sorted(self.env['commands'][section]):
try: try:
self.env['commands'][section][command].shutdown() self.env['commands'][section][command].shutdown()
@ -228,7 +228,7 @@ class commandManager():
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR)
def runCommand(self, command, section = 'commands'): def runCommand(self, command, section = 'commands'):
if self.commandExists(command, section): if self.commandExists(command, section):
try: try:
@ -237,7 +237,7 @@ class commandManager():
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR)
self.env['commandInfo']['lastCommandExecutionTime'] = time.time() self.env['commandInfo']['lastCommandExecutionTime'] = time.time()
def getCommandDescription(self, command, section = 'commands'): def getCommandDescription(self, command, section = 'commands'):
if self.commandExists(command, section): if self.commandExists(command, section):
try: try:
@ -245,7 +245,7 @@ class commandManager():
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut('commandManager.getCommandDescription:' + str(e),debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut('commandManager.getCommandDescription:' + str(e),debug.debugLevel.ERROR)
self.env['commandInfo']['lastCommandExecutionTime'] = time.time() self.env['commandInfo']['lastCommandExecutionTime'] = time.time()
def commandExists(self, command, section = 'commands'): def commandExists(self, command, section = 'commands'):
try: try:
return( command in self.env['commands'][section]) return( command in self.env['commands'][section])

View File

@ -11,6 +11,14 @@ class cursorManager():
pass pass
def initialize(self, environment): def initialize(self, environment):
self.env = environment self.env = environment
def shouldProcessNumpadCommands(self):
"""
Check if numpad commands should be processed based on numlock state
Return True if numlock is OFF (commands should work)
Return False if numlock is ON (let keys type numbers)
"""
# Return False if numlock is ON
return not self.env['input']['newNumLock']
def shutdown(self): def shutdown(self):
pass pass
def clearMarks(self): def clearMarks(self):
@ -47,7 +55,7 @@ class cursorManager():
return return
self.env['screen']['oldCursorReview'] = None self.env['screen']['oldCursorReview'] = None
self.env['screen']['newCursorReview'] = None self.env['screen']['newCursorReview'] = None
def isCursorHorizontalMove(self): def isCursorHorizontalMove(self):
return self.env['screen']['newCursor']['x'] != self.env['screen']['oldCursor']['x'] return self.env['screen']['newCursor']['x'] != self.env['screen']['oldCursor']['x']
@ -56,7 +64,7 @@ class cursorManager():
def isReviewMode(self): def isReviewMode(self):
return self.env['screen']['newCursorReview'] != None return self.env['screen']['newCursorReview'] != None
def enterReviewModeCurrTextCursor(self, overwrite=False): def enterReviewModeCurrTextCursor(self, overwrite=False):
if self.isReviewMode() and not overwrite: if self.isReviewMode() and not overwrite:
return return
@ -73,7 +81,7 @@ class cursorManager():
self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview']
self.env['screen']['newCursorReview']['x'] = x self.env['screen']['newCursorReview']['x'] = x
self.env['screen']['newCursorReview']['y'] = y self.env['screen']['newCursorReview']['y'] = y
def isApplicationWindowSet(self): def isApplicationWindowSet(self):
try: try:
currApp = self.env['runtime']['applicationManager'].getCurrentApplication() currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
@ -108,7 +116,7 @@ class cursorManager():
currApp = self.env['runtime']['applicationManager'].getCurrentApplication() currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
self.env['commandBuffer']['windowArea'][currApp] = {} self.env['commandBuffer']['windowArea'][currApp] = {}
if x1 * y1 <= \ if x1 * y1 <= \
x2 * y2: x2 * y2:
self.env['commandBuffer']['windowArea'][currApp]['1'] = {'x':x1, 'y':y1} self.env['commandBuffer']['windowArea'][currApp]['1'] = {'x':x1, 'y':y1}

View File

@ -36,14 +36,14 @@ class debugManager():
except Exception as e: except Exception as e:
print(e) print(e)
def writeDebugOut(self, text, level = debug.debugLevel.DEACTIVE, onAnyLevel=False): def writeDebugOut(self, text, level = debug.debugLevel.DEACTIVE, onAnyLevel=False):
mode = self.env['runtime']['settingsManager'].getSetting('general','debugMode') mode = self.env['runtime']['settingsManager'].getSetting('general','debugMode')
if mode == '': if mode == '':
mode = 'FILE' mode = 'FILE'
mode = mode.upper().split(',') mode = mode.upper().split(',')
fileMode = 'FILE' in mode fileMode = 'FILE' in mode
printMode = 'PRINT' in mode printMode = 'PRINT' in mode
if (self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') < int(level)) and \ if (self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') < int(level)) and \
not (onAnyLevel and self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') > int(debug.debugLevel.DEACTIVE)) : not (onAnyLevel and self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') > int(debug.debugLevel.DEACTIVE)) :
if self._fileOpened: if self._fileOpened:

View File

@ -21,7 +21,7 @@ class eventManager():
self.env = environment self.env = environment
def shutdown(self): def shutdown(self):
self.cleanEventQueue() self.cleanEventQueue()
def proceedEventLoop(self): def proceedEventLoop(self):
event = self._eventQueue.get() event = self._eventQueue.get()
st = time.time() st = time.time()

View File

@ -23,11 +23,11 @@ class fenrirManager():
raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable') raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable')
except RuntimeError: except RuntimeError:
raise raise
self.environment['runtime']['outputManager'].presentText(_("Start Fenrir"), soundIcon='ScreenReaderOn', interrupt=True) self.environment['runtime']['outputManager'].presentText(_("Start Fenrir"), soundIcon='ScreenReaderOn', interrupt=True)
signal.signal(signal.SIGINT, self.captureSignal) signal.signal(signal.SIGINT, self.captureSignal)
signal.signal(signal.SIGTERM, self.captureSignal) signal.signal(signal.SIGTERM, self.captureSignal)
self.isInitialized = True self.isInitialized = True
self.modifierInput = False self.modifierInput = False
self.singleKeyCommand = False self.singleKeyCommand = False
@ -42,10 +42,10 @@ class fenrirManager():
def handleInput(self, event): def handleInput(self, event):
self.environment['runtime']['debug'].writeDebugOut('DEBUG INPUT fenrirMan:' + str(event), debug.debugLevel.INFO) self.environment['runtime']['debug'].writeDebugOut('DEBUG INPUT fenrirMan:' + str(event), debug.debugLevel.INFO)
if not event['Data']: if not event['Data']:
event['Data'] = self.environment['runtime']['inputManager'].getInputEvent() event['Data'] = self.environment['runtime']['inputManager'].getInputEvent()
if event['Data']: if event['Data']:
event['Data']['EventName'] = self.environment['runtime']['inputManager'].convertEventName(event['Data']['EventName']) event['Data']['EventName'] = self.environment['runtime']['inputManager'].convertEventName(event['Data']['EventName'])
self.environment['runtime']['inputManager'].handleInputEvent(event['Data']) self.environment['runtime']['inputManager'].handleInputEvent(event['Data'])
@ -54,7 +54,7 @@ class fenrirManager():
if self.environment['runtime']['inputManager'].noKeyPressed(): if self.environment['runtime']['inputManager'].noKeyPressed():
self.environment['runtime']['inputManager'].clearLastDeepInput() self.environment['runtime']['inputManager'].clearLastDeepInput()
if self.environment['runtime']['screenManager'].isSuspendingScreen(): if self.environment['runtime']['screenManager'].isSuspendingScreen():
self.environment['runtime']['inputManager'].writeEventBuffer() self.environment['runtime']['inputManager'].writeEventBuffer()
else: else:
@ -74,7 +74,7 @@ class fenrirManager():
self.environment['runtime']['inputManager'].clearEventBuffer() self.environment['runtime']['inputManager'].clearEventBuffer()
else: else:
self.environment['runtime']['inputManager'].writeEventBuffer() self.environment['runtime']['inputManager'].writeEventBuffer()
if self.environment['runtime']['inputManager'].noKeyPressed(): if self.environment['runtime']['inputManager'].noKeyPressed():
self.modifierInput = False self.modifierInput = False
self.singleKeyCommand = False self.singleKeyCommand = False
@ -83,7 +83,7 @@ class fenrirManager():
if self.environment['input']['keyForeward'] > 0: if self.environment['input']['keyForeward'] > 0:
self.environment['input']['keyForeward'] -= 1 self.environment['input']['keyForeward'] -= 1
self.environment['runtime']['commandManager'].executeDefaultTrigger('onKeyInput') self.environment['runtime']['commandManager'].executeDefaultTrigger('onKeyInput')
def handleByteInput(self, event): def handleByteInput(self, event):
@ -124,14 +124,14 @@ class fenrirManager():
def handleScreenUpdate(self, event): def handleScreenUpdate(self, event):
self.environment['runtime']['screenManager'].handleScreenUpdate(event['Data']) self.environment['runtime']['screenManager'].handleScreenUpdate(event['Data'])
if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3: if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3:
self.environment['runtime']['inputManager'].clearLastDeepInput() self.environment['runtime']['inputManager'].clearLastDeepInput()
if (self.environment['runtime']['cursorManager'].isCursorVerticalMove() or if (self.environment['runtime']['cursorManager'].isCursorVerticalMove() or
self.environment['runtime']['cursorManager'].isCursorHorizontalMove()): self.environment['runtime']['cursorManager'].isCursorHorizontalMove()):
self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange') self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange')
self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate') self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate')
self.environment['runtime']['inputManager'].clearLastDeepInput() self.environment['runtime']['inputManager'].clearLastDeepInput()
@ -150,17 +150,17 @@ class fenrirManager():
def detectShortcutCommand(self): def detectShortcutCommand(self):
if self.environment['input']['keyForeward'] > 0: if self.environment['input']['keyForeward'] > 0:
return return
if len(self.environment['input']['prevInput']) > len(self.environment['input']['currInput']): if len(self.environment['input']['prevInput']) > len(self.environment['input']['currInput']):
return return
if self.environment['runtime']['inputManager'].isKeyPress(): if self.environment['runtime']['inputManager'].isKeyPress():
self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier() self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier()
else: else:
if not self.environment['runtime']['inputManager'].noKeyPressed(): if not self.environment['runtime']['inputManager'].noKeyPressed():
if self.singleKeyCommand: if self.singleKeyCommand:
self.singleKeyCommand = len(self.environment['input']['currInput']) == 1 self.singleKeyCommand = len(self.environment['input']['currInput']) == 1
if not(self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()): if not(self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()):
currentShortcut = self.environment['runtime']['inputManager'].getCurrShortcut() currentShortcut = self.environment['runtime']['inputManager'].getCurrShortcut()
self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(currentShortcut) self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(currentShortcut)
@ -220,7 +220,7 @@ class fenrirManager():
self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True) self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True)
self.environment['runtime']['eventManager'].cleanEventQueue() self.environment['runtime']['eventManager'].cleanEventQueue()
time.sleep(0.6) time.sleep(0.6)
for currentManager in self.environment['general']['managerList']: for currentManager in self.environment['general']['managerList']:
if self.environment['runtime'][currentManager]: if self.environment['runtime'][currentManager]:
self.environment['runtime'][currentManager].shutdown() self.environment['runtime'][currentManager].shutdown()

View File

@ -62,13 +62,13 @@ class inputManager():
if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
self.executeDeviceGrab = False self.executeDeviceGrab = False
return return
# Add maximum retries to prevent infinite loops # Add maximum retries to prevent infinite loops
maxRetries = 5 maxRetries = 5
retryCount = 0 retryCount = 0
grabTimeout = 3 # Timeout in seconds grabTimeout = 3 # Timeout in seconds
startTime = time.time() startTime = time.time()
if self.env['runtime']['screenManager'].getCurrScreenIgnored(): if self.env['runtime']['screenManager'].getCurrScreenIgnored():
while not self.ungrabAllDevices(): while not self.ungrabAllDevices():
retryCount += 1 retryCount += 1
@ -91,7 +91,7 @@ class inputManager():
break break
time.sleep(0.25) time.sleep(0.25)
self.env['runtime']['debug'].writeDebugOut(f"retry grabAllDevices {retryCount}/{maxRetries}", debug.debugLevel.WARNING) self.env['runtime']['debug'].writeDebugOut(f"retry grabAllDevices {retryCount}/{maxRetries}", debug.debugLevel.WARNING)
self.executeDeviceGrab = False self.executeDeviceGrab = False
def sendKeys(self, keyMacro): def sendKeys(self, keyMacro):
@ -274,17 +274,39 @@ class inputManager():
def getCurrShortcut(self, inputSequence = None): def getCurrShortcut(self, inputSequence = None):
shortcut = [] shortcut = []
shortcut.append(self.env['input']['shortcutRepeat']) shortcut.append(self.env['input']['shortcutRepeat'])
numpadKeys = ['KEY_KP0', 'KEY_KP1', 'KEY_KP2', 'KEY_KP3', 'KEY_KP4',
'KEY_KP5', 'KEY_KP6', 'KEY_KP7', 'KEY_KP8', 'KEY_KP9',
'KEY_KPDOT', 'KEY_KPPLUS', 'KEY_KPMINUS', 'KEY_KPASTERISK',
'KEY_KPSLASH', 'KEY_KPENTER', 'KEY_KPEQUAL']
if inputSequence: if inputSequence:
# Check if any key in the sequence is a numpad key and numlock is ON
# If numlock is ON and any key in the sequence is a numpad key, return an empty shortcut
if not self.env['runtime']['cursorManager'].shouldProcessNumpadCommands():
for key in inputSequence:
if key in numpadKeys:
# Return an empty/invalid shortcut that won't match any command
return "[]"
shortcut.append(inputSequence) shortcut.append(inputSequence)
else: else:
# Same check for current input
if not self.env['runtime']['cursorManager'].shouldProcessNumpadCommands():
for key in self.env['input']['currInput']:
if key in numpadKeys:
# Return an empty/invalid shortcut that won't match any command
return "[]"
shortcut.append(self.env['input']['currInput']) shortcut.append(self.env['input']['currInput'])
if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']): if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']):
if self.env['input']['shortcutRepeat'] > 1 and not self.shortcutExists(str(shortcut)): if self.env['input']['shortcutRepeat'] > 1 and not self.shortcutExists(str(shortcut)):
shortcut = [] shortcut = []
self.env['input']['shortcutRepeat'] = 1 self.env['input']['shortcutRepeat'] = 1
shortcut.append(self.env['input']['shortcutRepeat']) shortcut.append(self.env['input']['shortcutRepeat'])
shortcut.append(self.env['input']['currInput']) shortcut.append(self.env['input']['currInput'])
self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut) ,debug.debugLevel.INFO) self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut), debug.debugLevel.INFO)
return str(shortcut) return str(shortcut)
def currKeyIsModifier(self): def currKeyIsModifier(self):

View File

@ -22,7 +22,7 @@ class outputManager():
def shutdown(self): def shutdown(self):
self.env['runtime']['settingsManager'].shutdownDriver('soundDriver') self.env['runtime']['settingsManager'].shutdownDriver('soundDriver')
self.env['runtime']['settingsManager'].shutdownDriver('speechDriver') self.env['runtime']['settingsManager'].shutdownDriver('speechDriver')
def presentText(self, text, interrupt=True, soundIcon='', ignorePunctuation=False, announceCapital=False, flush=True): def presentText(self, text, interrupt=True, soundIcon='', ignorePunctuation=False, announceCapital=False, flush=True):
if text == '': if text == '':
return return
@ -58,13 +58,13 @@ class outputManager():
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech language in outputManager.speakText", debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut("setting speech language in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try: try:
self.env['runtime']['speechDriver'].setVoice(self.env['runtime']['settingsManager'].getSetting('speech', 'voice')) self.env['runtime']['speechDriver'].setVoice(self.env['runtime']['settingsManager'].getSetting('speech', 'voice'))
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Error while setting speech voice in outputManager.speakText", debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut("Error while setting speech voice in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try: try:
if announceCapital: if announceCapital:
self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'capitalPitch')) self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'capitalPitch'))
@ -73,13 +73,13 @@ class outputManager():
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech pitch in outputManager.speakText", debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut("setting speech pitch in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try: try:
self.env['runtime']['speechDriver'].setRate(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate')) self.env['runtime']['speechDriver'].setRate(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate'))
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech rate in outputManager.speakText", debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut("setting speech rate in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try: try:
self.env['runtime']['speechDriver'].setModule(self.env['runtime']['settingsManager'].getSetting('speech', 'module')) self.env['runtime']['speechDriver'].setModule(self.env['runtime']['settingsManager'].getSetting('speech', 'module'))
except Exception as e: except Exception as e:
@ -91,7 +91,7 @@ class outputManager():
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech volume in outputManager.speakText ", debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut("setting speech volume in outputManager.speakText ", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try: try:
if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'newLinePause'): if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'newLinePause'):
cleanText = text.replace('\n', ' , ') cleanText = text.replace('\n', ' , ')

View File

@ -20,7 +20,7 @@ class processManager():
self.addSimpleEventThread(fenrirEventType.HeartBeat, self.heartBeatTimer, multiprocess=True) self.addSimpleEventThread(fenrirEventType.HeartBeat, self.heartBeatTimer, multiprocess=True)
def shutdown(self): def shutdown(self):
self.terminateAllProcesses() self.terminateAllProcesses()
def terminateAllProcesses(self): def terminateAllProcesses(self):
for proc in self._Processes: for proc in self._Processes:
#try: #try:

View File

@ -172,7 +172,7 @@ class remoteManager():
self.env['runtime']['outputManager'].presentText(_('clipboard exported to file'), interrupt=True) self.env['runtime']['outputManager'].presentText(_('clipboard exported to file'), interrupt=True)
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut('export_clipboard_to_file:run: Filepath:'+ clipboardFile +' trace:' + str(e),debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut('export_clipboard_to_file:run: Filepath:'+ clipboardFile +' trace:' + str(e),debug.debugLevel.ERROR)
def saveSettings(self, settingConfigPath = None): def saveSettings(self, settingConfigPath = None):
if not settingConfigPath: if not settingConfigPath:
settingConfigPath = self.env['runtime']['settingsManager'].getSettingsFile() settingConfigPath = self.env['runtime']['settingsManager'].getSettingsFile()

View File

@ -83,7 +83,7 @@ class screenManager():
def updateScreenIgnored(self): def updateScreenIgnored(self):
self.prevScreenIgnored = self.currScreenIgnored self.prevScreenIgnored = self.currScreenIgnored
self.currScreenIgnored = self.isSuspendingScreen(self.env['screen']['newTTY']) self.currScreenIgnored = self.isSuspendingScreen(self.env['screen']['newTTY'])
def update(self, eventData, trigger='onUpdate'): def update(self, eventData, trigger='onUpdate'):
# set new "old" values # set new "old" values
self.env['screen']['oldContentBytes'] = self.env['screen']['newContentBytes'] self.env['screen']['oldContentBytes'] = self.env['screen']['newContentBytes']
@ -146,11 +146,11 @@ class screenManager():
cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3 cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3
oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset] oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset]
newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset] newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset]
# Use the original differ for typing mode to preserve behavior # Use the original differ for typing mode to preserve behavior
diff = self.differ.compare(oldScreenText, newScreenText) diff = self.differ.compare(oldScreenText, newScreenText)
diffList = list(diff) diffList = list(diff)
typing = True typing = True
tempNewDelta = ''.join(x[2:] for x in diffList if x[0] == '+') tempNewDelta = ''.join(x[2:] for x in diffList if x[0] == '+')
if tempNewDelta.strip() != '': if tempNewDelta.strip() != '':
@ -169,11 +169,11 @@ class screenManager():
# Process line by line using rapidfuzz # Process line by line using rapidfuzz
old_lines = oldScreenText.split('\n') old_lines = oldScreenText.split('\n')
new_lines = newScreenText.split('\n') new_lines = newScreenText.split('\n')
# Use standard differ for better word grouping # Use standard differ for better word grouping
diff = self.differ.compare(old_lines, new_lines) diff = self.differ.compare(old_lines, new_lines)
diffList = list(diff) diffList = list(diff)
except Exception as e: except Exception as e:
# Fall back to standard differ if there's any issue # Fall back to standard differ if there's any issue
self.env['runtime']['debug'].writeDebugOut('screenManager:update:rapidfuzz: ' + str(e), debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut('screenManager:update:rapidfuzz: ' + str(e), debug.debugLevel.ERROR)
@ -209,7 +209,7 @@ class screenManager():
ignoreScreens.extend(self.env['screen']['autoIgnoreScreens']) ignoreScreens.extend(self.env['screen']['autoIgnoreScreens'])
self.env['runtime']['debug'].writeDebugOut('screenManager:isSuspendingScreen ignore:' + str(ignoreScreens) + ' current:'+ str(screen ), debug.debugLevel.INFO) self.env['runtime']['debug'].writeDebugOut('screenManager:isSuspendingScreen ignore:' + str(ignoreScreens) + ' current:'+ str(screen ), debug.debugLevel.INFO)
return (screen in ignoreScreens) return (screen in ignoreScreens)
def isScreenChange(self): def isScreenChange(self):
if not self.env['screen']['oldTTY']: if not self.env['screen']['oldTTY']:
return False return False

View File

@ -29,7 +29,7 @@ class speechDriver():
return return
if not queueable: if not queueable:
self.cancel() self.cancel()
def cancel(self): def cancel(self):
if not self._isInitialized: if not self._isInitialized:
return return

View File

@ -34,7 +34,7 @@ class tableManager():
return '' return ''
def setRowColumnSep(self, columnSep = ''): def setRowColumnSep(self, columnSep = ''):
self.rowColumnSep = columnSep self.rowColumnSep = columnSep
def setHeadLine(self, headLine = ''): def setHeadLine(self, headLine = ''):
self.setHeadColumnSep() self.setHeadColumnSep()
self.setRowColumnSep() self.setRowColumnSep()

View File

@ -4,5 +4,5 @@
# Fenrir TTY screen reader # Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers. # By Chrys, Storm Dragon, and contributers.
version = "2025.04.10" version = "2025.04.14"
codeName = "testing" codeName = "testing"