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

No longer sentence nav in VS Code #17652

Merged
merged 10 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
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
9 changes: 6 additions & 3 deletions source/NVDAObjects/window/winword.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2006-2025 NV Access Limited, Manish Agrawal, Derek Riemer, Babbage B.V., Cyrille Bougot
# Copyright (C) 2006-2025 NV Access Limited, Manish Agrawal, Derek Riemer, Babbage B.V., Cyrille Bougot,
# Leonard de Ruijter
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

Expand Down Expand Up @@ -40,7 +41,7 @@
import treeInterceptorHandler
import browseMode
from . import Window
from ..behaviors import EditableTextWithoutAutoSelectDetection
from ..behaviors import EditableTextBase, EditableTextWithoutAutoSelectDetection
from . import _msOfficeChart
from ._msOffice import MsoHyperlink
import locationHelper
Expand Down Expand Up @@ -1573,7 +1574,9 @@ def _iterTextStyle(
}


class WordDocument(Window):
class WordDocument(Window, EditableTextBase):
_supportsSentenceNavigation = True

def winwordColorToNVDAColor(self, val):
if val >= 0:
# normal RGB value
Expand Down
5 changes: 4 additions & 1 deletion source/appModules/code.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2020-2024 NV Access Limited, Leonard de Ruijter, Cary-Rowen
# Copyright (C) 2020-2025 NV Access Limited, Leonard de Ruijter, Cary-Rowen
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

"""App module for Visual Studio Code."""

import appModuleHandler
import controlTypes
from NVDAObjects.behaviors import EditableTextBase
from NVDAObjects.IAccessible.chromium import Document
from NVDAObjects import NVDAObject, NVDAObjectTextInfo

Expand All @@ -26,6 +27,8 @@ def chooseNVDAObjectOverlayClasses(self, obj, clsList):
clsList.insert(0, VSCodeDocument)

def event_NVDAObject_init(self, obj: NVDAObject):
if isinstance(obj, EditableTextBase):
obj._supportsSentenceNavigation = False
# TODO: This is a specific fix for Visual Studio Code.
# Once the underlying issue is resolved, this workaround can be removed.
# See issue #15159 for more details.
Expand Down
68 changes: 47 additions & 21 deletions source/editableText.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# A part of NonVisual Desktop Access (NVDA)
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.
# Copyright (C) 2006-2022 NV Access Limited, Davy Kager, Julien Cochuyt, Rob Meredith
# Copyright (C) 2006-2025 NV Access Limited, Davy Kager, Julien Cochuyt, Rob Meredith, Leonard de Ruijter

"""Common support for editable text.
@note: If you want editable text functionality for an NVDAObject,
you should use the EditableText classes in L{NVDAObjects.behaviors}.
"""

import time
from numbers import Real
from speech import sayAll
import api
import review
Expand Down Expand Up @@ -36,25 +37,35 @@ class EditableText(TextContainerObject, ScriptableObject):
* When the object gains focus, L{initAutoSelectDetection} must be called.
* When the object notifies of a possible selection change, L{detectPossibleSelectionChange} must be called.
* Optionally, if the object notifies of changes to its content, L{hasContentChangedSinceLastSelection} should be set to C{True}.
@ivar hasContentChangedSinceLastSelection: Whether the content has changed since the last selection occurred.
@type hasContentChangedSinceLastSelection: bool
"""

#: Whether to fire caretMovementFailed events when the caret doesn't move in response to a caret movement key.
shouldFireCaretMovementFailedEvents = False
hasContentChangedSinceLastSelection: bool
"""Whether the content has changed since the last selection occurred."""

#: Whether or not to announce text found before the caret on a new line (e.g. auto numbering)
announceNewLineText = True
#: When announcing new line text: should the entire line be announced, or just text after the caret?
announceEntireNewLine = False
shouldFireCaretMovementFailedEvents: bool = False
LeonarddeR marked this conversation as resolved.
Show resolved Hide resolved
"""Whether to fire caretMovementFailed events when the caret doesn't move in response to a caret movement key."""

#: The minimum amount of time that should elapse before checking if the word under the caret has changed
_hasCaretMoved_minWordTimeoutSec = 0.03
announceNewLineText: bool = True
"""Whether or not to announce text found before the caret on a new line (e.g. auto numbering)"""

