Skip to content

Commit

Permalink
Merge fbd37d1 into c4ca763
Browse files Browse the repository at this point in the history
  • Loading branch information
burmancomp committed Jul 18, 2023
2 parents c4ca763 + fbd37d1 commit d33cb7f
Showing 1 changed file with 80 additions and 2 deletions.
82 changes: 80 additions & 2 deletions source/braille.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
Tuple,
Union,
Type,
Callable,
)
from locale import strxfrm

Expand Down Expand Up @@ -53,6 +54,7 @@
import re
import scriptHandler
import collections
from collections import deque
import extensionPoints
import hwPortUtils
import bdDetect
Expand Down Expand Up @@ -1569,6 +1571,7 @@ def bufferPosToRegionPos(self, bufferPos):
raise LookupError("No such position")

def regionPosToBufferPos(self, region, pos, allowNearest=False):
start: int = 0
for testRegion, start, end in self.regionsWithPositions:
if region == testRegion:
if pos < end - start:
Expand Down Expand Up @@ -2003,6 +2006,46 @@ def formatCellsForLog(cells: List[int]) -> str:
"""


class RepeatedTimer:
"""Repeating timer.
Timer is used to try to ensure that display content is always up to date.
"""

def __init__(
self,
interval: float,
updateFunction: Callable[[], None]
):
"""Constructor.
@param interval: Checking frequency
@param updateFunction: Update display
"""
self._interval = interval
self._timer = threading.Timer(self._interval, self._run)
self._updateFunction = updateFunction
self.is_running = False
self.start()

def _run(self):
self.is_running = False
self.start()
self._updateFunction()

def start(self):
if not self.is_running:
self._timer = threading.Timer(self._interval, self._run)
self._timer.start()
self.is_running = True

def stop(self):
self._timer.cancel()
self.is_running = False


UPDATE_DISPLAY_PERIODICALLY_INTERVAL: float = 0.5
"""Timer interval for L{BrailleHandler._updateDisplayPeriodically}."""


class BrailleHandler(baseObject.AutoPropertyObject):
# TETHER_AUTO, TETHER_FOCUS, TETHER_REVIEW and tetherValues
# are deprecated, but remain to retain API backwards compatibility
Expand Down Expand Up @@ -2042,6 +2085,13 @@ def __init__(self):
self._cursorPos = None
self._cursorBlinkUp = True
self._cells = []
self._oldCells: List[int] = []
self._handleUpdateQueue = deque(maxlen=1)
self._updateTimer = RepeatedTimer(
UPDATE_DISPLAY_PERIODICALLY_INTERVAL,
self._updateDisplayPeriodically
)
self._updateTimer.start()
self._cursorBlinkTimer = None
config.post_configProfileSwitch.register(self.handlePostConfigProfileSwitch)
if config.conf["braille"]["tetherTo"] == TetherTo.AUTO.value:
Expand All @@ -2064,6 +2114,9 @@ def terminate(self):
if self._cursorBlinkTimer:
self._cursorBlinkTimer.Stop()
self._cursorBlinkTimer = None
if self._updateTimer:
self._updateTimer.stop()
self._updateTimer = None
config.post_configProfileSwitch.unregister(self.handlePostConfigProfileSwitch)
if self.display:
self.display.terminate()
Expand Down Expand Up @@ -2468,6 +2521,12 @@ def handleCaretMove(
if shouldAutoTether:
self.setTether(TetherTo.FOCUS.value, auto=True)
if self._tether != TetherTo.FOCUS.value:
# Braille display content is updated in case where:
# braille is tethered to review, review cursor does not follow system caret,
# and focus object is navigator object.
if not config.conf["reviewCursor"]["followCaret"]:
if obj == api.getNavigatorObject():
self.handleUpdate(obj)
return
region = self.mainBuffer.regions[-1] if self.mainBuffer.regions else None
if region and region.obj==obj:
Expand Down Expand Up @@ -2526,7 +2585,7 @@ def _handleProgressBarUpdate(
self.handleUpdate(obj)
return

def handleUpdate(self, obj: "NVDAObject") -> None:
def handleUpdate(self, obj: "NVDAObject", fromTimer: bool = False) -> None:
if not self.enabled:
return
if objectBelowLockScreenAndWindowsIsLocked(obj):
Expand All @@ -2553,7 +2612,10 @@ def handleUpdate(self, obj: "NVDAObject") -> None:
self.mainBuffer.update()
self.mainBuffer.restoreWindow()
if self.buffer is self.mainBuffer:
if fromTimer and self._oldCells == self.buffer.windowBrailleCells:
return
self.update()
self._oldCells = self.buffer.windowBrailleCells.copy()
elif self.buffer is self.messageBuffer and keyboardHandler.keyCounter>self._keyCountForLastMessage:
self._dismissMessage()

Expand Down Expand Up @@ -2686,6 +2748,19 @@ def _ackTimeoutResetter(self, param: int):
self.display._awaitingAck = False
self._writeCellsInBackground()

def _updateDisplayPeriodically(self):
"""Timer runs this function periodically to ensure content is up to date."""
if self.buffer is not self.mainBuffer:
return
obj: NVDAObject
if api.isObjectInActiveTreeInterceptor(api.getNavigatorObject()):
obj = api.getCaretObject()
elif handler.getTether() == TetherTo.FOCUS.value:
obj = api.getFocusObject()
else:
obj = api.getNavigatorObject()
self._handleUpdateQueue.append(obj)


# Maps old braille display driver names to new drivers that supersede old drivers.
# Ensure that if a user has set a preferred driver which has changed name, the new
Expand Down Expand Up @@ -2720,14 +2795,17 @@ def initialize():
handler.setDisplayByName(config.conf["braille"]["display"])

def pumpAll():
"""Runs tasks at the end of each core cycle. For now just caret updates."""
"""Runs tasks at the end of each core cycle."""
if len(handler._handleUpdateQueue):
handler.handleUpdate(handler._handleUpdateQueue.popleft(), True)
handler.handlePendingCaretUpdate()

def terminate():
global handler
handler.terminate()
handler = None


class BrailleDisplayDriver(driverHandler.Driver):
"""Abstract base braille display driver.
Each braille display driver should be a separate Python module in the root brailleDisplayDrivers directory
Expand Down

0 comments on commit d33cb7f

Please sign in to comment.