Skip to content

Commit a151f2a

Browse files
authored
Merge e23d478 into 30e00a9
2 parents 30e00a9 + e23d478 commit a151f2a

5 files changed

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

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

source/gui/settingsDialogs.py

Lines changed: 25 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,24 @@ def makeSettings(self, settingsSizer):
37583759
)
37593760
self.bindHelpEvent("BrailleSettingsShowSelection", self.brailleShowSelectionCombo)
37603761

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

@@ -3783,6 +3802,7 @@ def onSave(self):
37833802
config.conf["braille"]["focusContextPresentation"] = self.focusContextPresentationValues[self.focusContextPresentationList.GetSelection()]
37843803
self.brailleInterruptSpeechCombo.saveCurrentValueToConf()
37853804
self.brailleShowSelectionCombo.saveCurrentValueToConf()
3805+
self.brailleRouteReviewCursorAndSystemCaretCombo.saveCurrentValueToConf()
37863806

37873807
def onShowCursorChange(self, evt):
37883808
self.cursorBlinkCheckBox.Enable(evt.IsChecked())
@@ -3796,6 +3816,11 @@ def onBlinkCursorChange(self, evt):
37963816
def onShowMessagesChange(self, evt):
37973817
self.messageTimeoutEdit.Enable(evt.GetSelection() == 1)
37983818

3819+
def onTetherToChange(self, evt: wx.CommandEvent) -> None:
3820+
"""Showss or hides "Route review cursor and system caret" braille setting."""
3821+
tetherChoice = [x.value for x in TetherTo][evt.GetSelection()]
3822+
self.brailleRouteReviewCursorAndSystemCaretCombo.Enable(tetherChoice != TetherTo.FOCUS.value)
3823+
37993824
def showStartErrorForProviders(
38003825
parent: wx.Window,
38013826
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 review cursor and system caret ====[BrailleSettingsRouteReviewCursorAndSystemCaret]
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 review cursor and system caret 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)