Skip to content

Commit 7518e2c

Browse files
Merge 32b4e30 into 0c0d88a
2 parents 0c0d88a + 32b4e30 commit 7518e2c

1 file changed

Lines changed: 26 additions & 17 deletions

File tree

source/NVDAObjects/UIA/winConsoleUIA.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,27 @@ class consoleUIATextInfo(UIATextInfo):
2525
_expandCollapseBeforeReview = False
2626

2727
def __init__(self, obj, position, _rangeObj=None):
28+
# We want to limit textInfos to just the visible part of the console.
29+
# Therefore we specifically handle POSITION_FIRST, POSITION_LAST and POSITION_ALL.
30+
# We could use IUIAutomationTextRange::getVisibleRanges, but it seems very broken in consoles
31+
# once more than a few screens worth of content has been written to the console.
32+
# Therefore we resort to using IUIAutomationTextPattern::rangeFromPoint
33+
# for the top left, and bottom right of the console window.
34+
if position is textInfos.POSITION_FIRST:
35+
_rangeObj = self.__class__(obj, obj.location.topLeft)._rangeObj
36+
elif position is textInfos.POSITION_LAST:
37+
tempInfo = self.__class__(obj, obj.location.bottomRight)
38+
# Consoles sometimes do not honor the x coordinate,
39+
# so therefore ensure we are really at the end of the line.
40+
tempInfo.expand(textInfos.UNIT_LINE)
41+
tempInfo.collapse(end=True)
42+
_rangeObj = tempInfo._rangeObj
43+
elif position is textInfos.POSITION_ALL:
44+
first = self.__class__(obj, textInfos.POSITION_FIRST)
45+
last = self.__class__(obj, textInfos.POSITION_LAST)
46+
first.setEndPoint(last, "endToEnd")
47+
_rangeObj = first._rangeObj
2848
super(consoleUIATextInfo, self).__init__(obj, position, _rangeObj)
29-
# Re-implement POSITION_FIRST and POSITION_LAST in terms of
30-
# visible ranges to fix review top/bottom scripts.
31-
if position == textInfos.POSITION_FIRST:
32-
visiRanges = self.obj.UIATextPattern.GetVisibleRanges()
33-
firstVisiRange = visiRanges.GetElement(0)
34-
self._rangeObj = firstVisiRange
35-
self.collapse()
36-
elif position == textInfos.POSITION_LAST:
37-
visiRanges = self.obj.UIATextPattern.GetVisibleRanges()
38-
lastVisiRange = visiRanges.GetElement(visiRanges.length - 1)
39-
self._rangeObj = lastVisiRange
40-
self.collapse(True)
4149

4250
def collapse(self, end=False):
4351
"""Works around a UIA bug on Windows 10 1803 and later."""
@@ -273,11 +281,12 @@ def _get_TextInfo(self):
273281
return consoleUIATextInfo
274282

275283
def _getTextLines(self):
276-
# Filter out extraneous empty lines from UIA
277-
ptr = self.UIATextPattern.GetVisibleRanges()
278-
res = [ptr.GetElement(i).GetText(-1) for i in range(ptr.length)]
279-
return res
280-
284+
# This override of _getTextLines takes advantage of the fact that
285+
# the console text contains linefeeds for every line
286+
# Thus a simple string splitlines is much faster than splitting by unit line.
287+
ti = self.makeTextInfo(textInfos.POSITION_ALL)
288+
text = ti.text or ""
289+
return text.splitlines()
281290

282291
def findExtraOverlayClasses(obj, clsList):
283292
if obj.UIAElement.cachedAutomationId == "Text Area":

0 commit comments

Comments
 (0)