#: The maximum amount of time that may elapse before we no longer rely on caret events to detect movement.
_useEvents_maxTimeoutSec = 0.06
announceEntireNewLine: bool = False
"""When announcing new line text: should the entire line be announced, or just text after the caret?"""

_caretMovementTimeoutMultiplier = 1
_hasCaretMoved_minWordTimeoutSec: float = 0.03
"""The minimum amount of time that should elapse before checking if the word under the caret has changed"""

_useEvents_maxTimeoutSec: float = 0.06
"""The maximum amount of time that may elapse before we no longer rely on caret events to detect movement."""

_caretMovementTimeoutMultiplier: Real = 1
"""A multiplier to apply to the caret movement timeout to increase or decrease it in a subclass."""

_supportsSentenceNavigation: bool | None = None
"""Whether the editable text supports sentence navigation.
When `None` (default), the state is undetermined, e.g. sentence navigation will be attempted, when it fails, the gesture will be send to the OS.
When `True`, sentence navigation is explicitly supported and will be performed. When it fails, the gesture is discarded.
When `False`, sentence navigation is explicitly not supported and the gesture is sent to the OS.
"""

def _hasCaretMoved(self, bookmark, retryInterval=0.01, timeout=None, origWord=None):
"""
Expand Down Expand Up @@ -226,17 +237,32 @@ def script_caret_newLine(self, gesture):
suppressBlanks=True,
)

def _caretMoveBySentenceHelper(self, gesture, direction):
def _caretMoveBySentenceHelper(self, gesture: InputGesture, direction: int) -> None:
if isScriptWaiting():
if not self._supportsSentenceNavigation: # either None or False
gesture.send()
return
try:
info = self.makeTextInfo(textInfos.POSITION_CARET)
info.move(textInfos.UNIT_SENTENCE, direction)
info.updateCaret()
self._caretScriptPostMovedHelper(textInfos.UNIT_SENTENCE, gesture, info)
except: # noqa: E722
gesture.send()
return
caretMoved = False
newInfo = None
if not self._supportsSentenceNavigation:
bookmark = info.bookmark
gesture.send()
caretMoved, newInfo = self._hasCaretMoved(bookmark)
if not caretMoved and self._supportsSentenceNavigation is not False:
info.move(textInfos.UNIT_SENTENCE, direction)
info.updateCaret()
else:
info = newInfo
self._caretScriptPostMovedHelper(
textInfos.UNIT_SENTENCE if not caretMoved else textInfos.UNIT_LINE,
gesture,
info,
)
except Exception:
if self._supportsSentenceNavigation is True:
log.exception("Error in _caretMoveBySentenceHelper")

def script_caret_moveByLine(self, gesture):
self._caretMovementScriptHelper(gesture, textInfos.UNIT_LINE)
Expand Down
2 changes: 2 additions & 0 deletions user_docs/en/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ As a consequence, announcement of first line indent is now supported for LibreOf
* NVDA can now be configured to speak the current line or paragraph when navigating with braille navigation keys. (#17053, @nvdaes)
* In Word, the selection update is now reported when using Word commands to extend or reduce the selection (`f8` or `shift+f8`). (#3293, @CyrilleB79)
* In Microsoft Word 16.0.18226 and higher or when using Word object model, NVDA will now report if a heading is collapsed in both speech and braille. (#17499)
* NVDA is now able to report caret changes when pressing `alt+upArrow` or `alt+downArrow` gestures, for example in Visual Studio. (#17652, @LeonarddeR)

### Changes

Expand Down Expand Up @@ -96,6 +97,7 @@ In any document, if the cursor is on the last line, it will be moved to the end
* Custom braille tables in the developer scratchpad are now properly ignored when running with add-ons disabled. (#17565, @LeonarddeR)
* Fix issue with certain section elements not being recognized as editable controls in Visual Studio Code. (#17573, @Cary-rowen)
* Fixed an issue where continuous reading (say all) stopped at the end of the first sentence when using some SAPI5 synthesizers. (#16691, @gexgd0419)
* In Visual Studio Code, NVDA no longer hijacks the `alt+upArrow` and `alt+downArrow` gestures for sentence navigation. (#17082, @LeonarddeR)

### Changes for Developers

Expand Down