From a9ea60799f0bf547b99e06d3fb6f9ca13295b21e Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Thu, 30 Oct 2025 17:07:02 -0500 Subject: [PATCH] When translating clipboard to numpad events, use the *input* CP (#19511) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I looked as far back as I was able to find, and we've used the OutputCP since at least Windows NT 3.51. I think it has _never_ been correct. At issue today is the GB18030-2022 test string, which contains the following problematic characters: * `ˊ` `U+02CA` Modifier Letter Acute Accent * `ˋ` `U+02CB` Modifier Letter Grave Accent * `˙` `U+02D9` Dot Above * `–` `U+2013` En Dash They cannot be pasted into PowerShell 5.1 (PSReadline). It turns out that when we try to synthesize an input event (Alt down, numpad press, Alt up **with wchar**) we are using their output codepage 65001. These characters, of course, do not have a single byte encoding in that codepage... and so we do not generate the numpad portion of the synthesized event, only the alt down and up parts! This is totally fine. **However**, there is also a .NET Framework bug (which was only fixed after they released .NET Core, and rebranded, and the community stepped in, ...) finally fixed in .NET 9 which used to result in some Alt KeyUp events being dropped from the queue entirely. https://github.com/dotnet/runtime/issues/102425 Using the input codepage ensures the right events get synthesized. It works around the .NET bug. Technically, padding in those numpad input events is _also more correct_. It also scares me, because it has been this way since NT 3.51 or earlier. --- src/interactivity/win32/Clipboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interactivity/win32/Clipboard.cpp b/src/interactivity/win32/Clipboard.cpp index 02db284c33..92470d88b9 100644 --- a/src/interactivity/win32/Clipboard.cpp +++ b/src/interactivity/win32/Clipboard.cpp @@ -310,7 +310,7 @@ InputEventQueue Clipboard::TextToKeyEvents(_In_reads_(cchData) const wchar_t* co currentChar = UNICODE_CARRIAGERETURN; } - const auto codepage = ServiceLocator::LocateGlobals().getConsoleInformation().OutputCP; + const auto codepage = ServiceLocator::LocateGlobals().getConsoleInformation().CP; CharToKeyEvents(currentChar, codepage, keyEvents); }