fix: handle COMError in UIA selectionContainer to prevent silent focus#20255
Merged
seanbudd merged 2 commits intoJun 1, 2026
Merged
Conversation
When a UIA SelectionItemPattern provider errors on get_CurrentSelectionContainer, NVDA's _get_selectionContainer raised an uncaught COMError. The exception propagated up through reportFocus -> speakObject -> getObjectPropertiesSpeech (triggered by the SELECTABLE|FOCUSABLE|SELECTED branch in speech.py), aborting speech for the entire focus event. Reproduced in Telegram Desktop (Qt 5.15.19 with UIA backend) where QWindowsUiaSelectionItemProvider::get_SelectionContainer returns UIA_E_ELEMENTNOTAVAILABLE if the QAccessibleInterface has no actionInterface. Catch COMError on the property access and treat it as no selection container, matching the defensive pattern already used by _get_UIASelectionPattern2 three lines above.
seanbudd
approved these changes
Jun 1, 2026
seanbudd
left a comment
Member
There was a problem hiding this comment.
Thanks @rezabakhshilaktasaraei
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to issue number:
No GitHub issue filed — happy to open one if preferred. The bug is diagnosable from a UIA debug log and the fix is a defensive try/except matching an existing pattern in the same file three lines above.
Summary of the issue:
When NVDA focuses a UIA list item whose provider exposes the
SelectionItempattern but errors when asked for theSelectionContainer,NVDAObjects.UIA.UIA._get_selectionContainerraises an uncaughtCOMError. The exception propagates up throughreportFocus→speakObject→getObjectPropertiesSpeech, aborting speech for the entire focus event — the user hears nothing on focus.The trigger is the
SELECTABLE | FOCUSABLE | SELECTEDbranch inspeech/speech.py:801-818(the code that suppresses redundant "selected" announcements when only one item is selected). That branch queriesobj.selectionContainer, which fails.Reproduced in Telegram Desktop built against Qt 5.15.19 with the UIA backend (
qwindowsuiaaccessibility). The chat list (Dialogs::InnerWidget) exposesListItem-role virtual children with a single selected row. UIA debug log of the crash:Qt's
QWindowsUiaSelectionItemProvider::get_SelectionContainerrequiresactionInterface()to be non-null even though it never uses the action interface (seeqwindowsuiaselectionitemprovider.cpp:183-185). When the accessible interface has no action interface — as is the case for Telegram Desktop's chat row items, which only expose name/role/state/rect — Qt returnsUIA_E_ELEMENTNOTAVAILABLE(0x80040201), surfaced as aCOMError. This is arguably an upstream Qt bug too, but Qt 5.15 LTS is closed for community fixes, and any UIA provider that errors on this property has the same effect on NVDA today.The bug is invisible until a list item with
SELECTEDstate is encountered. Withstate.selectednot set, the speech.py guard is skipped,selectionContaineris never fetched, and the same focus path completes normally — which is why the symptom looks like "NVDA only goes silent on selected items".Description of user facing changes:
Focus is no longer silent on list items in Qt-based UIA applications (such as Telegram Desktop) when the item exposes
SelectionItemPatternbut its provider errors onSelectionContainer. NVDA treats the error the same as a NULL selection container — focus speech proceeds normally.Description of developer facing changes:
NVDAObjects.UIA.UIA._get_selectionContainernow catchesCOMErrorfromIUIAutomationSelectionItemPattern::CurrentSelectionContainerand returnsNone. This matches the defensive pattern already used by_get_UIASelectionPattern2three lines above.Description of development approach:
Diagnosed from a UIA debug log captured in Telegram Desktop (see traceback above). The log shows
gainFocuscorrectly queued for the new list item, thenreportFocusfailing insidegetObjectPropertiesSpeechat thep.currentSelectionContainerCOM call. Wrapping that single property access intry/except COMError(and returningNoneon failure) fixes the crash. The rest of the method already handles the NULL case via the existingif not e: return Nonebranch, so no other changes are needed.Testing strategy:
Manual reproduction in Telegram Desktop with NVDA running from source:
A unit test would mock
IUIAutomationSelectionItemPatternso thatCurrentSelectionContainerraisesCOMErrorand assert_get_selectionContainerreturnsNone. Happy to add one if requested — it was not added in this PR because the bulk of_get_selectionContaineris bare COM access without much else to test in isolation.Known issues with pull request:
None.
Code Review Checklist: