diff --git a/src/fenrir/commands/onScreenUpdate/deactive/72000-history.py b/src/fenrir/commands/onScreenUpdate/60000-history.py similarity index 86% rename from src/fenrir/commands/onScreenUpdate/deactive/72000-history.py rename to src/fenrir/commands/onScreenUpdate/60000-history.py index 7cde4a06..efdbe244 100644 --- a/src/fenrir/commands/onScreenUpdate/deactive/72000-history.py +++ b/src/fenrir/commands/onScreenUpdate/60000-history.py @@ -15,19 +15,15 @@ class command(): pass def getDescription(self): return '' - + def run(self): - if self.env['runtime']['inputManager'].noKeyPressed(): - return if self.env['screen']['newAttribDelta'] != '': return if self.env['runtime']['screenManager'].isScreenChange(): return if self.env['runtime']['cursorManager'].isCursorVerticalMove(): return - if len(self.env['input']['currInput']) != 1: - return - if not self.env['input']['currInput'][0] in ['KEY_UP','KEY_DOWN']: + if not (self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_UP'],['KEY_DOWN']]): return prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']] currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] diff --git a/src/fenrir/core/fenrirManager.py b/src/fenrir/core/fenrirManager.py index d6193199..4ac8ec97 100644 --- a/src/fenrir/core/fenrirManager.py +++ b/src/fenrir/core/fenrirManager.py @@ -51,6 +51,8 @@ class fenrirManager(): def handleInput(self, event): #startTime = time.time() eventReceived = self.environment['runtime']['inputManager'].getInputEvent() + if self.environment['runtime']['inputManager'].noKeyPressed(): + self.environment['runtime']['inputManager'].clearLastDeepInput() if eventReceived: if self.environment['runtime']['screenManager'].isSuspendingScreen(): @@ -106,11 +108,15 @@ class fenrirManager(): self.environment['runtime']['applicationManager'].getPrevApplication(), \ self.environment['runtime']['applicationManager'].getCurrentApplication()) ''' - # has cursor changed? + # timout for the last keypress + if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3: + self.environment['runtime']['inputManager'].clearLastDeepInput() + # has cursor changed? if self.environment['runtime']['cursorManager'].isCursorVerticalMove() or \ self.environment['runtime']['cursorManager'].isCursorHorizontalMove(): self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange') self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate') + self.environment['runtime']['inputManager'].clearLastDeepInput() #print('handleScreenUpdate:',time.time() - startTime) def handlePlugInputDevice(self, event): @@ -128,7 +134,7 @@ class fenrirManager(): else: if not self.environment['runtime']['inputManager'].noKeyPressed(): if self.singleKeyCommand: - self.singleKeyCommand = len(self.environment['input']['prevDeepestInput']) == 1 + self.singleKeyCommand = len( self.environment['runtime']['inputManager'].getLastDeepestInput() ) == 1 # key is already released. we need the old one if not( self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()): shortcut = self.environment['runtime']['inputManager'].getCurrShortcut() diff --git a/src/fenrir/core/inputManager.py b/src/fenrir/core/inputManager.py index df82337e..2620eab0 100644 --- a/src/fenrir/core/inputManager.py +++ b/src/fenrir/core/inputManager.py @@ -22,7 +22,8 @@ class inputManager(): self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock'] self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2) self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock'] - + self.lastDeepestInput = [] + self.lastInputTime = time.time() def shutdown(self): self.removeAllDevices() self.env['runtime']['settingsManager'].shutdownDriver('inputDriver') @@ -40,26 +41,25 @@ class inputManager(): if len(self.env['input']['currInput']) > 1: self.env['input']['currInput'] = sorted(self.env['input']['currInput']) elif len(self.env['input']['currInput']) == 0: - self.env['input']['prevDeepestInput'] = [] self.env['input']['shortcutRepeat'] = 1 self.setLedState = self.handleLedStates(mEvent) - self.env['input']['lastInputTime'] = time.time() + self.lastInputTime = time.time() elif mEvent['EventState'] == 1: if not mEvent['EventName'] in self.env['input']['currInput']: self.env['input']['currInput'].append(mEvent['EventName']) if len(self.env['input']['currInput']) > 1: self.env['input']['currInput'] = sorted(self.env['input']['currInput']) - if len(self.env['input']['prevDeepestInput']) < len(self.env['input']['currInput']): - self.env['input']['prevDeepestInput'] = self.env['input']['currInput'].copy() - elif self.env['input']['prevDeepestInput'] == self.env['input']['currInput']: - if time.time() - self.env['input']['lastInputTime'] <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'): + if len(self.lastDeepestInput) < len(self.env['input']['currInput']): + self.setLastDeepestInput( self.env['input']['currInput'].copy()) + elif self.lastDeepestInput == self.env['input']['currInput']: + if time.time() - self.lastInputTime <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'): self.env['input']['shortcutRepeat'] += 1 else: self.env['input']['shortcutRepeat'] = 1 self.setLedState = self.handleLedStates(mEvent) - self.env['input']['lastInputTime'] = time.time() + self.lastInputTime = time.time() elif mEvent['EventState'] == 2: - self.env['input']['lastInputTime'] = time.time() + self.lastInputTime = time.time() else: pass self.env['input']['oldNumLock'] = self.env['input']['newNumLock'] @@ -143,7 +143,14 @@ class inputManager(): def clearEventBuffer(self): self.env['runtime']['inputDriver'].clearEventBuffer() - + def setLastDeepestInput(self, currentDeepestInput): + self.lastDeepestInput = currentDeepestInput + def clearLastDeepInput(self): + self.lastDeepestInput = [] + def getLastInputTime(self): + return self.lastInputTime + def getLastDeepestInput(self): + return self.lastDeepestInput def writeEventBuffer(self): try: if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): @@ -157,10 +164,10 @@ class inputManager(): return self.env['input']['currInput'] == [] def isKeyPress(self): return (self.env['input']['prevInput'] == []) and (self.env['input']['currInput'] != []) - def getPrevDeepestInput(self): + def getPrevDeepestShortcut(self): shortcut = [] shortcut.append(self.env['input']['shortcutRepeat']) - shortcut.append(self.env['input']['prevDeepestInput']) + shortcut.append(self.getLastDeepestInput()) return str(shortcut) def getPrevShortcut(self): @@ -186,7 +193,7 @@ class inputManager(): return str(shortcut) def currKeyIsModifier(self): - if len(self.env['input']['prevDeepestInput']) != 1: + if len(self.getLastDeepestInput()) != 1: return False return (self.env['input']['currInput'][0] =='KEY_FENRIR') or (self.env['input']['currInput'][0] == 'KEY_SCRIPT') diff --git a/src/fenrir/screenDriver/vcsaDriver.py b/src/fenrir/screenDriver/vcsaDriver.py index 56aab35b..618a89aa 100644 --- a/src/fenrir/screenDriver/vcsaDriver.py +++ b/src/fenrir/screenDriver/vcsaDriver.py @@ -128,9 +128,8 @@ class driver(): currScreen = str(tty.read()[3:-1]) oldScreen = currScreen watchdog = select.epoll() - watchdog.register(vcsa[currScreen], select.EPOLLPRI) - watchdog.register(tty, select.EPOLLPRI) - lastScreenContent = b'' + watchdog.register(vcsa[currScreen], select.POLLPRI | select.POLLERR) + watchdog.register(tty, select.POLLPRI | select.POLLERR) while active.value == 1: changes = watchdog.poll(2) for change in changes: @@ -146,7 +145,7 @@ class driver(): except: pass try: - watchdog.register(vcsa[ currScreen ], select.EPOLLPRI) + watchdog.register(vcsa[ currScreen ], select.POLLPRI | select.POLLERR) except: pass oldScreen = currScreen @@ -155,14 +154,21 @@ class driver(): vcsa[currScreen].seek(0) lastScreenContent = vcsa[currScreen].read() except: - lastScreenContent = b'' + pass else: self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO) - vcsa[currScreen].seek(0) - screenContent = vcsa[currScreen].read() - if screenContent != lastScreenContent: - eventQueue.put({"Type":fenrirEventType.ScreenUpdate,"Data":None}) - lastScreenContent = screenContent + vcsa[currScreen].seek(0) + dirtyContent = vcsa[currScreen].read() + screenContent = b'' + timeout = time.time() + while screenContent != dirtyContent: + screenContent = dirtyContent + if time.time() - timeout >= 0.4: + break + time.sleep(0.03) + vcsa[currScreen].seek(0) + dirtyContent = vcsa[currScreen].read() + eventQueue.put({"Type":fenrirEventType.ScreenUpdate,"Data":None}) except Exception as e: self.env['runtime']['debug'].writeDebugOut('VCSA:updateWatchdog:' + str(e),debug.debugLevel.ERROR) diff --git a/src/fenrir/utils/screen_utils.py b/src/fenrir/utils/screen_utils.py index 432f1aac..267bcdad 100644 --- a/src/fenrir/utils/screen_utils.py +++ b/src/fenrir/utils/screen_utils.py @@ -7,6 +7,9 @@ from core import debug from collections import Counter import string +from select import select +from select import epoll +import select def removeNonprintable(text): # Get the difference of all ASCII characters from the set of printable characters @@ -20,6 +23,16 @@ def insertNewlines(string, every=64): def splitEvery(toSplit, every=64): return list(toSplit[i:i+every] for i in range(0, len(toSplit), every)) +def hasMoreRead(fd): + r, w, e = select([fd], [], [], 0) + return (fd in r) + +def hasMorePollPri(fd): + p = epoll() + p.register(fd, select.POLLPRI | select.POLLERR) + r = p.poll(0) + return (fd in r) + def trackHighlights(oldAttr, newAttr, text, lenght): result = '' currCursor = None