Write ASCII NULL to StdIn for untranslated WM_KEYDOWN events. #9417

Closed
opened 2026-01-31 01:53:57 +00:00 by claunia · 4 comments
Owner

Originally created by @cnayoung on GitHub (Jul 3, 2020).

Description of the new feature/enhancement

Other Windows terminals (cmd.exe, PowerShell used outside of Windows Terminal) always represent WM_KEYDOWN events, even when there is no corresponding WM_CHAR (i.e., TranslateMessageEx returns False in your code). In this case, an ASCII NULL (ASCII 0) is written to StdIn. This allows console applications to detect certain types of events where a key is pressed but there is no corresponding character. While this is generally not useful for normal keyboard entry, it can be very useful in certain circumstances, including processing input from barcode scanners.

Desktop application frameworks and browsers normally report all WM_KEYDOWN events using their event model, even if there is no character value to report. Cmd.exe and PowerShell approximate to this same strategy by writing an ASCII 0 to StdIn. Windows Terminal does not do this. This makes it unsuitable to handle certain scenarios. As an example, we operate a large pharmaceutical system used by every pharmacist, dispensing doctor and medicine wholesaler across Europe (currently 30 countries, rising to 31 or 32 by 2025). We also provide a simple stand-alone browser client application for rapid and simple access to that system. Users use the client system to scan barcodes using barcode scanners that emulate keyboards. To be economically viable, we had to ensure that we can handle several issues that can arise with barcode scanners, including mismatches between the scanner and computer keyboard layouts, without significant volumes of support calls. To do this, we ask users to scan an initial sequence of barcodes that we display dynamically on the screen. We analyse the results and build a map that ensures that barcodes can be read reliably.

Internally we use a console application extensively to test different combinations of scanner and computer configuration. We cannot use this application in Windows Terminal, except under narrow constraints. The first problem is that we cannot detect dead keys when building the map, which prevents use with the majority of European keyboards. The second is that some keyboard layouts do not support the old DOS convention for entering ASCII control characters. Unfortunately, the Data Matrix barcodes used across the pharmaceutical industry rely on the use of ASCII 29 (this is a GS1 standard supported by almost all barcode scanners). When emulating keyboards, barcode scanners have no choice than to use the old DOS convention (Ctrl+[ASCII+64]). If the computer keyboard does not support the DOS convention, we can still infer ASCII 29s if we receive an ASCII 0 to indicate a key was pressed. This significantly extends the usefulness of our library. This general approach works well in browsers and other environments, including desktop apps. It works in cmd.exe and PowerShell (when run outside of Windows Terminal), but not Windows Terminal. With ASCII 0 support, with a barcode scanner configured as a US keyboard (generally the default), we can map reliably to approximately 93% of all European Windows keyboard layouts without the user having to reconfigure their barcode scanner. With this feature, this drops to probably 10% - 20%.

Proposed technical implementation details (optional)

When processing a WM_KEYDOWN (and maybe WM_ SYSKEYDOWN) event, if TranslateMessageEx returns False (no WM_CHAR), ensure that an ASCII 0 is written to StdIn.

Evidence.docx

Originally created by @cnayoung on GitHub (Jul 3, 2020). # Description of the new feature/enhancement Other Windows terminals (cmd.exe, PowerShell used outside of Windows Terminal) always represent WM_KEYDOWN events, even when there is no corresponding WM_CHAR (i.e., TranslateMessageEx returns False in your code). In this case, an ASCII NULL (ASCII 0) is written to StdIn. This allows console applications to detect certain types of events where a key is pressed but there is no corresponding character. While this is generally not useful for normal keyboard entry, it can be very useful in certain circumstances, including processing input from barcode scanners. Desktop application frameworks and browsers normally report all WM_KEYDOWN events using their event model, even if there is no character value to report. Cmd.exe and PowerShell approximate to this same strategy by writing an ASCII 0 to StdIn. Windows Terminal does not do this. This makes it unsuitable to handle certain scenarios. As an example, we operate a large pharmaceutical system used by every pharmacist, dispensing doctor and medicine wholesaler across Europe (currently 30 countries, rising to 31 or 32 by 2025). We also provide a simple stand-alone browser client application for rapid and simple access to that system. Users use the client system to scan barcodes using barcode scanners that emulate keyboards. To be economically viable, we had to ensure that we can handle several issues that can arise with barcode scanners, including mismatches between the scanner and computer keyboard layouts, without significant volumes of support calls. To do this, we ask users to scan an initial sequence of barcodes that we display dynamically on the screen. We analyse the results and build a map that ensures that barcodes can be read reliably. Internally we use a console application extensively to test different combinations of scanner and computer configuration. We cannot use this application in Windows Terminal, except under narrow constraints. The first problem is that we cannot detect dead keys when building the map, which prevents use with the majority of European keyboards. The second is that some keyboard layouts do not support the old DOS convention for entering ASCII control characters. Unfortunately, the Data Matrix barcodes used across the pharmaceutical industry rely on the use of ASCII 29 (this is a GS1 standard supported by almost all barcode scanners). When emulating keyboards, barcode scanners have no choice than to use the old DOS convention (Ctrl+[ASCII+64]). If the computer keyboard does not support the DOS convention, we can still infer ASCII 29s if we receive an ASCII 0 to indicate a key was pressed. This significantly extends the usefulness of our library. This general approach works well in browsers and other environments, including desktop apps. It works in cmd.exe and PowerShell (when run outside of Windows Terminal), but not Windows Terminal. With ASCII 0 support, with a barcode scanner configured as a US keyboard (generally the default), we can map reliably to approximately 93% of all European Windows keyboard layouts without the user having to reconfigure their barcode scanner. With this feature, this drops to probably 10% - 20%. # Proposed technical implementation details (optional) When processing a WM_KEYDOWN (and maybe WM_ SYSKEYDOWN) event, if TranslateMessageEx returns False (no WM_CHAR), ensure that an ASCII 0 is written to StdIn. [Evidence.docx](https://github.com/microsoft/terminal/files/4870765/Evidence.docx)
claunia added the Needs-TriageArea-InputResolution-DuplicateProduct-Terminal labels 2026-01-31 01:53:57 +00:00
Author
Owner

