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: make review bounds configurable #9687

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 101 additions & 10 deletions source/NVDAObjects/UIA/winConsoleUIA.py
Expand Up @@ -4,14 +4,17 @@
# See the file COPYING for more details.
# Copyright (C) 2019 Bill Dengler

import api
import config
import ctypes
import NVDAHelper
import speech
import time
import textInfos
import ui
import UIAHandler

from inputCore import SCRCAT_MISC
from scriptHandler import script
from winVersion import isAtLeastWin10
from . import UIATextInfo
Expand Down Expand Up @@ -100,16 +103,22 @@ def move(self, unit, direction, endPoint=None):
else: # moving by a unit other than word
res = super(consoleUIATextInfo, self).move(unit, direction, endPoint)
if oldRange and (
self._rangeObj.CompareEndPoints(
UIAHandler.TextPatternRangeEndpoint_Start,
firstVisiRange,
UIAHandler.TextPatternRangeEndpoint_Start
) < 0
or self._rangeObj.CompareEndPoints(
UIAHandler.TextPatternRangeEndpoint_Start,
lastVisiRange,
UIAHandler.TextPatternRangeEndpoint_End
) >= 0
(
self.obj._reviewTopBounded and
self._rangeObj.CompareEndPoints(
UIAHandler.TextPatternRangeEndpoint_Start,
firstVisiRange,
UIAHandler.TextPatternRangeEndpoint_Start
) < 0
)
or (
self.obj._reviewBottomBounded and
self._rangeObj.CompareEndPoints(
UIAHandler.TextPatternRangeEndpoint_Start,
lastVisiRange,
UIAHandler.TextPatternRangeEndpoint_End
) >= 0
)
):
self._rangeObj = oldRange
return 0
Expand Down Expand Up @@ -205,6 +214,9 @@ class winConsoleUIA(Terminal):
_lastCharTime = 0
_queuedChars = []
_TYPING_TIMEOUT = 1
_reviewBoundsSetting = 0
_reviewTopBounded = True
_reviewBottomBounded = True

def _reportNewText(self, line):
# Additional typed character filtering beyond that in LiveText
Expand Down Expand Up @@ -253,6 +265,85 @@ def script_clear_isTyping(self, gesture):
self._isTyping = False
self._queuedChars = []

@script(
gesture="kb:NVDA+o",
description=_("Selects the next review bounds setting"), # Translators: A gesture description.
category=SCRCAT_MISC,
)
def script_next_review_bound(self, gesture):
self._reviewBoundsSetting += 1
self._updateReviewBounds()

@script(
gesture="kb:NVDA+shift+o",
description=_("Selects the previous review bounds setting"), # Translators: A gesture description.
category=SCRCAT_MISC,
)
def script_prev_review_bound(self, gesture):
self._reviewBoundsSetting -= 1
self._updateReviewBounds()

def _updateReviewBounds(self):
self._reviewBoundsSetting %= 4
setting = self._reviewBoundsSetting
if setting == 0:
self._reviewTopBounded = True
self._reviewBottomBounded = True
ui.message(
# Translators: Announced in the Windows Console when review is constrained to onscreen text.
_("Doubly bounded")
)
elif setting == 1:
self._reviewTopBounded = False
self._reviewBottomBounded = True
ui.message(
# Translators: Announced in the Windows Console when review past the end of the onscreen text is constrained, but review before it is not.
_("Bottom bounded")
)
elif setting == 2:
self._reviewTopBounded = False
self._reviewBottomBounded = False
ui.message(
# Translators: Announced in the Windows Console when review is unconstrained (i.e. the entire buffer can be reviewed).
_("Unbounded")
)
elif setting == 3:
self._reviewTopBounded = True
self._reviewBottomBounded = False
ui.message(
# Translators: Announced in the Windows Console when review before the beginning of the onscreen text is constrained, but review after it is not.
_("Top bounded")
)
# Reset the review position if we're now out of bounds.
rp = api.getReviewPosition()
visiRanges = self.UIATextPattern.GetVisibleRanges()
visiLength = visiRanges.length
if visiLength > 0:
firstVisiRange = visiRanges.GetElement(0)
lastVisiRange = visiRanges.GetElement(visiLength - 1)
if (
(
self._reviewTopBounded and
rp._rangeObj.CompareEndPoints(
UIAHandler.TextPatternRangeEndpoint_Start,
firstVisiRange,
UIAHandler.TextPatternRangeEndpoint_Start
) < 0
)
or (
self._reviewBottomBounded and
rp._rangeObj.CompareEndPoints(
UIAHandler.TextPatternRangeEndpoint_Start,
lastVisiRange,
UIAHandler.TextPatternRangeEndpoint_End
) >= 0
)
):
api.setReviewPosition(
self.makeTextInfo(textInfos.POSITION_CARET),
isCaret=True
)

def _getTextLines(self):
# Filter out extraneous empty lines from UIA
ptr = self.UIATextPattern.GetVisibleRanges()
Expand Down
18 changes: 18 additions & 0 deletions user_docs/en/userGuide.t2t
Expand Up @@ -942,6 +942,24 @@ When in the table view of added books:
| Context menu | applications | Opens the context menu for the selected book. |
%kc:endInclude

++ Windows Console ++[windoesConsole]

By default, when UI Automation is enabled for the Windows Console, the review cursor is constrained to the text currently visible on the screen (i.e. once text scrolls off the top or below the bottom of the console, it cannot be reviewed). However, this can be changed on the fly to allow previously visible text to be reviewed. The following review modes are available:

- Top bounded: Review before the beginning of the onscreen text is constrained, but review after it is not.
- Doubly bounded (default): review is constrained to onscreen text.
- Bottom bounded: review past the onscreen text is constrained, but review before it is permitted. This mode allows text that scrolled off the top of the screen to be reviewed.
- Unbounded: No constraints are placed on review, so all text presented by the operating system can be read.


%kc:beginInclude
The following commands are available in the Windows Console when UI Automation is enabled:

|| Name | Key | Description |
| next review bounds setting | NVDA+o | Selects the next review bounds setting for this console window. |
| previous review bounds setting | NVDA+shift+o | Selects the previous review bounds setting for this console window. |
%kc:endInclude

+ Configuring NVDA +[ConfiguringNVDA]
Most configuration can be performed using dialog boxes accessed through the Preferences sub-menu of the NVDA menu.
Many of these settings can be found in the multi-page [NVDA Settings dialog #NVDASettings].
Expand Down