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

UI Automation in Windows Console and Windows Terminal: Make POSITION_FIRST and POSITION_LAST relative to visible text in FORMATTED consoles #13671

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions source/NVDAObjects/UIA/winConsoleUIA.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@


class ConsoleUIATextInfo(UIATextInfo):
"A TextInfo implementation for consoles with an IMPROVED, but not FORMATTED, API level."
"A TextInfo implementation for consoles with a FORMATTED API level."

# #13157: In FORMATTED consoles, the review cursor is not bounded to the
# visible text, allowing text to be freely explored.
# However, it is often useful to jump to the top or bottom of a screen of
# text when viewing paginated output. To enable this use case, make
# POSITION_FIRST and POSITION_LAST relative to the visible text.
_RESTRICT_TO_VISIBLE_POSITIONS = (
textInfos.POSITION_FIRST,
textInfos.POSITION_LAST
)

def __init__(self, obj, position, _rangeObj=None):
collapseToEnd = None
# We want to limit textInfos to just the visible part of the console.
# Therefore we specifically handle POSITION_FIRST, POSITION_LAST and POSITION_ALL.
if not _rangeObj and position in (
textInfos.POSITION_FIRST,
textInfos.POSITION_LAST,
textInfos.POSITION_ALL
):
if not _rangeObj and position in self._RESTRICT_TO_VISIBLE_POSITIONS:
try:
_rangeObj, collapseToEnd = self._getBoundingRange(obj, position)
except (COMError, RuntimeError):
Expand Down Expand Up @@ -61,6 +66,20 @@ def _getBoundingRange(self, obj, position):
collapseToEnd = True
return (_rangeObj, collapseToEnd)


class ConsoleUIATextInfoBounded(ConsoleUIATextInfo):
"A TextInfo implementation for consoles with an IMPROVED, but not FORMATTED, API level."

# Since pre-FORMATTED consoles have thousands of empty lines at the end of
# output, we want to limit textInfos to just the visible part of the
# console. Therefore we specifically handle POSITION_FIRST, POSITION_LAST
# and POSITION_ALL.
_RESTRICT_TO_VISIBLE_POSITIONS = (
textInfos.POSITION_FIRST,
textInfos.POSITION_LAST,
textInfos.POSITION_ALL
)

def move(self, unit, direction, endPoint=None):
oldInfo = None
if self.basePosition != textInfos.POSITION_CARET:
Expand Down Expand Up @@ -369,9 +388,9 @@ def _get_TextInfo(self):
ConsoleUIATextInfoWorkaroundEndInclusive fixes expand/collapse and implements
word movement."""
if self.apiLevel >= WinConsoleAPILevel.FORMATTED:
return UIATextInfo # No TextInfo workarounds needed
elif self.apiLevel >= WinConsoleAPILevel.IMPROVED:
return ConsoleUIATextInfo
elif self.apiLevel >= WinConsoleAPILevel.IMPROVED:
return ConsoleUIATextInfoBounded
else:
return ConsoleUIATextInfoWorkaroundEndInclusive

Expand Down Expand Up @@ -420,6 +439,9 @@ def findExtraOverlayClasses(obj, clsList):


class WinTerminalUIA(EnhancedTermTypedCharSupport):
def _get_TextInfo(self):
return ConsoleUIATextInfo

def event_UIA_notification(self, **kwargs):
"""
In an upcoming terminal release, UIA notification events will be sent
Expand Down