Repository navigation
Speak typed characters in Windows consoles in the correct language (second try) - #10554
Merged
Merged
Conversation
… saving them for exposia as windowThreadID in WinConsole NVDAObjects. Necessary for speak typed characters. Addresses #10113.
|
PR introduces Flake8 errors 😲 See test results for Failed build of commit 712c583a82 |
codeofdusk
approved these changes
Nov 28, 2019
codeofdusk
left a comment
Contributor
There was a problem hiding this comment.
Looks fine to me, assuming that nothing in the legacy console support depends on the previous threadID behavior.
LeonarddeR
approved these changes
Nov 28, 2019
LeonarddeR
left a comment
Collaborator
There was a problem hiding this comment.
Only some style comments
| # But NVDA really requires to know the actual thread the window was created in, | ||
| # I.e. inside conhost, | ||
| # In order to handle speaking of typed characters etc. | ||
| # winEventCallback adds these when ever it sees an event for ConsoleWindowClass windows, |
Collaborator
There was a problem hiding this comment.
Should this be whenever?
Suggested change
| # winEventCallback adds these when ever it sees an event for ConsoleWindowClass windows, | |
| # winEventCallback adds these whenever it sees an event for ConsoleWindowClass windows, |
| # In order to handle speaking of typed characters etc. | ||
| # winEventCallback adds these when ever it sees an event for ConsoleWindowClass windows, | ||
| # As winEvents always contain the true thread ID. | ||
| consoleWindowsToThreadIDs = {} |
Collaborator
There was a problem hiding this comment.
Typing
Suggested change
| consoleWindowsToThreadIDs = {} | |
| consoleWindowsToThreadIDs: Dict[int, int] = {} |
| #: the caret in consoles can take a while to move on Windows 10 1903 and later. | ||
| _caretMovementTimeoutMultiplier = 1.5 | ||
|
|
||
| def _get_windowThreadID(self): |
Collaborator
There was a problem hiding this comment.
Not that I think this should happen now, but I wonder whether we want a base class for console windows that the legacy and UIA impls inherit from.
This was referenced Aug 12, 2026
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.
Replaces pr #10551
Link to issue number:
Fixes #10113
Summary of the issue:
With the work to support Windows consoles via UIA, NVDA moved to speaking typed characters in consoles by detecting keyboard input and then using ToUnicodeEx to convert the keyboard input into a character for speaking. We had already been taking this approach for Microsoft Edge and other places in Windows 10 where we could not inject in-process.
ToUnicodeEx requires a keyboard layout to use the correct language. Therefore, we would call GetKeyboardLayout, giving it the thread ID of the focused window.
However, it seems that Windows console windows report the wrong thread ID, and therefore, GetKeyboardLayout fails, returning 0 instead of a valid keyboard layout.
Passing this 0 to ToUnicodeEx, it would generate characters in the user's system language (I think). At least, on my system it was always english US no matter what input language I was currently using.
Description of how this pull request fixes the issue:
Override the windowThreadID property on both UIA and legacy WinConsole NVDAObjects, to reflect the true thread ID of the window. This thread ID is found in a new cache of console windows to thread IDs in IAccessibleHandler, filled in by received winEvents for ConsoleWindowClass windows.
Received winEvents always contain an ID of the true thread that NotifyWinEvent was called in. In the case of ConsoleWindowClass winEvents, this is from inside conhost.
this thread happens to be the true input (focus thread) for consoles, and therefore GetKeyboardLayout returns the correct input language for the console, when given this threadID.
We can garantee that there will at least either be a focus winEvent, or a locationChange winEvent (for the caret) for consoles, when moving to a console and or starting NVDA within a console. This is enough to make sure that we have a threadID for that console window when we need it.
Testing performed:
Known issues with pull request:
It is possible that the very first typed character when starting NVDA from within a console will be announced in the wrong language, as the caret has not yet moved once. But this is rather rare.
Change log entry:
None