Skip to content

Commit e5f4e50

Browse files
authored
Merge 1de2e9e into 3f89b60
2 parents 3f89b60 + 1de2e9e commit e5f4e50

5 files changed

Lines changed: 167 additions & 4 deletions

File tree

source/config/configSpec.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
focusContextPresentation = option("changedContext", "fill", "scroll", default="changedContext")
8484
interruptSpeechWhileScrolling = featureFlag(optionsEnum="BoolFlag", behaviorOfDefault="enabled")
8585
showSelection = featureFlag(optionsEnum="BoolFlag", behaviorOfDefault="enabled")
86+
routeSystemCaretAlongWithReviewCursor = featureFlag(optionsEnum="BoolFlag", behaviorOfDefault="disabled")
8687
enableHidBrailleSupport = integer(0, 2, default=0) # 0:Use default/recommended value (yes), 1:yes, 2:no
8788
8889
# Braille display driver settings

source/globalCommands.py

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# Burman's Computer and Education Ltd.
99

1010
import itertools
11+
from _ctypes import COMError
1112
from typing import (
1213
List,
1314
Optional,
@@ -3315,6 +3316,45 @@ def script_braille_cycleShowSelection(self, gesture: inputCore.InputGesture) ->
33153316
msg = _("Braille show selection %s") % BoolFlag[nextName].displayString
33163317
ui.message(msg)
33173318

3319+
@script(
3320+
# Translators: Input help mode message for cycle through
3321+
# braille route system caret along with review cursor command.
3322+
description=_("Cycle through the braille route system caret along with review cursor states"),
3323+
category=SCRCAT_BRAILLE
3324+
)
3325+
def script_braille_cycleRouteSystemCaretAlongWithReviewCursor(self, gesture: inputCore.InputGesture) -> None:
3326+
# If braille is not tethered to focus, set next state of
3327+
# braille route system caret along with review cursor.
3328+
# State is reported using ui.message.
3329+
# Unavailable if tether is to focus.
3330+
if TetherTo.FOCUS.value == config.conf["braille"]["tetherTo"]:
3331+
ui.message(
3332+
_(
3333+
# Translators: Gesture is unavailable because braille tether is to focus.
3334+
"Action unavailable. Braille is tethered to focus"
3335+
)
3336+
)
3337+
return
3338+
featureFlag: FeatureFlag = config.conf["braille"]["routeSystemCaretAlongWithReviewCursor"]
3339+
boolFlag: BoolFlag = featureFlag.enumClassType
3340+
values = [x.value for x in boolFlag]
3341+
currentValue = featureFlag.value.value
3342+
nextValueIndex = (currentValue % len(values)) + 1
3343+
nextName: str = boolFlag(nextValueIndex).name
3344+
config.conf["braille"]["routeSystemCaretAlongWithReviewCursor"] = nextName
3345+
featureFlag = config.conf["braille"]["routeSystemCaretAlongWithReviewCursor"]
3346+
if featureFlag.isDefault():
3347+
msg = _(
3348+
# Translators: Used when reporting braille route system caret along with review cursor
3349+
# state (default behavior).
3350+
"Braille route system caret along with review cursor default (%s)"
3351+
) % featureFlag.behaviorOfDefault.displayString
3352+
else:
3353+
# Translators: Reports which route system caret along with review cursor state is used
3354+
# (disabled or enabled).
3355+
msg = _("Braille route system caret along with review cursor %s") % BoolFlag[nextName].displayString
3356+
ui.message(msg)
3357+
33183358
@script(
33193359
# Translators: Input help mode message for report clipboard text command.
33203360
description=_("Reports the text on the Windows clipboard"),
@@ -3483,8 +3523,79 @@ def script_braille_scrollForward(self, gesture):
34833523
description=_("Routes the cursor to or activates the object under this braille cell"),
34843524
category=SCRCAT_BRAILLE
34853525
)
3486-
def script_braille_routeTo(self, gesture):
3487-
braille.handler.routeTo(gesture.routingIndex)
3526+
def script_braille_routeTo(self, gesture: inputCore.InputGesture) -> None:
3527+
# Routes cursor to or activates the object under this braille cell.
3528+
# Try to ensure that braille message can be dismissed.
3529+
if braille.handler.buffer is braille.handler.messageBuffer:
3530+
braille.handler.routeTo(gesture.routingIndex)
3531+
return
3532+
# Lookup error occurs when pressing routing button in "unknown" object.
3533+
try:
3534+
braille.handler.routeTo(gesture.routingIndex)
3535+
except LookupError:
3536+
log.debug(f"Routing failed.", exc_info=True)
3537+
return
3538+
# To proceed braille should be tethered to review cursor which means
3539+
# that tether is automatic (and review cursor is shown in braille)
3540+
# or tether is to review cursor.
3541+
# "Route system caret along with review cursor" should be also enabled
3542+
# in braille settings.
3543+
if (
3544+
braille.handler.getTether() != TetherTo.REVIEW.value
3545+
or not config.conf["braille"]["routeSystemCaretAlongWithReviewCursor"]
3546+
):
3547+
return
3548+
navigatorObject: NVDAObject = api.getNavigatorObject()
3549+
if not isinstance(navigatorObject, NVDAObject):
3550+
ui.message(
3551+
_(
3552+
# Translators: There is no focusable object e.g. cannot use
3553+
# tab and shift tab to move to controls.
3554+
"No focus"
3555+
)
3556+
)
3557+
return
3558+
# Try to set focus to current navigator object
3559+
if navigatorObject != api.getFocusObject():
3560+
# This script is available on the lock screen via getSafeScripts, as such
3561+
# ensure the navigatorObject does not contain secure information
3562+
# before setting focus to this object
3563+
if objectBelowLockScreenAndWindowsIsLocked(navigatorObject):
3564+
ui.message(gui.blockAction.Context.WINDOWS_LOCKED.translatedMessage)
3565+
return
3566+
# When trying to move focus in Word 2019 system menu, setFocus
3567+
# caused _ctypes.COMError.
3568+
try:
3569+
# It is not always possible to move caret, but setting focus can
3570+
# provide more possibilities such as activating controls with routing
3571+
# buttons.
3572+
navigatorObject.setFocus()
3573+
except COMError:
3574+
log.debug("Set focus failed.", exc_info=True)
3575+
return
3576+
# If not in browse mode, try to reduce "no caret" messages.
3577+
if not api.isObjectInActiveTreeInterceptor(navigatorObject):
3578+
if not navigatorObject._hasNavigableText:
3579+
log.debug(f"Navigator object {navigatorObject} is not navigable")
3580+
return
3581+
review: textInfos.TextInfo = api.getReviewPosition()
3582+
# This script is available on the lock screen via getSafeScripts, as such
3583+
# ensure the review object does not contain secure information
3584+
# before displaying this object in braille line
3585+
if objectBelowLockScreenAndWindowsIsLocked(review.obj):
3586+
ui.reviewMessage(gui.blockAction.Context.WINDOWS_LOCKED.translatedMessage)
3587+
return
3588+
try:
3589+
review.updateCaret()
3590+
except NotImplementedError:
3591+
log.debug("Unable to move caret", exc_info=True)
3592+
# Translators: Reported when trying to move caret to the position
3593+
# of the review cursor but there is no caret.
3594+
ui.message(
3595+
_(
3596+
"No caret"
3597+
)
3598+
)
34883599

34893600
@script(
34903601
# Translators: Input help mode message for Braille report formatting command.

source/gui/settingsDialogs.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3707,6 +3707,7 @@ def makeSettings(self, settingsSizer):
37073707
tetherChoices = [x[1] for x in braille.handler.tetherValues]
37083708
self.tetherList = sHelper.addLabeledControl(tetherListText, wx.Choice, choices=tetherChoices)
37093709
self.bindHelpEvent("BrailleTether", self.tetherList)
3710+
self.tetherList.Bind(wx.EVT_CHOICE, self.onTetherToChange)
37103711
tetherChoice = config.conf["braille"]["tetherTo"]
37113712
selection = [x.value for x in TetherTo].index(tetherChoice)
37123713
self.tetherList.SetSelection(selection)
@@ -3758,6 +3759,25 @@ def makeSettings(self, settingsSizer):
37583759
)
37593760
self.bindHelpEvent("BrailleSettingsShowSelection", self.brailleShowSelectionCombo)
37603761

3762+
self.brailleRouteSystemCaretAlongWithReviewCursorCombo: nvdaControls.FeatureFlagCombo = \
3763+
sHelper.addLabeledControl(
3764+
labelText=_(
3765+
# Translators: This is a label for a combo-box in the Braille settings panel.
3766+
"Ro&ute system caret along with review cursor"
3767+
),
3768+
wxCtrlClass=nvdaControls.FeatureFlagCombo,
3769+
keyPath=["braille", "routeSystemCaretAlongWithReviewCursor"],
3770+
conf=config.conf,
3771+
)
3772+
self.bindHelpEvent(
3773+
"BrailleSettingsRouteSystemCaretAlongWithReviewCursor",
3774+
self.brailleRouteSystemCaretAlongWithReviewCursorCombo
3775+
)
3776+
tetherChoice = [x.value for x in TetherTo][self.tetherList.GetSelection()]
3777+
# Setting has no effect when braille is tethered to focus.
3778+
if tetherChoice == TetherTo.FOCUS.value:
3779+
self.brailleRouteSystemCaretAlongWithReviewCursorCombo.Disable()
3780+
37613781
if gui._isDebug():
37623782
log.debug("Finished making settings, now at %.2f seconds from start"%(time.time() - startTime))
37633783

@@ -3783,6 +3803,7 @@ def onSave(self):
37833803
config.conf["braille"]["focusContextPresentation"] = self.focusContextPresentationValues[self.focusContextPresentationList.GetSelection()]
37843804
self.brailleInterruptSpeechCombo.saveCurrentValueToConf()
37853805
self.brailleShowSelectionCombo.saveCurrentValueToConf()
3806+
self.brailleRouteSystemCaretAlongWithReviewCursorCombo.saveCurrentValueToConf()
37863807

37873808
def onShowCursorChange(self, evt):
37883809
self.cursorBlinkCheckBox.Enable(evt.IsChecked())
@@ -3796,6 +3817,11 @@ def onBlinkCursorChange(self, evt):
37963817
def onShowMessagesChange(self, evt):
37973818
self.messageTimeoutEdit.Enable(evt.GetSelection() == 1)
37983819

3820+
def onTetherToChange(self, evt: wx.CommandEvent) -> None:
3821+
"""Shows or hides "Route system caret along with review cursor" braille setting."""
3822+
tetherChoice = [x.value for x in TetherTo][evt.GetSelection()]
3823+
self.brailleRouteSystemCaretAlongWithReviewCursorCombo.Enable(tetherChoice != TetherTo.FOCUS.value)
3824+
37993825
def showStartErrorForProviders(
38003826
parent: wx.Window,
38013827
providers: List[vision.providerInfo.ProviderInfo],

source/utils/security.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# A part of NonVisual Desktop Access (NVDA)
2-
# Copyright (C) 2022-2023 NV Access Limited, Cyrille Bougot
2+
# Copyright (C) 2022-2023 NV Access Limited, Cyrille Bougot,
3+
# Burman's Computer and Education Ltd.
34
# This file may be used under the terms of the GNU General Public License, version 2 or later.
45
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html
56

@@ -99,14 +100,15 @@ def getSafeScripts() -> Set["scriptHandler._ScriptFunctionT"]:
99100
# on the lock screen using braille.
100101
commands.script_braille_scrollBack,
101102
commands.script_braille_scrollForward,
102-
commands.script_braille_routeTo,
103103
commands.script_braille_previousLine,
104104
commands.script_braille_nextLine,
105105

106106
# Object navigation is required to ensure controls
107107
# on the lock screen are accessible.
108108
# Preventing object navigation outside the lock screen
109109
# is handled in `api.setNavigatorObject` and by applying `LockScreenObject`.
110+
# Routing is here because it may change focus.
111+
commands.script_braille_routeTo,
110112
commands.script_navigatorObject_current,
111113
commands.script_navigatorObject_currentDimensions,
112114
commands.script_navigatorObject_toFocus,

user_docs/en/userGuide.t2t

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,29 @@ Disabling this option may improve readability.
16871687

16881688
To toggle show selection from anywhere, please assign a custom gesture using the [Input Gestures dialog #InputGestures].
16891689

1690+
==== Route system caret along with review cursor ====[BrailleSettingsRouteSystemCaretAlongWithReviewCursor]
1691+
: Default
1692+
Disabled
1693+
: Options
1694+
Default (Disabled), Enabled, Disabled
1695+
:
1696+
1697+
This setting determines if system focus/caret should be also tried to be moved
1698+
with a routing button press when [braille tether #BrailleTether] is automatic
1699+
and braille is temporarily tethered to review, or tether is to review cursor.
1700+
Option is disabled by default.
1701+
1702+
When this option is enabled and braille is tethered to review,
1703+
it is often but not always possible to move both review cursor
1704+
and system focus/caret to the desired position by pressing a routing button.
1705+
It may be especially handy to review text without affecting system caret in edit areas, and move system caret only when needed.
1706+
1707+
Please note: The option is hidden, and it has no effect unless
1708+
the braille is tethered automatically or to review cursor.
1709+
1710+
To toggle route system caret along with review cursor from anywhere,
1711+
please assign a custom gesture using the [Input Gestures dialog #InputGestures].
1712+
16901713
+++ Select Braille Display (NVDA+control+a) +++[SelectBrailleDisplay]
16911714
The Select Braille Display dialog, which can be opened by activating the Change... button in the Braille category of the NVDA settings dialog, allows you to select which Braille display NVDA should use for braille output.
16921715
Once you have selected your braille display of choice, you can press Ok and NVDA will load the selected display.

0 commit comments

Comments
 (0)