Skip to content
Open
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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ dependencies = [
"fuzzysearch==0.8.1",
# Building user documentation and the l10nUtil
"Markdown==3.10",
"lxml==6.0.2",
"lxml==6.1.0",
"mdx_truly_sane_lists==1.3",
"markdown-link-attr-modifier==0.2.1",
"mdx-gh-links==0.4",
Expand Down
9 changes: 6 additions & 3 deletions source/browseMode.py
Original file line number Diff line number Diff line change
Expand Up @@ -2225,12 +2225,15 @@ def event_gainFocus(self, obj, nextHandler):
# we need to call it manually here.
vision.handler.handleGainFocus(obj)
else:
# Although we are going to speak the object rather than textInfo content, we still need to silently speak the textInfo content so that the textInfo speech cache is updated correctly.
self._replayFocusEnteredEvents()
nextHandler()
# Although we spoke the object rather than textInfo content, we still need to silently speak the textInfo content so that the textInfo speech cache is updated correctly.
# Not doing this would cause later browseMode speaking to either not speak controlFields it had entered, or speak controlField exits after having already exited.
# See #7435 for a discussion on this.
# #17750: It's important that we do this *after* speaking the object.
# Otherwise, the cached info would prevent NVDA from detecting things like
# row and column changes.
speech.speakTextInfo(focusInfo, reason=OutputReason.ONLYCACHE)
self._replayFocusEnteredEvents()
nextHandler()
focusInfo.collapse()
if self._focusEventMustUpdateCaretPosition:
self._set_selection(focusInfo, reason=OutputReason.FOCUS)
Expand Down
2 changes: 1 addition & 1 deletion source/buildVersion.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def formatVersionForGUI(year, major, minor):
# Version information for NVDA
name = "NVDA"
version_year = 2026
version_major = 2
version_major = 3
version_minor = 0
version_build = 0 # Should not be set manually. Set in 'sconscript'.
version = _formatDevVersionString()
Expand Down
13 changes: 10 additions & 3 deletions source/virtualBuffers/gecko_ia2.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,15 @@ def _normalizeControlField(self, attrs): # noqa: C901
attrs["detailsRoles"] = set(self._normalizeDetailsRole(detailsRoles))
if config.conf["debugLog"]["annotations"]:
log.debug(f"detailsRoles: {attrs['detailsRoles']}")
return super()._normalizeControlField(attrs)
attrs = super()._normalizeControlField(attrs)
# #17750: The table-id attribute from the buffer is just a unique id.
# However, the IAccessible NVDAObject specifies the tableID as
# (windowHandle, uniqueId). These need to be compatible for speech cache
# comparison lest we break row/column change detection.
tableID = attrs.get("table-id")
if tableID:
attrs["table-id"] = (int(attrs["controlIdentifier_docHandle"]), tableID)
return attrs

def _normalizeDetailsRole(self, detailsRoles: str) -> Iterable[Optional[controlTypes.Role]]:
"""
Expand Down Expand Up @@ -579,8 +587,7 @@ def event_scrollingStart(self, obj, nextHandler):
event_scrollingStart.ignoreIsReady = True

def _getTableCellAt(self, tableID, startPos, destRow, destCol):
docHandle = self.rootDocHandle
table = self.getNVDAObjectFromIdentifier(docHandle, tableID)
table = self.getNVDAObjectFromIdentifier(*tableID)
try:
try:
cell = table.IAccessibleTable2Object.cellAt(destRow - 1, destCol - 1).QueryInterface(
Expand Down
24 changes: 21 additions & 3 deletions user_docs/en/changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# What's New in NVDA

## 2026.3

### Important notes

### New Features

### Changes

### Bug Fixes

* When moving to an ARIA grid cell in focus mode in web browsers, NVDA no longer reports both the row and column headers even if only the row or only the column changed. (#17750, @jcsteh)

### Changes for Developers

Please refer to [the developer guide](https://download.nvaccess.org/documentation/developerGuide.html#API) for information on NVDA's API deprecation and removal process.

#### Deprecations

<!-- Beyond this point, Markdown should not be automatically linted, as we don't modify old change log sections and lint rules may change over time. -->
<!-- markdownlint-disable -->

## 2026.2

### Important notes
Expand Down Expand Up @@ -143,9 +164,6 @@ Please responsibly disclose security issues following NVDA's [security policy](h

* The `winBindings.cfgmgr32` module is now included in NVDA binary builds. (#20089, @Cary-rowen)

<!-- Beyond this point, Markdown should not be linted, as we don't modify old change log sections. -->
<!-- markdownlint-disable -->

## 2026.1

This release includes support for reading math content with MathCAT, which is now built-in to NVDA.
Expand Down
18 changes: 9 additions & 9 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading