Fixed version for master branch.
This commit is contained in:
commit
7a87fb51bb
10
install.sh
10
install.sh
@ -1,12 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
#Basic install script for Fenrir.
|
#Basic install script for Fenrir.
|
||||||
read -p "This will install Fenrir. Press ctrl+C to cancel, or enter to continue." continue
|
read -rp "This will install Fenrir. Press ctrl+C to cancel, or enter to continue."
|
||||||
|
|
||||||
# Fenrir main application
|
# Fenrir main application
|
||||||
install -m755 -d /opt/fenrirscreenreader
|
install -m755 -d /opt/fenrirscreenreader
|
||||||
cp -af src/* /opt/fenrirscreenreader
|
cp -af src/* /opt/fenrirscreenreader
|
||||||
|
|
||||||
ln -fs /opt/fenrirscreenreader/fenrir-daemon /usr/bin/fenrir-daemon
|
|
||||||
ln -fs /opt/fenrirscreenreader/fenrir /usr/bin/fenrir
|
ln -fs /opt/fenrirscreenreader/fenrir /usr/bin/fenrir
|
||||||
# tools
|
# tools
|
||||||
install -m755 -d /usr/share/fenrirscreenreader/tools
|
install -m755 -d /usr/share/fenrirscreenreader/tools
|
||||||
@ -33,8 +32,9 @@ cp -af config/sound/template /usr/share/sounds/fenrirscreenreader/template
|
|||||||
# config
|
# config
|
||||||
if [ -f "/etc/fenrirscreenreader/settings/settings.conf" ]; then
|
if [ -f "/etc/fenrirscreenreader/settings/settings.conf" ]; then
|
||||||
echo "Do you want to overwrite your current global settings? (y/n)"
|
echo "Do you want to overwrite your current global settings? (y/n)"
|
||||||
read yn
|
read -r yn
|
||||||
if [ $yn = "Y" -o $yn = "y" ]; then
|
yn="${yn:0:1}"
|
||||||
|
if [[ "${yn^}" == "Y" ]]; then
|
||||||
mv /etc/fenrirscreenreader/settings/settings.conf /etc/fenrirscreenreader/settings/settings.conf.bak
|
mv /etc/fenrirscreenreader/settings/settings.conf /etc/fenrirscreenreader/settings/settings.conf.bak
|
||||||
echo "Your old settings.conf has been backed up to settings.conf.bak."
|
echo "Your old settings.conf has been backed up to settings.conf.bak."
|
||||||
install -m644 -D "config/settings/settings.conf" /etc/fenrirscreenreader/settings/settings.conf
|
install -m644 -D "config/settings/settings.conf" /etc/fenrirscreenreader/settings/settings.conf
|
||||||
|
@ -3,6 +3,6 @@ daemonize>=2.5.0
|
|||||||
dbus-python>=1.2.8
|
dbus-python>=1.2.8
|
||||||
pyudev>=0.21.0
|
pyudev>=0.21.0
|
||||||
pexpect
|
pexpect
|
||||||
ppyperclip
|
pyperclip
|
||||||
pyte>=0.7.0
|
pyte>=0.7.0
|
||||||
rapidfuzz>=2.0.0
|
rapidfuzz>=2.0.0
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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])
|
||||||
|
@ -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}
|
||||||
|
@ -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:
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -42,6 +42,25 @@ class inputDriver():
|
|||||||
if not self._initialized:
|
if not self._initialized:
|
||||||
return True
|
return True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def forceUngrab(self):
|
||||||
|
"""Emergency method to release grabbed devices in case of failure"""
|
||||||
|
if not self._initialized:
|
||||||
|
return True
|
||||||
|
try:
|
||||||
|
# Try standard ungrab first
|
||||||
|
return self.ungrabAllDevices()
|
||||||
|
except Exception as e:
|
||||||
|
# Just log the failure and inform the user
|
||||||
|
if hasattr(self, 'env') and 'runtime' in self.env and 'debug' in self.env['runtime']:
|
||||||
|
self.env['runtime']['debug'].writeDebugOut(
|
||||||
|
f"Emergency device release failed: {str(e)}",
|
||||||
|
debug.debugLevel.ERROR
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print(f"Emergency device release failed: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
def hasIDevices(self):
|
def hasIDevices(self):
|
||||||
if not self._initialized:
|
if not self._initialized:
|
||||||
return False
|
return False
|
||||||
|
@ -49,6 +49,7 @@ class inputManager():
|
|||||||
return event
|
return event
|
||||||
def setExecuteDeviceGrab(self, newExecuteDeviceGrab = True):
|
def setExecuteDeviceGrab(self, newExecuteDeviceGrab = True):
|
||||||
self.executeDeviceGrab = newExecuteDeviceGrab
|
self.executeDeviceGrab = newExecuteDeviceGrab
|
||||||
|
|
||||||
def handleDeviceGrab(self, force = False):
|
def handleDeviceGrab(self, force = False):
|
||||||
if force:
|
if force:
|
||||||
self.setExecuteDeviceGrab()
|
self.setExecuteDeviceGrab()
|
||||||
@ -61,17 +62,38 @@ 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
|
||||||
|
maxRetries = 5
|
||||||
|
retryCount = 0
|
||||||
|
grabTimeout = 3 # Timeout in seconds
|
||||||
|
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
|
||||||
|
if retryCount >= maxRetries or (time.time() - startTime) > grabTimeout:
|
||||||
|
self.env['runtime']['debug'].writeDebugOut("Failed to ungrab devices after multiple attempts", debug.debugLevel.ERROR)
|
||||||
|
# Force a release of devices if possible through alternative means
|
||||||
|
try:
|
||||||
|
self.env['runtime']['inputDriver'].forceUngrab()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
break
|
||||||
time.sleep(0.25)
|
time.sleep(0.25)
|
||||||
self.env['runtime']['debug'].writeDebugOut("retry ungrabAllDevices " ,debug.debugLevel.WARNING)
|
self.env['runtime']['debug'].writeDebugOut(f"retry ungrabAllDevices {retryCount}/{maxRetries}", debug.debugLevel.WARNING)
|
||||||
self.env['runtime']['debug'].writeDebugOut("All devices ungrabbed" ,debug.debugLevel.INFO)
|
|
||||||
else:
|
else:
|
||||||
while not self.grabAllDevices():
|
while not self.grabAllDevices():
|
||||||
|
retryCount += 1
|
||||||
|
if retryCount >= maxRetries or (time.time() - startTime) > grabTimeout:
|
||||||
|
self.env['runtime']['debug'].writeDebugOut("Failed to grab devices after multiple attempts", debug.debugLevel.ERROR)
|
||||||
|
# Continue without grabbing input - limited functionality but not locked
|
||||||
|
break
|
||||||
time.sleep(0.25)
|
time.sleep(0.25)
|
||||||
self.env['runtime']['debug'].writeDebugOut("retry grabAllDevices" ,debug.debugLevel.WARNING)
|
self.env['runtime']['debug'].writeDebugOut(f"retry grabAllDevices {retryCount}/{maxRetries}", debug.debugLevel.WARNING)
|
||||||
self.env['runtime']['debug'].writeDebugOut("All devices grabbed" ,debug.debugLevel.INFO)
|
|
||||||
self.executeDeviceGrab = False
|
self.executeDeviceGrab = False
|
||||||
|
|
||||||
def sendKeys(self, keyMacro):
|
def sendKeys(self, keyMacro):
|
||||||
for e in keyMacro:
|
for e in keyMacro:
|
||||||
key = ''
|
key = ''
|
||||||
@ -252,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):
|
||||||
|
@ -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', ' , ')
|
||||||
|
@ -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:
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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.03.02"
|
version = "2025.04.14"
|
||||||
codeName = "master"
|
codeName = "master"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user