Skip to content

Commit cca30e2

Browse files
authored
Merge c33ef89 into 9157916
2 parents 9157916 + c33ef89 commit cca30e2

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

source/braille.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
TetherTo,
4343
ReportTableHeaders,
4444
)
45+
from config.featureFlag import FeatureFlag
4546
from config.featureFlagEnums import ReviewRoutingMovesSystemCaretFlag
4647
from logHandler import log
4748
import controlTypes
@@ -1569,6 +1570,7 @@ def bufferPosToRegionPos(self, bufferPos):
15691570
raise LookupError("No such position")
15701571

15711572
def regionPosToBufferPos(self, region, pos, allowNearest=False):
1573+
start: int = 0
15721574
for testRegion, start, end in self.regionsWithPositions:
15731575
if region == testRegion:
15741576
if pos < end - start:
@@ -2003,6 +2005,22 @@ def formatCellsForLog(cells: List[int]) -> str:
20032005
"""
20042006

20052007

2008+
class UpdateTimer(wx.Timer):
2009+
"""Repeating timer for keeping display content always up to date."""
2010+
2011+
def __init__(self):
2012+
"""Constructor."""
2013+
super().__init__()
2014+
2015+
def Notify(self) -> None:
2016+
"""Check if braille needs update."""
2017+
handler.brailleUpdateCheck()
2018+
2019+
2020+
BRAILLE_UPDATE_CHECK_INTERVAL: int = 500
2021+
"""Timer interval in milliseconds for L{BrailleHandler._brailleUpdateCheck}."""
2022+
2023+
20062024
class BrailleHandler(baseObject.AutoPropertyObject):
20072025
# TETHER_AUTO, TETHER_FOCUS, TETHER_REVIEW and tetherValues
20082026
# are deprecated, but remain to retain API backwards compatibility
@@ -2042,6 +2060,12 @@ def __init__(self):
20422060
self._cursorPos = None
20432061
self._cursorBlinkUp = True
20442062
self._cells = []
2063+
self._showSelection: FeatureFlag = config.conf["braille"]["showSelection"]
2064+
self._showCursor: bool = config.conf["braille"]["showCursor"]
2065+
# Was braille line updated during previous timer cycle.
2066+
self._alreadyUpdated: bool = False
2067+
self._updateTimer = UpdateTimer()
2068+
self._updateTimer.Start(BRAILLE_UPDATE_CHECK_INTERVAL)
20452069
self._cursorBlinkTimer = None
20462070
config.post_configProfileSwitch.register(self.handlePostConfigProfileSwitch)
20472071
if config.conf["braille"]["tetherTo"] == TetherTo.AUTO.value:
@@ -2064,6 +2088,9 @@ def terminate(self):
20642088
if self._cursorBlinkTimer:
20652089
self._cursorBlinkTimer.Stop()
20662090
self._cursorBlinkTimer = None
2091+
if self._updateTimer:
2092+
self._updateTimer.Stop()
2093+
self._updateTimer = None
20672094
config.post_configProfileSwitch.unregister(self.handlePostConfigProfileSwitch)
20682095
if self.display:
20692096
self.display.terminate()
@@ -2332,6 +2359,7 @@ def _blink(self):
23322359
self._displayWithCursor()
23332360

23342361
def update(self):
2362+
self._alreadyUpdated = True
23352363
cells = self.buffer.windowBrailleCells
23362364
self._rawText = self.buffer.windowRawText
23372365
if log.isEnabledFor(log.IO):
@@ -2341,6 +2369,8 @@ def update(self):
23412369
self._cells = cells + [0] * (self.displaySize - len(cells))
23422370
self._cursorPos = self.buffer.cursorWindowPos
23432371
self._updateDisplay()
2372+
self._showSelection = config.conf["braille"]["showSelection"]
2373+
self._showCursor = config.conf["braille"]["showCursor"]
23442374

23452375
def scrollForward(self):
23462376
self.buffer.scrollForward()
@@ -2468,6 +2498,12 @@ def handleCaretMove(
24682498
if shouldAutoTether:
24692499
self.setTether(TetherTo.FOCUS.value, auto=True)
24702500
if self._tether != TetherTo.FOCUS.value:
2501+
# Braille display content is updated in case where:
2502+
# braille is tethered to review, review cursor does not follow system caret,
2503+
# and focus object is navigator object.
2504+
if not config.conf["reviewCursor"]["followCaret"]:
2505+
if obj == api.getNavigatorObject():
2506+
self.handleUpdate(obj)
24712507
return
24722508
region = self.mainBuffer.regions[-1] if self.mainBuffer.regions else None
24732509
if region and region.obj==obj:
@@ -2686,6 +2722,28 @@ def _ackTimeoutResetter(self, param: int):
26862722
self.display._awaitingAck = False
26872723
self._writeCellsInBackground()
26882724

2725+
def brailleUpdateCheck(self) -> None:
2726+
"""Braille may need update when show cursor or show selection state change or when in terminal window."""
2727+
if self.buffer is not self.mainBuffer:
2728+
return
2729+
if self._alreadyUpdated:
2730+
self._alreadyUpdated = False
2731+
return
2732+
obj: NVDAObject
2733+
if api.isObjectInActiveTreeInterceptor(api.getNavigatorObject()):
2734+
obj = api.getCaretObject()
2735+
elif self.getTether() == TetherTo.FOCUS.value:
2736+
obj = api.getFocusObject()
2737+
else:
2738+
obj = api.getNavigatorObject()
2739+
if (
2740+
hasattr(obj, "role") and obj.role == controlTypes.Role.TERMINAL
2741+
or self._showSelection != config.conf["braille"]["showSelection"]
2742+
):
2743+
self.handleUpdate(obj)
2744+
elif self._showCursor != config.conf["braille"]["showCursor"]:
2745+
self.update()
2746+
26892747

26902748
# Maps old braille display driver names to new drivers that supersede old drivers.
26912749
# Ensure that if a user has set a preferred driver which has changed name, the new
@@ -2728,6 +2786,7 @@ def terminate():
27282786
handler.terminate()
27292787
handler = None
27302788

2789+
27312790
class BrailleDisplayDriver(driverHandler.Driver):
27322791
"""Abstract base braille display driver.
27332792
Each braille display driver should be a separate Python module in the root brailleDisplayDrivers directory

0 commit comments

Comments
 (0)