@DHowett commented on GitHub (Jul 3, 2020):

Would you mind giving this a try in the Preview version of Terminal? We recently completed #4999, which lets us pass higher-fidelity Win32 console input records to the commandline application on the other end.

@DHowett commented on GitHub (Jul 3, 2020): Would you mind giving this a try in the Preview version of Terminal? We recently completed #4999, which lets us pass higher-fidelity Win32 console input records to the commandline application on the other end.
Author
Owner

@cnayoung commented on GitHub (Jul 3, 2020):

Sure. I'll get back to you once I have done this.

@cnayoung commented on GitHub (Jul 3, 2020): Sure. I'll get back to you once I have done this.
Author
Owner

@cnayoung commented on GitHub (Jul 3, 2020):

Hi Dustin. Well, that must be an all-time record for implementing a feature request! Yes, it works OK in Preview 1.1!

I did run into a problem. The preview appears to be handling the keyboard input very slowly. It could just be an environmental issue on my machine but I suspect it is just that the preview needs some optimizing before release. When I run the same code outside of Windows Terminal it is much faster. By default, our code looks for gaps in keyboard input and assumes that the barcode scanner has stopped transmitting if it detects a gap. The app is configured to detect 100ms gaps which is normally OK, but proved insufficient in this case. Gap detection is optional and unnecessary if the barcode scanner outputs a LF, CR or CRLF. When I switched gap detection off, everything worked perfectly, if a little slowly. I rebooted the barcode scanner, but that made no difference.

Anyway, thanks for your response, and can I just record how much I like Windows Terminal and what you guys are doing. It's great to see Microsoft giving this attention to terminals, and I really like the way WT is evolving. Very relieved that I can use it with our console app!

@cnayoung commented on GitHub (Jul 3, 2020): Hi Dustin. Well, that must be an all-time record for implementing a feature request! Yes, it works OK in Preview 1.1! I did run into a problem. The preview appears to be handling the keyboard input very slowly. It could just be an environmental issue on my machine but I suspect it is just that the preview needs some optimizing before release. When I run the same code outside of Windows Terminal it is much faster. By default, our code looks for gaps in keyboard input and assumes that the barcode scanner has stopped transmitting if it detects a gap. The app is configured to detect 100ms gaps which is normally OK, but proved insufficient in this case. Gap detection is optional and unnecessary if the barcode scanner outputs a LF, CR or CRLF. When I switched gap detection off, everything worked perfectly, if a little slowly. I rebooted the barcode scanner, but that made no difference. Anyway, thanks for your response, and can I just record how much I like Windows Terminal and what you guys are doing. It's great to see Microsoft giving this attention to terminals, and I really like the way WT is evolving. Very relieved that I can use it with our console app!
Author
Owner

@zadjii-msft commented on GitHub (Jul 16, 2020):

I'm glad that #4999 fixed this for you!

I'm also very surprised that the input latency is that much worse for you. Sure, we're sending a lot more bytes now for input (from something like 1B per keydown to 17B for the down and 17B for the up), but it should still have less than 100ms latency...

I'm gonna close this out for now, since #4999 seemed to fix the issue at hand, but we can continue the latency conversation below

@zadjii-msft commented on GitHub (Jul 16, 2020): I'm glad that #4999 fixed this for you! I'm also very surprised that the input latency is that much worse for you. Sure, we're sending a _lot_ more bytes now for input (from something like 1B per keydown to 17B for the down and 17B for the up), but it should still have less than 100ms latency... I'm gonna close this out for now, since #4999 seemed to fix the issue at hand, but we can continue the latency conversation below
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#9417