diff --git a/config/keyboard/pty.conf b/config/keyboard/pty.conf index 5d20c07e..484d14c4 100644 --- a/config/keyboard/pty.conf +++ b/config/keyboard/pty.conf @@ -1,5 +1,7 @@ # f1 - fenrir help ^[OP=toggle_tutorial_mode +# double tap control+end read attributes +^[[1;5F^[[1;5F=attribute_cursor # escape - stop speech ^[=shut_up # context menu key - stop speech diff --git a/src/fenrirscreenreader/core/byteManager.py b/src/fenrirscreenreader/core/byteManager.py index c3e5de8a..53354eee 100644 --- a/src/fenrirscreenreader/core/byteManager.py +++ b/src/fenrirscreenreader/core/byteManager.py @@ -5,13 +5,19 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -import os, inspect, re +from fenrirscreenreader.core.eventData import fenrirEventType +import os, inspect, re, time currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) fenrirPath = os.path.dirname(currentdir) class byteManager(): def __init__(self): - pass + self.command = '' + self.switchCtrlModeOnce = 0 + self.controlMode = True + self.repeat = 1 + self.lastInputTime = time.time() + self.lastByteKey = b'' def initialize(self, environment): self.env = environment def shutdown(self): @@ -23,7 +29,63 @@ class byteManager(): if len(convertedEscapeSequence) > 1: if convertedEscapeSequence[0] == 94 and convertedEscapeSequence[1] ==91: convertedEscapeSequence = b'^[' + convertedEscapeSequence[2:] - return convertedEscapeSequence + return convertedEscapeSequence + def handleByteInput(self, eventData): + if not eventData: + return + if eventData == b'': + return + + convertedEscapeSequence = self.unifyEscapeSeq(eventData) + + if self.switchCtrlModeOnce > 0: + self.switchCtrlModeOnce -= 1 + + isControlMode = False + if self.controlMode and not self.switchCtrlModeOnce == 1 or\ + not self.controlMode: + isControlMode = self.handleControlMode(eventData) + shortcutData = convertedEscapeSequence + if self.lastByteKey == convertedEscapeSequence: + if time.time() - self.lastInputTime <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'): + self.repeat += 1 + shortcutData = shortcutData + convertedEscapeSequence + isCommand = False + if self.controlMode and not self.switchCtrlModeOnce == 1 or\ + not self.controlMode and self.switchCtrlModeOnce == 1: + isCommand = self.detectByteCommand(shortcutData) + if not isCommand: + isCommand = self.detectByteCommand(convertedEscapeSequence) + self.repeat = 1 + if not (isCommand or isControlMode): + self.env['runtime']['screenManager'].injectTextToScreen(eventData) + if not isCommand: + self.repeat = 1 + self.lastByteKey = convertedEscapeSequence + self.lastInputTime = time.time() + def handleControlMode(self, escapeSequence): + convertedEscapeSequence = self.unifyEscapeSeq(escapeSequence) + if convertedEscapeSequence == b'^[R': + self.controlMode = not self.controlMode + self.switchCtrlModeOnce = 0 + if self.controlMode: + self.env['runtime']['outputManager'].presentText(_('Sticky Mode On'), soundIcon='Accept', interrupt=True, flush=True) + else: + self.env['runtime']['outputManager'].presentText(_('Sticky Mode On'), soundIcon='Cancel', interrupt=True, flush=True) + return True + if convertedEscapeSequence == b'^[:': + self.switchCtrlModeOnce = 2 + self.env['runtime']['outputManager'].presentText(_('bypass'), soundIcon='PTYBypass', interrupt=True, flush=True) + return True + return False + def detectByteCommand(self, escapeSequence): + convertedEscapeSequence = self.unifyEscapeSeq(escapeSequence) + self.command = self.env['runtime']['inputManager'].getCommandForShortcut(convertedEscapeSequence) + if self.command != '': + self.env['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) + self.command = '' + return True + return False def loadByteShortcuts(self, kbConfigPath=fenrirPath + '/../../config/keyboard/pty.conf'): kbConfig = open(kbConfigPath,"r") while(True): diff --git a/src/fenrirscreenreader/core/fenrirManager.py b/src/fenrirscreenreader/core/fenrirManager.py index 6e4d70c9..4e5df778 100644 --- a/src/fenrirscreenreader/core/fenrirManager.py +++ b/src/fenrirscreenreader/core/fenrirManager.py @@ -92,38 +92,12 @@ class fenrirManager(): return if event['Data'] == b'': return - self.environment['runtime']['commandManager'].executeDefaultTrigger('onByteInput') - - if self.switchCtrlModeOnce > 0: - self.switchCtrlModeOnce -= 1 - - isControlMode = False - if self.controlMode and not self.switchCtrlModeOnce == 1 or\ - not self.controlMode: - isControlMode = self.handleControlMode(event['Data']) - - isCommand = False - if self.controlMode and not self.switchCtrlModeOnce == 1 or\ - not self.controlMode and self.switchCtrlModeOnce == 1: - isCommand = self.detectByteCommand(event['Data']) - if not (isCommand or isControlMode): - self.environment['runtime']['screenManager'].injectTextToScreen(event['Data']) - def handleControlMode(self, escapeSequence): - convertedEscapeSequence = self.environment['runtime']['byteManager'].unifyEscapeSeq(escapeSequence) - if convertedEscapeSequence == b'^[R': - self.controlMode = not self.controlMode - self.switchCtrlModeOnce = 0 - if self.controlMode: - self.environment['runtime']['outputManager'].presentText(_('Sticky Mode On'), soundIcon='Accept', interrupt=True, flush=True) - else: - self.environment['runtime']['outputManager'].presentText(_('Sticky Mode On'), soundIcon='Cancel', interrupt=True, flush=True) - return True - if convertedEscapeSequence == b'^[:': - self.switchCtrlModeOnce = 2 - self.environment['runtime']['outputManager'].presentText(_('bypass'), soundIcon='PTYBypass', interrupt=True, flush=True) - return True - return False - def handleExecuteCommand(self, event): + self.environment['runtime']['byteManager'].handleByteInput(event['Data']) + + self.environment['runtime']['commandManager'].executeDefaultTrigger('onByteInput') + def handleExecuteCommand(self, event): + if not event['Data']: + return if event['Data'] == '': return command = event['Data'] @@ -173,15 +147,7 @@ class fenrirManager(): self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat',force=True) #self.environment['runtime']['outputManager'].brailleText(flush=False) - def detectByteCommand(self, escapeSequence): - convertedEscapeSequence = self.environment['runtime']['byteManager'].unifyEscapeSeq(escapeSequence) - self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(convertedEscapeSequence) - self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) - if self.command != '': - self.command = '' - return True - return False def detectShortcutCommand(self): if self.environment['input']['keyForeward'] > 0: return diff --git a/src/fenrirscreenreader/screenDriver/ptyDriver.py b/src/fenrirscreenreader/screenDriver/ptyDriver.py index 14335349..e3f20343 100644 --- a/src/fenrirscreenreader/screenDriver/ptyDriver.py +++ b/src/fenrirscreenreader/screenDriver/ptyDriver.py @@ -76,7 +76,7 @@ class driver(screenDriver): self.env['general']['currUser'] = getpass.getuser() def readAll(self,fd, timeout = 9999999, interruptFdList = None): starttime = time.time() - bytes = os.read(fd, 200) + bytes = os.read(fd, 4096) if bytes == b'': raise EOFError # respect timeout but wait a little bit of time to see if something more is here @@ -88,7 +88,7 @@ class driver(screenDriver): break if (time.time() - starttime) >= timeout: break - data = os.read(fd, 100) + data = os.read(fd, 4096) if data == b'': raise EOFError bytes += data @@ -156,7 +156,7 @@ class driver(screenDriver): # output if self.p_out in r: try: - msgBytes = self.readAll(self.p_out.fileno(), timeout=0.1, interruptFdList=[sys.stdin]) + msgBytes = self.readAll(self.p_out.fileno(), timeout=0.05, interruptFdList=[sys.stdin]) except (EOFError, OSError): active.value = False break