Skip to content

Commit 7b61a75

Browse files
authored
Merge 1c207b7 into c4ca763
2 parents c4ca763 + 1c207b7 commit 7b61a75

3 files changed

Lines changed: 52 additions & 32 deletions

File tree

source/NVDAObjects/UIA/winConsoleUIA.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# A part of NonVisual Desktop Access (NVDA)
22
# This file is covered by the GNU General Public License.
33
# See the file COPYING for more details.
4-
# Copyright (C) 2019-2022 Bill Dengler, Leonard de Ruijter
4+
# Copyright (C) 2019-2023 Bill Dengler, Leonard de Ruijter
55

66
import api
7+
import braille
78
import config
89
import controlTypes
910
import ctypes
@@ -479,6 +480,7 @@ def event_UIA_notification(
479480
for line in displayString.splitlines():
480481
if line and not line.isspace(): # Don't say "blank" during autoread
481482
speech.speakText(line)
483+
braille.handler.handleUpdate(self)
482484

483485

484486
def __getattr__(attrName: str) -> Any:

source/NVDAObjects/behaviors.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
# -*- coding: UTF-8 -*-
21
# A part of NonVisual Desktop Access (NVDA)
32
# This file is covered by the GNU General Public License.
43
# See the file COPYING for more details.
5-
# Copyright (C) 2006-2022 NV Access Limited, Peter Vágner, Joseph Lee, Bill Dengler
4+
# Copyright (C) 2006-2023 NV Access Limited, Peter Vágner, Joseph Lee, Bill Dengler, Leonard de Ruijter
65

76
"""Mix-in classes which provide common behaviour for particular types of controls across different APIs.
87
Behaviors described in this mix-in include providing table navigation commands for certain table rows, terminal input and output support, announcing notifications and suggestion items and so on.
@@ -411,6 +410,7 @@ def _reportNewLines(self, lines):
411410
"""
412411
for line in lines:
413412
self._reportNewText(line)
413+
braille.handler.handleUpdate(self)
414414

415415
def _reportNewText(self, line):
416416
"""Report a line of new text.

source/braille.py

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
from autoSettingsUtils.driverSetting import BooleanDriverSetting, NumericDriverSetting
6262
from utils.security import objectBelowLockScreenAndWindowsIsLocked
6363
import hwIo
64+
from buildVersion import version_year
65+
import NVDAState
6466

6567
if TYPE_CHECKING:
6668
from NVDAObjects import NVDAObject
@@ -2014,6 +2016,11 @@ class BrailleHandler(baseObject.AutoPropertyObject):
20142016
queuedWrite: Optional[List[int]] = None
20152017
queuedWriteLock: threading.Lock
20162018
ackTimerHandle: int
2019+
_regionsPendingUpdate: Set[Region]
2020+
"""
2021+
Regions pending an update.
2022+
Regions are added by L{handleUpdate} and L{handleCaretMove} and cleared in L{_handlePendingUpdate}.
2023+
"""
20172024

20182025
def __init__(self):
20192026
louisHelper.initialize()
@@ -2032,6 +2039,7 @@ def __init__(self):
20322039
with its previous output.
20332040
If L{decide_enabled} decides to disable the handler, pending output should be cleared.
20342041
"""
2042+
self._regionsPendingUpdate = set()
20352043

20362044

20372045
self.mainBuffer = BrailleBuffer(self)
@@ -2472,29 +2480,46 @@ def handleCaretMove(
24722480
region = self.mainBuffer.regions[-1] if self.mainBuffer.regions else None
24732481
if region and region.obj==obj:
24742482
region.pendingCaretUpdate=True
2483+
self._regionsPendingUpdate.add(region)
24752484
elif prevTether == TetherTo.REVIEW.value:
24762485
# The caret moved in a different object than the review position.
24772486
self._doNewObject(getFocusRegions(obj, review=False))
24782487

2479-
def handlePendingCaretUpdate(self):
2480-
"""Checks to see if the final text region needs its caret updated and if so calls _doCursorMove for the region."""
2481-
region=self.mainBuffer.regions[-1] if self.mainBuffer.regions else None
2482-
if isinstance(region,TextInfoRegion) and region.pendingCaretUpdate:
2483-
try:
2484-
self._doCursorMove(region)
2485-
finally:
2486-
region.pendingCaretUpdate=False
2488+
if version_year < 2024 and NVDAState._allowDeprecatedAPI():
2489+
def handlePendingCaretUpdate(self):
2490+
log.warning(
2491+
"braille.BrailleHandler.handlePendingCaretUpdate is now deprecated "
2492+
"with no public replacement. "
2493+
"It will be removed in NVDA 2024.1."
2494+
)
2495+
self._handlePendingUpdate()
24872496

2488-
def _doCursorMove(self, region):
2489-
self.mainBuffer.saveWindow()
2490-
region.update()
2491-
self.mainBuffer.update()
2492-
self.mainBuffer.restoreWindow()
2493-
self.scrollToCursorOrSelection(region)
2494-
if self.buffer is self.mainBuffer:
2495-
self.update()
2496-
elif self.buffer is self.messageBuffer and keyboardHandler.keyCounter>self._keyCountForLastMessage:
2497-
self._dismissMessage()
2497+
def _handlePendingUpdate(self):
2498+
"""When any region is pending an update, updates the region and the braille display.
2499+
"""
2500+
if not self._regionsPendingUpdate:
2501+
return
2502+
try:
2503+
scrollTo: Optional[TextInfoRegion] = None
2504+
self.mainBuffer.saveWindow()
2505+
for region in self._regionsPendingUpdate:
2506+
region.update()
2507+
if isinstance(region, TextInfoRegion) and region.pendingCaretUpdate:
2508+
scrollTo = region
2509+
region.pendingCaretUpdate = False
2510+
self.mainBuffer.update()
2511+
self.mainBuffer.restoreWindow()
2512+
if scrollTo is not None:
2513+
self.scrollToCursorOrSelection(scrollTo)
2514+
if self.buffer is self.mainBuffer:
2515+
self.update()
2516+
elif (
2517+
self.buffer is self.messageBuffer
2518+
and keyboardHandler.keyCounter > self._keyCountForLastMessage
2519+
):
2520+
self._dismissMessage()
2521+
finally:
2522+
self._regionsPendingUpdate.clear()
24982523

24992524
def scrollToCursorOrSelection(self, region):
25002525
if region.brailleCursorPos is not None:
@@ -2548,14 +2573,7 @@ def handleUpdate(self, obj: "NVDAObject") -> None:
25482573
if isinstance(obj, NVDAObject) and obj.role == controlTypes.Role.PROGRESSBAR and obj.isInForeground:
25492574
self._handleProgressBarUpdate(obj)
25502575
return
2551-
self.mainBuffer.saveWindow()
2552-
region.update()
2553-
self.mainBuffer.update()
2554-
self.mainBuffer.restoreWindow()
2555-
if self.buffer is self.mainBuffer:
2556-
self.update()
2557-
elif self.buffer is self.messageBuffer and keyboardHandler.keyCounter>self._keyCountForLastMessage:
2558-
self._dismissMessage()
2576+
self._regionsPendingUpdate.add(region)
25592577

25602578
def handleReviewMove(self, shouldAutoTether=True):
25612579
if not self.enabled:
@@ -2567,7 +2585,7 @@ def handleReviewMove(self, shouldAutoTether=True):
25672585
return
25682586
region = self.mainBuffer.regions[-1] if self.mainBuffer.regions else None
25692587
if region and region.obj == reviewPos.obj:
2570-
self._doCursorMove(region)
2588+
self._regionsPendingUpdate.add(region)
25712589
else:
25722590
# We're reviewing a different object.
25732591
self._doNewObject(getFocusRegions(reviewPos.obj, review=True))
@@ -2720,8 +2738,8 @@ def initialize():
27202738
handler.setDisplayByName(config.conf["braille"]["display"])
27212739

27222740
def pumpAll():
2723-
"""Runs tasks at the end of each core cycle. For now just caret updates."""
2724-
handler.handlePendingCaretUpdate()
2741+
"""Runs tasks at the end of each core cycle. For now just region updates, e.g. for caret movement."""
2742+
handler._handlePendingUpdate()
27252743

27262744
def terminate():
27272745
global handler

0 commit comments

Comments
 (0)