Skip to content

Commit 712c583

Browse files
Merge 8cbc512 into 7f2f03c
2 parents 7f2f03c + 8cbc512 commit 712c583

3 files changed

Lines changed: 35 additions & 0 deletions

File tree

‎source/IAccessibleHandler.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,10 @@ def winEventCallback(handle,eventID,window,objectID,childID,threadID,timestamp):
575575
window=tempWindow
576576

577577
windowClassName=winUser.getClassName(window)
578+
if windowClassName == "ConsoleWindowClass":
579+
# #10113: we need to use winEvents to track the real thread for console windows.
580+
consoleWindowsToThreadIDs[window] = threadID
581+
578582
# Modern IME candidate list windows fire menu events which confuse us
579583
# and can't be used properly in conjunction with input composition support.
580584
if windowClassName=="Microsoft.IME.UIManager.CandidateWindow.Host" and eventID in MENU_EVENTIDS:
@@ -1102,3 +1106,12 @@ def isMarshalledIAccessible(IAccessibleObject):
11021106
windll.kernel32.GetModuleHandleExW(6,addr,byref(handle))
11031107
windll.kernel32.GetModuleFileNameW(handle,buf,1024)
11041108
return not buf.value.lower().endswith('oleacc.dll')
1109+
1110+
#: Maps from console windows (ConsoleWindowClass) to thread IDs
1111+
# Windows hacks GetWindowThreadProcessId to return the input thread of the first attached process in a console,
1112+
# But NVDA really requires to know the actual thread the window was created in,
1113+
# I.e. inside conhost,
1114+
# In order to handle speaking of typed characters etc.
1115+
# winEventCallback adds these when ever it sees an event for ConsoleWindowClass windows,
1116+
# As winEvents always contain the true thread ID.
1117+
consoleWindowsToThreadIDs = {}

‎source/NVDAObjects/UIA/winConsoleUIA.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,17 @@ class WinConsoleUIA(KeyboardHandlerBasedTypedCharSupport):
254254
#: the caret in consoles can take a while to move on Windows 10 1903 and later.
255255
_caretMovementTimeoutMultiplier = 1.5
256256

257+
def _get_windowThreadID(self):
258+
# #10113: Windows forces the thread of console windows to match the thread of the first attached process.
259+
# However, To correctly handle speaking of typed characters,
260+
# NVDA really requires the real thread the window was created in,
261+
# I.e. a thread inside conhost.
262+
from IAccessibleHandler import consoleWindowsToThreadIDs
263+
threadID = consoleWindowsToThreadIDs.get(self.windowHandle,0)
264+
if not threadID:
265+
threadID = super().windowThreadID
266+
return threadID
267+
257268
def _get_TextInfo(self):
258269
"""Overriding _get_TextInfo and thus the TextInfo property
259270
on NVDAObjects.UIA.UIA

‎source/NVDAObjects/window/winConsole.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ def initOverlayClass(self):
2626
if isinstance(self, KeyboardHandlerBasedTypedCharSupport):
2727
self._supportsTextChange = False
2828

29+
def _get_windowThreadID(self):
30+
# #10113: Windows forces the thread of console windows to match the thread of the first attached process.
31+
# However, To correctly handle speaking of typed characters,
32+
# NVDA really requires the real thread the window was created in,
33+
# I.e. a thread inside conhost.
34+
from IAccessibleHandler import consoleWindowsToThreadIDs
35+
threadID = consoleWindowsToThreadIDs.get(self.windowHandle,0)
36+
if not threadID:
37+
threadID = super().windowThreadID
38+
return threadID
39+
2940
def _get_TextInfo(self):
3041
consoleObject=winConsoleHandler.consoleObject
3142
if consoleObject and self.windowHandle == consoleObject.windowHandle:

0 commit comments

Comments
 (0)