Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 of UI Automation in Windows Console: fix setEndPoint/compareEndPoints #10057

Merged
merged 12 commits into from
Aug 12, 2019
40 changes: 37 additions & 3 deletions source/NVDAObjects/UIA/winConsoleUIA.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,49 @@ def expand(self, unit):
else:
return super(consoleUIATextInfo, self).expand(unit)

def _get_isCollapsed(self):
def compareEndPoints(self, other, which):
"""Works around a UIA bug on Windows 10 1803 and later."""
feerrenrut marked this conversation as resolved.
Show resolved Hide resolved
# Even when a console textRange's start and end have been moved to the
# same position, the console incorrectly reports the end as being
# past the start.
# Therefore to decide if the textRange is collapsed,
# Check if it has no text.
# Compare to the start (not the end) when collapsed.
selfEndPoint, otherEndPoint = which.split("To")
if selfEndPoint == "end" and not self._isCollapsed():
selfEndPoint = "start"
if otherEndPoint == "End" and not other._isCollapsed():
otherEndPoint = "Start"
which = f"{selfEndPoint}To{otherEndPoint}"
return super().compareEndPoints(other, which=which)

def setEndPoint(self, other, which):
"""Override of L{textInfos.TextInfo.setEndPoint}.
Works around a UIA bug on Windows 10 1803 and later that means we can
not trust the "end" endpoint of a collapsed (empty) text range
for comparisons.
"""
selfEndPoint, otherEndPoint = which.split("To")
# In this case, there is no need to check if self is collapsed
# since the point of this method is to change its text range, modifying the "end" endpoint of a collapsed
# text range is fine.
if otherEndPoint == "End" and not other._isCollapsed():
otherEndPoint = "Start"
which = f"{selfEndPoint}To{otherEndPoint}"
return super().setEndPoint(other, which=which)

def _isCollapsed(self):
"""Works around a UIA bug on Windows 10 1803 and later that means we
cannot trust the "end" endpoint of a collapsed (empty) text range
for comparisons.
Instead we check to see if we can get the first character from the
text range. A collapsed range will not have any characters
and will return an empty string."""
return not bool(self._rangeObj.getText(1))

def _get_isCollapsed(self):
# To decide if the textRange is collapsed,
# Check if it has no text.
return self._isCollapsed

def _getCurrentOffsetInThisLine(self, lineInfo):
"""
Given a caret textInfo expanded to line, returns the index into the
Expand Down