Scenario: Improved keyboard handling #6973

Closed
opened 2026-01-31 00:51:56 +00:00 by claunia · 17 comments
Owner

Originally created by @zadjii-msft on GitHub (Mar 18, 2020).

Originally assigned to: @zadjii-msft on GitHub.

The Terminal's keyboard input is fundamentally backed by VT sequences, which limits the range of keys that we can actually send relative to what the console was capable of. This megathread is tracking all the issues that might be related to this:

  • Some keybindings used by PSReadLine aren't getting through #879
  • Bug Report: Control+Space not sent to terminal emulator. #2865
  • Shift+Enter always submits, breaking PSReadline features [Windows.Terminal] #530
  • Powershell: Ctrl-Alt-? does not work in Windows Terminal #3079
  • Bug: ctrl+break is not ctrl+c #1119
  • Something wrong with keyboard modifiers processing? #1694
  • Numeric input not accepted by choice.exe #3608
  • Ctrl+Keys that can't be encoded as VT should still fall through as the unmodified character #3483
  • Modifier keys are not properly propagated to application hosted in Windows Terminal #4334 / Terminal processing regression from v0.5.2762.0 (#4446)
  • We may be able to fix the Ctrl+Backspace/Ctrl+H mixup that resulted in #5957.

Before 2.0, we're hoping on adding support for parsing a much broader variety of keys via conpty.

Keys that we definitely need to support, that don't have unique VT sequences:

Originally created by @zadjii-msft on GitHub (Mar 18, 2020). Originally assigned to: @zadjii-msft on GitHub. The Terminal's keyboard input is fundamentally backed by VT sequences, which limits the range of keys that we can actually send relative to what the console was capable of. This megathread is tracking all the issues that might be related to this: * [x] Some keybindings used by PSReadLine aren't getting through #879 * [x] Bug Report: Control+Space not sent to terminal emulator. #2865 * [x] Shift+Enter always submits, breaking PSReadline features [Windows.Terminal] #530 * [x] Powershell: Ctrl-Alt-? does not work in Windows Terminal #3079 * [x] Bug: ctrl+break is not ctrl+c #1119 * [x] Something wrong with keyboard modifiers processing? #1694 * [x] Numeric input not accepted by choice.exe #3608 * [ ] Ctrl+Keys that can't be encoded as VT should still fall through as the unmodified character #3483 * [x] Modifier keys are not properly propagated to application hosted in Windows Terminal #4334 / #4446 * [ ] We may be able to fix the Ctrl+Backspace/Ctrl+H mixup that resulted in #5957. Before 2.0, we're hoping on adding support for parsing a much broader variety of keys via conpty. Keys that we definitely need to support, that don't have unique VT sequences: * [x] <kbd>Ctrl+Space</kbd> (#879, #2865) * [x] <kbd>Shift+Enter</kbd> (#530) * [x] <kbd>Ctrl+Break</kbd> (#1119) * [x] <kbd>Ctrl+Alt+?</kbd> (#3079) * [x] <kbd>Ctrl</kbd>, <kbd>Alt</kbd>, <kbd>Shift</kbd>, (without another keydown/up) (#3608, #4334, #4446)
claunia added the Resolution-Fix-CommittedArea-InputProduct-ConptyIssue-Scenario labels 2026-01-31 00:51:56 +00:00
Author
Owner

@zadjii-msft commented on GitHub (Apr 14, 2020):

This is a work-in-progress

Potential Solutions:

Create our own format for INPUT_RECORDs

  • If we wanted to do this, then we'd probably want to have the Terminal only send input as this format, and not use the existing translator to synthesize VT sequences
    • Consider sending a ctrl down, '^A', ctrl up. We wouldn't want to send this as three sequences, because conpty will take the '^A' and synthesize another ctrl down, ctrl up pair.
  • With conpty passthrough mode, we'd still need the InpustStateMachineEngine to convert these sequences into INPUT_RECORDs to translate back to VT
  • Wouldn't really expect client apps to ever need this format, but it could always be possible for them to need it in the future.

Pros:

  • Definitely gets us all the information that we need.
  • Can handle solo modifiers
  • Can handle keydown and keyup separately
  • We can make the sequence however we want to parse it.

Cons:

  • No reference implementation, so we'd be flying blind
  • We'd be defining our own VT sequences for these, which we've never done before. This was inevitable, however, this is still the first time we'd be doing this.
  • Something about Microsoft extending well-defined protocols being bad 😆
  • By having the Terminal send all input as this protocol, VT Input passthrough to apps that want VT input won't work anymore for the Terminal. That's okay

Scenarios

User is typing into WSL from WT

WT -> conpty[1] -> wsl

  • conpty 1 will ask for win32-input-mode from WT
  • When the user types keys in WT, WT will translate them into win32 sequences and send them to conpty[1]
  • conpty[1] will translate those win32 sequences into INPUT_RECORDs
  • when WSL reads the input, conpty 1 will translate the INPUT_RECORDs into VT sequences corresponding to whatever input mode the linux app is in

User is typing into cmd.exe running in WSL interop

WT -> conpty[1] -> wsl -> conpty[2] -> cmd.exe

(presuming you start from the previous scenario, and launch cmd.exe inside wsl)

  • conpty 2 will ask for win32-input-mode from conpty 1
  • When the user types keys in WT, WT will translate them into win32 sequences and send them to conpty[1]
  • conpty[1] will translate those win32 sequences into INPUT_RECORDs
  • when WSL reads the input, conpty 1 will translate the INPUT_RECORDs into VT sequences for the win32 input that conpty 2 requested
  • conpty 2 will get those sequences, and will translate those win32 sequences into INPUT_RECORDs
  • when cmd.exe reads the input, they'll receive the full INPUT_RECORDs they're expecting

kitty extension

Reference

Pros:

  • Not terribly difficult to decode
  • Unique from anything else we'd be processing, as it's an APC sequence (\x1b_)
  • From their docs:

    All printable key presses without modifier keys are sent just as in the normal mode. ... For non printable keys and key combinations including one or more modifiers, an escape sequence encoding the key event is sent

    • I think like this. ASCII and other keyboard layout chars (things that would hit SendChar) would still just come through as the normal char.

Cons:

  • Their encoding table is mad. Look at this. What order is that in? Obviously the first column is sorted alphabetically, but the mapping of key->char is in a seemingly bonkers order.
  • I can't get it working locally, so hard to test 😐
  • They do declare the fullkbd terminfo capability to identify that they support this mode, but I'm not sure anyone else uses it.
    • I'm also not sure that any client apps are reading this currently.
  • This isn't designed to be full KEY_EVENTs - where would we put the scancode (for apps that think that's important)?
    • We'd have to extend this protocol anyways

xterm "Set key modifier options"

Notably looking at modifyOtherKeys.

Pros:

  • xterm implements this so there's a reference implementation
  • relatively easy to parse these sequences. CSI 27 ; <modifiers> ; <key> ~

Cons:

  • Only sends the sequence on key-up
  • Doesn't send modifiers all on their own

DECPCTERM

VT100.net doc

Pros:

  • Enables us to send key-down and key-up keys independently
  • Enables us to send modifiers on their own
  • Part of the VT 510 standard

Cons:

  • neither xterm nor gnome-terminal (VTE) seem to implement this. I'm not sure if anyone's got a reference implementation for us to work with.
  • Unsure how this would work with other keyboard layouts
    • this doc seems to list the key-down/up codes for all the en-us keyboard keys, but the scancodes for these are different for up and down. That would seem to imply we couldn't just shove the Win32 scancode in those bits

DECPKM, DECSKMR

DECPKM
DECSKMR
DECEKBD

Pros:

  • Enables us to send key-down and key-up keys independently
  • Enables us to send modifiers on their own
  • Part of the VT 510 standard

Cons:

  • neither xterm nor gnome-terminal (VTE) seem to implement this. I'm not sure if anyone's got a reference implementation for us to work with.
  • not sure that "a three-character ISO key position name, for example C01" is super compatible with our Win32 VKEYs.

Things to keep in mind

  • Would this encoding be mixable with other normal VT processing easily?
    • How would the Terminal know when it should send a <chosen_encoding> key vs a normally encoded one?
      • For ex, Ctrl+space - should we send NUL or <chosen_encoding's version of ctrl+space>
  • If there's a scenario where Windows Terminal might not be connected to a conpty, then how does conpty enable <chosen_encoding>?
  • Is the goal "Full INPUT_RECORD fidelity" or "Make the above scenarios work"?
    • One could imagine having the Terminal special-case the above keys, and send the xterm modifyOtherKeys sequences just for those scenarios.
      • This would not work for shift all by itself.
    • In my opinion, "just making the above work" is a subset of "full INPUT_RECORD", and inevitably we're going to want "full INPUT_RECORD"

Current Conclusions

This is not a formal conclusion, just where I'm currently leaning. Expect this to change.

April 15, 2020: I'm leaning towards synthesizing our own format for INPUT_RECORDs currently.

  • The kitty format isn't bad, but it's not good, and it's not widespread
  • The DEC* formats don't have any reference implementations, so it's not like any other terminal emulators are using them.
  • xterm's modifyOtherKeys doesn't actually get us solo modifier up/downs

The goal we're trying to achieve is communicating INPUT_RECORDs from the terminal to the client app via conpty. This isn't supposed to be a *nix terminal compatible communication, it's supposed to be fundamentally Win32-like.

References

@zadjii-msft commented on GitHub (Apr 14, 2020): _This is a work-in-progress_ Potential Solutions: ## Create our own format for `INPUT_RECORD`s * If we wanted to do this, then we'd probably want to have the Terminal only send input as this format, and not use the existing translator to synthesize VT sequences - Consider sending a ctrl down, '^A', ctrl up. We wouldn't want to send this as three sequences, because conpty will take the '^A' and synthesize _another_ ctrl down, ctrl up pair. * With conpty passthrough mode, we'd still need the `InpustStateMachineEngine` to convert these sequences into INPUT_RECORDs to translate back to VT * Wouldn't really expect client apps to ever _need_ this format, but it could always be possible for them to need it in the future. #### Pros: * Definitely gets us all the information that we need. * Can handle solo modifiers * Can handle keydown and keyup separately * We can make the sequence however we want to parse it. #### Cons: * No reference implementation, so we'd be flying blind * We'd be defining our own VT sequences for these, which we've never done before. This was _inevitable_, however, this is still the first time we'd be doing this. * Something about Microsoft extending well-defined protocols being bad 😆 * By having the Terminal send all input as _this protocol_, VT Input passthrough to apps that want VT input won't work anymore for the Terminal. That's _okay_ ### Scenarios #### User is typing into WSL from WT `WT -> conpty[1] -> wsl` * conpty 1 will ask for win32-input-mode from WT * When the user types keys in WT, WT will translate them into win32 sequences and send them to conpty[1] * conpty[1] will translate those win32 sequences into `INPUT_RECORD`s * when WSL reads the input, conpty 1 will translate the `INPUT_RECORD`s into VT sequences corresponding to whatever input mode the linux app is in #### User is typing into `cmd.exe` running in WSL interop `WT -> conpty[1] -> wsl -> conpty[2] -> cmd.exe` (presuming you start from the previous scenario, and launch `cmd.exe` inside wsl) * conpty 2 will ask for win32-input-mode from conpty 1 * When the user types keys in WT, WT will translate them into win32 sequences and send them to conpty[1] * conpty[1] will translate those win32 sequences into `INPUT_RECORD`s * when WSL reads the input, conpty 1 will translate the `INPUT_RECORD`s into VT sequences for the win32 input that conpty 2 requested * conpty 2 will get those sequences, and will translate those win32 sequences into `INPUT_RECORD`s * when cmd.exe reads the input, they'll receive the full `INPUT_RECORD`s they're expecting ## kitty extension [Reference](https://sw.kovidgoyal.net/kitty/protocol-extensions.html#keyboard-handling) #### Pros: * Not terribly difficult to decode * Unique from anything else we'd be processing, as it's an APC sequence (`\x1b_`) * From their docs: > All printable key presses without modifier keys are sent just as in the normal mode. ... For non printable keys and key combinations including one or more modifiers, an escape sequence encoding the key event is sent - I think like this. ASCII and other keyboard layout chars (things that would hit `SendChar`) would still just come through as the normal char. #### Cons: * Their encoding table is _mad_. [Look at this](https://sw.kovidgoyal.net/kitty/key-encoding.html). What order is that in? Obviously the first column is sorted alphabetically, but the mapping of key->char is in a seemingly bonkers order. * I can't get it working locally, so hard to test 😐 * They do declare the `fullkbd` terminfo capability to identify that they support this mode, but I'm not sure anyone else uses it. - I'm also not sure that any _client_ apps are reading this currently. * This isn't designed to be full `KEY_EVENT`s - where would we put the scancode (for apps that think that's important)? - We'd have to extend this protocol _anyways_ ## `xterm` "Set key modifier options" Notably looking at [`modifyOtherKeys`](https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys). #### Pros: * `xterm` implements this so there's a reference implementation * relatively easy to parse these sequences. `CSI 27 ; <modifiers> ; <key> ~` #### Cons: * Only sends the sequence on key-up * Doesn't send modifiers all on their own ## `DECPCTERM` [VT100.net doc](https://vt100.net/docs/vt510-rm/DECPCTERM.html) #### Pros: * Enables us to send key-down and key-up keys independently * Enables us to send modifiers on their own * Part of the VT 510 standard #### Cons: * neither `xterm` nor `gnome-terminal` (VTE) seem to implement this. I'm not sure if anyone's got a reference implementation for us to work with. * Unsure how this would work with other keyboard layouts - [this doc](https://vt100.net/docs/vt510-rm/chapter8.html#S8.13) seems to list the key-down/up codes for all the en-us keyboard keys, but the scancodes for these are different for up and down. That would seem to imply we couldn't just shove the Win32 scancode in those bits ## `DECPKM`, `DECSKMR` [DECPKM](https://vt100.net/docs/vt510-rm/DECKPM.html) [DECSKMR](https://vt100.net/docs/vt510-rm/DECSKMR.html) [DECEKBD](https://vt100.net/docs/vt510-rm/DECEKBD.html) #### Pros: * Enables us to send key-down and key-up keys independently * Enables us to send modifiers on their own * Part of the VT 510 standard #### Cons: * neither `xterm` nor `gnome-terminal` (VTE) seem to implement this. I'm not sure if anyone's got a reference implementation for us to work with. * not sure that "a three-character ISO key position name, for example C01" is super compatible with our Win32 VKEYs. <!-- I'm removing this from the list. The encoding I'm thinking of was an undocumented feature of _cygwin_, but since it's totally undocumented, there's basically no way of me investigating it for our own use. ## ConEmu `INPUT_RECORD` extension Does this even exist? IIRC this was the original plan like, years ago, but I've got no emails that refer to it, nor does it seem like there's any documentation about it on the [conemu docs](https://conemu.github.io/en/TableOfContents.html) site. Maybe it wasn't ConEmu, and it was some other terminal on Windows? --> ## Things to keep in mind * Would this encoding be mixable with other normal VT processing easily? - How would the Terminal know when it should send a \<chosen_encoding> key vs a normally encoded one? - For ex, Ctrl+space - should we send NUL or \<chosen_encoding's version of ctrl+space> * If there's a scenario where Windows Terminal might _not_ be connected to a conpty, then how does conpty enable \<chosen_encoding>? * Is the goal "Full `INPUT_RECORD` fidelity" or "Make the above scenarios work"? - One could imagine having the Terminal special-case the above keys, and send the xterm modifyOtherKeys sequences just for those scenarios. - This would _not_ work for <kbd>shift</kbd> all by itself. - In my _opinion_, "just making the above work" is a subset of "full INPUT_RECORD", and inevitably we're going to want "full INPUT_RECORD" ## Current Conclusions _This is not a formal conclusion, just where I'm currently leaning_. Expect this to change. **April 15, 2020**: I'm leaning towards synthesizing our own format for INPUT_RECORDs currently. * The kitty format isn't bad, but it's not _good_, and it's not widespread * The `DEC*` formats don't have any reference implementations, so it's not like any other terminal emulators are using them. * xterm's `modifyOtherKeys` doesn't actually get us solo modifier up/downs The goal we're trying to achieve is communicating `INPUT_RECORD`s from the terminal to the client app via conpty. This isn't supposed to be a *nix terminal compatible communication, it's supposed to be fundamentally Win32-like. ## References * [Why Is It so Hard to Detect Keyup Event on Linux?](https://blog.robertelder.org/detect-keyup-event-linux-terminal/) - and the [HackerNews discussion](https://news.ycombinator.com/item?id=19012132)
Author
Owner

@j4james commented on GitHub (Apr 15, 2020):

Another option to consider is Key Position Mode (DECKPM) which reports the state of the modifier keys along with each key press (see DECEKBD for the actual report format). I don't think it has separate keyup and keydown events, but it does have an option to report modifier keypresses separately (see DECSMKR).

How would the Terminal know when it should send a <chosen_encoding> key vs a normally encoded one?

I assumed this is something the conpty host would initiate on startup, requesting whichever mode (or modes) we decided to support. If the terminal at the other end supported the requested mode, then it would start reporting keypresses in that format.

In some cases, if the key reporting sequences can mean different things in different modes, the host might need to know whether the client had actually accepted the request to use a particular mode. In the case of DECKPM you could determine that by querying the mode state with DECRQM. In the case of DECPCTERM, you could determine whether the client supported the option from the DA1 report.

@j4james commented on GitHub (Apr 15, 2020): Another option to consider is _Key Position Mode_ ([`DECKPM`](https://vt100.net/docs/vt510-rm/DECKPM.html)) which reports the state of the modifier keys along with each key press (see [`DECEKBD`](https://vt100.net/docs/vt510-rm/DECEKBD.html) for the actual report format). I don't think it has separate keyup and keydown events, but it does have an option to report modifier keypresses separately (see [`DECSMKR`](https://vt100.net/docs/vt510-rm/DECSMKR.html)). > How would the Terminal know when it should send a <chosen_encoding> key vs a normally encoded one? I assumed this is something the conpty host would initiate on startup, requesting whichever mode (or modes) we decided to support. If the terminal at the other end supported the requested mode, then it would start reporting keypresses in that format. In some cases, if the key reporting sequences can mean different things in different modes, the host might need to know whether the client had actually accepted the request to use a particular mode. In the case of `DECKPM` you could determine that by querying the mode state with [`DECRQM`](https://vt100.net/docs/vt510-rm/DECRQM.html). In the case of `DECPCTERM`, you could determine whether the client supported the option from the [`DA1`](https://vt100.net/docs/vt510-rm/DA1.html) report.
Author
Owner

@zadjii-msft commented on GitHub (Apr 15, 2020):

Thanks for the suggestions @j4james. Those worry me the same way that DECPCTERM does in that there doesn't seem to be any terminal applications that I can use as a reference implementation for them 😕

@zadjii-msft commented on GitHub (Apr 15, 2020): Thanks for the suggestions @j4james. Those worry me the same way that DECPCTERM does in that there doesn't seem to be any terminal applications that I can use as a reference implementation for them 😕
Author
Owner

@j4james commented on GitHub (Apr 15, 2020):

Those worry me the same way that DECPCTERM does in that there doesn't seem to be any terminal applications that I can use as a reference implementation for them

What about this? https://www.amazon.com/DEC-VT510-TERMINAL/dp/B016YJZYVK 😄
I've actually considered getting one myself, although I don't really have the space for it.

Anyway I'd much prefer implementing an actual standard over any of the proprietary extensions, but I suspect we'll probably end up implementing several of the protocols anyway. I know I would want to add support for the DEC standards even if nobody else does, just because I'd like WT to be a proper terminal emulator. And we'll probably want to do XTerm's modifier extension, because I think there are existing apps that make use of it.

I don't really see the point of coming up with our own proprietary protocol, though, unless it can actually do something that DECPCTERM doesn't. You still don't have a reference implementation, and you've got the additional effort of inventing your own protocol.

this doc seems to list the key-down/up codes for all the en-us keyboard keys, but the scancodes for these are different for up and down. That would seem to imply we couldn't just shove the Win32 scancode in those bits

I haven't really looked at it in much detail, but the impression I got was that the "make" code was a standard scancode, and the "break" code is just the same thing with the high bit set (for the two byte sequences, it'll be the second byte that has the high bit set).

@j4james commented on GitHub (Apr 15, 2020): > Those worry me the same way that `DECPCTERM` does in that there doesn't seem to be any terminal applications that I can use as a reference implementation for them What about this? https://www.amazon.com/DEC-VT510-TERMINAL/dp/B016YJZYVK 😄 I've actually considered getting one myself, although I don't really have the space for it. Anyway I'd much prefer implementing an actual standard over any of the proprietary extensions, but I suspect we'll probably end up implementing several of the protocols anyway. I know I would want to add support for the DEC standards even if nobody else does, just because I'd like WT to be a proper terminal emulator. And we'll probably want to do XTerm's modifier extension, because I think there are existing apps that make use of it. I don't really see the point of coming up with our own proprietary protocol, though, unless it can actually do something that `DECPCTERM` doesn't. You still don't have a reference implementation, and you've got the additional effort of inventing your own protocol. > [this doc](https://vt100.net/docs/vt510-rm/chapter8.html#S8.13) seems to list the key-down/up codes for all the en-us keyboard keys, but the scancodes for these are different for up and down. That would seem to imply we couldn't just shove the Win32 scancode in those bits I haven't really looked at it in much detail, but the impression I got was that the "make" code was a standard scancode, and the "break" code is just the same thing with the high bit set (for the two byte sequences, it'll be the second byte that has the high bit set).
Author
Owner

@zadjii-msft commented on GitHub (Apr 21, 2020):

What about this? amazon.com/DEC-VT510-TERMINAL/dp/B016YJZYVK 😄
I've actually considered getting one myself, although I don't really have the space for it.

We can barely convince management to get us high-dpi displays, I doubt I could get that approved 😆

I would want to add support for the DEC standards even if nobody else does, just because I'd like WT to be a proper terminal emulator

I totally agree with this sentiment. I don't disagree that this is a valuable goal to move towards. However, from where I'm sitting looking at these bugs, being a better terminal emulator doesn't actually help us solve them. Being a better console emulator would though.

The way I'm looking at it now is that we can definitely make conhost a better terminal emulator independently of making the Windows Terminal a better console emulator. By letting the Terminal speak <our INPUT_RECORD protocol> to conpty, then conpty can have real INPUT_RECORDs in it's input buffer that Win32 applications will be able to read just the way they like to. Then, conhost is also already good at taking INPUT_RECORDs and turning them into strings of characters for applications that request VT input.

You still don't have a reference implementation, and you've got the additional effort of inventing your own protocol.

Without a reference implementation, I'm kinda inventing my own protocol anyways though, right? 😉 I still hate this about this solution, but the crux of the issue is that there are going to be some legacy Win32 apps out there somewhere that are going to want some piece of information that will only come from an INPUT_RECORD, and only a Win32 solution will work for this.

Maybe there's some future where the Terminal isn't connected to conpty. In that future, the Terminal will still be a better terminal emulator because it shares the same core terminal input translation as conhost does. So doing the INPUT_RECORD path isn't going to back the Terminal into a corner in the future.

@zadjii-msft commented on GitHub (Apr 21, 2020): > What about this? [amazon.com/DEC-VT510-TERMINAL/dp/B016YJZYVK](https://www.amazon.com/DEC-VT510-TERMINAL/dp/B016YJZYVK) 😄 > I've actually considered getting one myself, although I don't really have the space for it. We can barely convince management to get us high-dpi displays, I doubt I could get that approved 😆 > I would want to add support for the DEC standards even if nobody else does, just because I'd like WT to be a proper terminal emulator I totally agree with this sentiment. I don't disagree that this is a valuable goal to move towards. However, from where I'm sitting looking at these bugs, being a better _terminal_ emulator doesn't actually help us solve them. Being a better _console_ emulator would though. The way I'm looking at it now is that we can definitely make conhost a better terminal emulator independently of making the Windows Terminal a better console emulator. By letting the Terminal speak \<our INPUT_RECORD protocol> to conpty, then conpty can have real `INPUT_RECORD`s in it's input buffer that Win32 applications will be able to read just the way they like to. Then, conhost is also already good at taking `INPUT_RECORD`s and turning them into strings of characters for applications that request VT input. > You still don't have a reference implementation, and you've got the additional effort of inventing your own protocol. Without a reference implementation, I'm kinda inventing my own protocol anyways though, right? 😉 I still hate this about this solution, but the crux of the issue is that there are going to be some legacy Win32 apps out there somewhere that are going to want some piece of information that will only come from an `INPUT_RECORD`, and only a Win32 solution will work for this. Maybe there's some future where the Terminal isn't connected to conpty. In that future, the Terminal will still be a better terminal emulator because it shares the same core terminal input translation as conhost does. So doing the `INPUT_RECORD` path isn't going to back the Terminal into a corner in the future.
Author
Owner

@j4james commented on GitHub (Apr 21, 2020):

but the crux of the issue is that there are going to be some legacy Win32 apps out there somewhere that are going to want some piece of information that will only come from an INPUT_RECORD, and only a Win32 solution will work for this.

Maybe you're right. I was just hoping we'd have a solution where you could connect a standard terminal to the end of a conpty pipe and have it just work. With a proprietary solution that's never going to happen.

@j4james commented on GitHub (Apr 21, 2020): > but the crux of the issue is that there are going to be some legacy Win32 apps out there somewhere that are going to want some piece of information that will only come from an INPUT_RECORD, and only a Win32 solution will work for this. Maybe you're right. I was just hoping we'd have a solution where you could connect a standard terminal to the end of a conpty pipe and have it just work. With a proprietary solution that's never going to happen.
Author
Owner

@zadjii-msft commented on GitHub (Apr 21, 2020):

See but here's the thing I'm thinking - I think that's going to be just fine still.

The way I'm imagining it right now, when conpty starts up, it's going to ask for some private input mode. As all good terminal emulators should, when they don't understand that sequence, they'll just ignore it. Then they'll send input like they currently do, and conpty will handle it just the same as it can currently. We'll translate the normal sequences the same way we currently do, and everything will work just as well as they currently do.

However, for something that's been updated to support win32-input-mode, like the Terminal, it'll see that private mode sequence and start sending the win32 compatible sequences instead. If other terminals wanted to also adopt this to work better with legacy Windows applications they totally could, but I wouldn't say that this would be horribly important.

Our guidance is still going to be "if you're authoring a commandline application, you should avoid these keyboard shortcuts or use VT input, otherwise your application might not work in all terminals". For things like Hyper, mintty, putty, they're still going to hit this bug unless they're updated. However, regardless of which dialect we chose, they'd hit this bug, since none of them implement some reasonable alternative 😄

I'm just thinking that a win32-specific solution to a win32-specific bug isn't the worst outcome. I do appreciate you keeping me honest though ☺️

@zadjii-msft commented on GitHub (Apr 21, 2020): See but here's the thing I'm thinking - I think that's going to be just fine still. The way I'm imagining it right now, when conpty starts up, it's going to ask for some private input mode. As all good terminal emulators should, when they don't understand that sequence, they'll just ignore it. Then they'll send input like they currently do, and conpty will handle it just the same as it can currently. We'll translate the normal sequences the same way we currently do, and everything will work just as well as they currently do. However, for something that's been updated to support win32-input-mode, like the Terminal, it'll see that private mode sequence and start sending the win32 compatible sequences instead. If other terminals wanted to also adopt this to work better _with legacy Windows applications_ they totally could, but I wouldn't say that this would be horribly important. Our guidance is still going to be "if you're authoring a commandline application, you should avoid these keyboard shortcuts or use VT input, otherwise your application might not work in all terminals". For things like Hyper, mintty, putty, they're still going to hit this bug unless they're updated. However, _regardless_ of which dialect we chose, they'd hit this bug, since none of them implement some reasonable alternative 😄 I'm just thinking that a win32-specific solution to a win32-specific bug isn't the worst outcome. I do appreciate you keeping me honest though ☺️
Author
Owner

@j4james commented on GitHub (Apr 21, 2020):

For things like Hyper, mintty, putty, they're still going to hit this bug unless they're updated. However, regardless of which dialect we chose, they'd hit this bug, since none of them implement some reasonable alternative

Yeah. If I'm being realistic, it really doesn't matter. But I can't help thinking how cool it would have been to hook up a DEC terminal, built nearly 30 years ago, and have it work near perfectly with modern console apps. I means that's essentially what the PCTerm mode was designed for in the first place.

Then you could tell any terminal emulators that want the same level of functionality they'd just need to implement an existing VT protocol. As feature requests go, I suspect that's a lot easier to justify to some people than a proprietary win32-specific protocol.

Anyway, I'm just musing here on what might have been. I do understand your reasons for going the other route.

@j4james commented on GitHub (Apr 21, 2020): > For things like Hyper, mintty, putty, they're still going to hit this bug unless they're updated. However, regardless of which dialect we chose, they'd hit this bug, since none of them implement some reasonable alternative Yeah. If I'm being realistic, it really doesn't matter. But I can't help thinking how cool it would have been to hook up a DEC terminal, built nearly 30 years ago, and have it work near perfectly with modern console apps. I means that's essentially what the PCTerm mode was designed for in the first place. Then you could tell any terminal emulators that want the same level of functionality they'd just need to implement an existing VT protocol. As feature requests go, I suspect that's a lot easier to justify to some people than a proprietary win32-specific protocol. Anyway, I'm just musing here on what might have been. I do understand your reasons for going the other route.
Author
Owner

@machekku commented on GitHub (Apr 26, 2020):

Hi, I'm just a lurker and not an expert in this area, but when I saw this task I immediately thought of libtermkey/libtickit and their author who's been trying to improve terminal keyboard input for a long time: http://www.leonerd.org.uk/hacks/fixterms/ Maybe this could give you some ideas.

@machekku commented on GitHub (Apr 26, 2020): Hi, I'm just a lurker and not an expert in this area, but when I saw this task I immediately thought of libtermkey/libtickit and their author who's been trying to improve terminal keyboard input for a long time: http://www.leonerd.org.uk/hacks/fixterms/ Maybe this could give you some ideas.
Author
Owner

@zadjii-msft commented on GitHub (May 14, 2020):

As of 6b2d95264

  • Some keybindings used by PSReadLine aren't getting through #879
    • Ctrl+Backspace (BackwardKillWord)
      • ✔ already works in 1.0
    • Shift+Ctrl+Enter (InsertLineBelow)
      • 🎉 This is a new fix! 🎉
    • Ctrl+Space (MenuComplete)
      • ✔ already works in 1.0
    • Shift+Tab (TabCompletePrevious)
      • ✔ already works in 1.0
    • Alt+0 (DigitArgument) (and other digits)
      • ✔ already works in 1.0
    • PageDown (ScrollDisplayDown)
      • ⚠ Not sure this is even possible with conpty at all, though this can be bound directly in the Terminal
    • Ctrl+PageDown (ScrollDisplayDownLine)
      • ⚠ Not sure this is even possible with conpty at all, though this can be bound directly in the Terminal
    • PageUp (ScrollDisplayUp)
      • ⚠ Not sure this is even possible with conpty at all, though this can be bound directly in the Terminal
    • Ctrl+PageUp (ScrollDisplayUpLine)
      • ⚠ Not sure this is even possible with conpty at all, though this can be bound directly in the Terminal
    • Ctrl+Alt+? (ShowKeyBindings)
    • Alt+? (WhatIsKey)
      • ✔ already works in 1.0
  • Bug Report: Control+Space not sent to terminal emulator. #2865
    • ✔ already works in 1.0
  • 🎉 Shift+Enter always submits, breaking PSReadline features [Windows.Terminal] #530
  • 🎉 Powershell: Ctrl-Alt-? does not work in Windows Terminal #3079
  • Bug: ctrl+break is not ctrl+c #1119
    • Pause/Break now works in this scenario to pause the ping output
    • Ctrl+C STOPPED working!
  • 🎉 Something wrong with keyboard modifiers processing? #1694
  • 🎉 Numeric input not accepted by choice.exe #3608
  • Ctrl+Keys that can't be encoded as VT should still fall through as the unmodified character #3483
    • Okay this one's different. For this one, if a Ctrl+char hits the normal VT translation path, and that char is in (0x20,0x3f]|[0x60,0x7e], then we should just send that char
  • 🎉 Modifier keys are not properly propagated to application hosted in Windows Terminal #4334 / Terminal processing regression from v0.5.2762.0 (#4446)

EDIT:

The Ctrl+C issue:

(removed the image, because apparently, I released Ctrl too early in the conhost window, so that one was wrong 0.o)

# conhost
Down: 1 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x28
Down: 0 Repeat: 1 KeyCode: 0x43 ScanCode: 0x2e Char: ^C (0x3) KeyState: 0x28
Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x20

# WT & conpty+win32-input-mode
Down: 1 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x8
Down: 1 Repeat: 0 KeyCode: 0x43 ScanCode: 0x2e Char: ^C (0x3) KeyState: 0x8
Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x0

Differences:

  • WT is sending the ^C on a key down, conhost on the key-up
  • The repeat count is 0 in WT

The Ctrl+Break issue:

Ctrl+Break in conhost:
Down: 0 Repeat: 1 KeyCode: 0x13 ScanCode: 0x45 Char: \0 (0x0) KeyState: 0x20
Down: 0 Repeat: 1 KeyCode: 0x3 ScanCode: 0x46 Char: ^C (0x3) KeyState: 0x128
Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x20

Master regressions list:

  • Ctrl+C doesn't kill ping.exe (fixed by 5fc00d5bb)
  • Ctrl+Break still doesn't work (fixed by 5fc00d5bb)
  • Enter now only sends a keydown, no following keyup? (fixed by 5fc00d5bb)
    • probably getting treated as a char
  • (Backspace, actually almost all chars) now only sends a keydown, no following keyup? (fixed by 5fc00d5bb)
@zadjii-msft commented on GitHub (May 14, 2020): As of 6b2d95264 * [x] Some keybindings used by PSReadLine aren't getting through #879 - [x] <kbd>Ctrl+Backspace</kbd> (`BackwardKillWord`) - ✔ already works in 1.0 - [x] <kbd>Shift+Ctrl+Enter</kbd> (`InsertLineBelow`) - 🎉 This is a new fix! 🎉 - [x] <kbd>Ctrl+Space</kbd> (`MenuComplete`) - ✔ already works in 1.0 - [x] <kbd>Shift+Tab</kbd> (`TabCompletePrevious`) - ✔ already works in 1.0 - [x] <kbd>Alt+0</kbd> (`DigitArgument`) (and other digits) - ✔ already works in 1.0 - [ ] <kbd>PageDown</kbd> (`ScrollDisplayDown`) - ⚠ Not sure this is even possible with conpty at all, though this can be bound directly in the Terminal - [ ] <kbd>Ctrl+PageDown</kbd> (`ScrollDisplayDownLine`) - ⚠ Not sure this is even possible with conpty at all, though this can be bound directly in the Terminal - [ ] <kbd>PageUp</kbd> (`ScrollDisplayUp`) - ⚠ Not sure this is even possible with conpty at all, though this can be bound directly in the Terminal - [ ] <kbd>Ctrl+PageUp</kbd> (`ScrollDisplayUpLine`) - ⚠ Not sure this is even possible with conpty at all, though this can be bound directly in the Terminal - [x] <kbd>Ctrl+Alt+?</kbd> (`ShowKeyBindings`) - [x] <kbd>Alt+?</kbd> (`WhatIsKey`) - ✔ already works in 1.0 * [x] Bug Report: Control+Space not sent to terminal emulator. #2865 - ✔ already works in 1.0 * [x] 🎉 Shift+Enter always submits, breaking PSReadline features [Windows.Terminal] #530 * [x] 🎉 Powershell: Ctrl-Alt-? does not work in Windows Terminal #3079 * [x] Bug: ctrl+break is not ctrl+c #1119 - Pause/Break now works in this scenario to pause the ping output - ❌ Ctrl+C STOPPED working! - ✔(fixed by 5fc00d5bb) * [x] 🎉 Something wrong with keyboard modifiers processing? #1694 * [x] 🎉 Numeric input not accepted by choice.exe #3608 * [ ] Ctrl+Keys that can't be encoded as VT should still fall through as the unmodified character #3483 - Okay this one's different. For this one, if a Ctrl+char hits the normal VT translation path, and that char is in (0x20,0x3f]|[0x60,0x7e], then we should just send that char * [x] 🎉 Modifier keys are not properly propagated to application hosted in Windows Terminal #4334 / #4446 <hr> EDIT: ## The Ctrl+C issue: <!-- ![image](https://user-images.githubusercontent.com/18356694/81955700-0baf5e80-95d0-11ea-8461-17e76b14e9dd.png) --> (removed the image, because apparently, I released Ctrl too early in the conhost window, so that one was wrong 0.o) ``` # conhost Down: 1 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x28 Down: 0 Repeat: 1 KeyCode: 0x43 ScanCode: 0x2e Char: ^C (0x3) KeyState: 0x28 Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x20 # WT & conpty+win32-input-mode Down: 1 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x8 Down: 1 Repeat: 0 KeyCode: 0x43 ScanCode: 0x2e Char: ^C (0x3) KeyState: 0x8 Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x0 ``` Differences: * WT is sending the ^C on a key down, conhost on the key-up * The repeat count is 0 in WT <hr> ## The Ctrl+Break issue: ``` Ctrl+Break in conhost: Down: 0 Repeat: 1 KeyCode: 0x13 ScanCode: 0x45 Char: \0 (0x0) KeyState: 0x20 Down: 0 Repeat: 1 KeyCode: 0x3 ScanCode: 0x46 Char: ^C (0x3) KeyState: 0x128 Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x20 ``` <hr> ### Master regressions list: * [x] Ctrl+C doesn't kill `ping.exe` (fixed by 5fc00d5bb) * [x] Ctrl+Break still doesn't work (fixed by 5fc00d5bb) * [x] Enter now only sends a keydown, no following keyup? (fixed by 5fc00d5bb) - probably getting treated as a _char_ * [x] (Backspace, actually almost all _chars_) now only sends a keydown, no following keyup? (fixed by 5fc00d5bb)
Author
Owner

@tasogare3710 commented on GitHub (May 19, 2020):

I came from #5957.

I found other different key codes.

ctrl+J -> ^Q == LF -> DC1
ctrl+? -> ^_ == DEL -> US

@tasogare3710 commented on GitHub (May 19, 2020): I came from #5957. I found other different key codes. ctrl+J -> ^Q == LF -> DC1 ctrl+? -> ^_ == DEL -> US
Author
Owner

@zadjii-msft commented on GitHub (Jun 9, 2020):

With #6309 merged, I'm closing this issue out. #3483 and #5957 were both bugs that can be solved on their own, and weren't really a part of this scenario.

@zadjii-msft commented on GitHub (Jun 9, 2020): With #6309 merged, I'm closing this issue out. #3483 and #5957 were both bugs that can be solved on their own, and weren't really a part of this scenario.
Author
Owner

@unxed commented on GitHub (Apr 3, 2023):

To simplify implementation of win32-input-mode in terminals on platforms other than Windows, I wrote a small library that translates X11/Wayland XKB key syms into Windows key codes. There is also a demo application that prints win32-input-mode escape sequences based on X11 input events. I hope this will help those who want to add support for the win32-input-mode to their terminals designed for platforms other than Windows.

https://github.com/unxed/xkb2win

@unxed commented on GitHub (Apr 3, 2023): To simplify implementation of win32-input-mode in terminals on platforms other than Windows, I wrote a small library that translates X11/Wayland XKB key syms into Windows key codes. There is also a demo application that prints win32-input-mode escape sequences based on X11 input events. I hope this will help those who want to add support for the win32-input-mode to their terminals designed for platforms other than Windows. https://github.com/unxed/xkb2win
Author
Owner

@determin1st commented on GitHub (Mar 28, 2024):

eee... mm.. so where's the protocol description? how do i parse it without any description

kitty and leonerd's designs are awful! no sane terminal user will implement those

@determin1st commented on GitHub (Mar 28, 2024): eee... mm.. so where's the protocol description? how do i parse it without any description kitty and leonerd's designs are awful! no sane terminal user will implement those
Author
Owner
@zadjii-msft commented on GitHub (Mar 28, 2024): Here's the spec: https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
Author
Owner

@determin1st commented on GitHub (Mar 29, 2024):

notes

  • it's not INPUT_RECORD, its KEY_RECORD, INPUT_RECORD includes MOUSE_RECORD and others
  • same negligence for parsers as in kitty's design. querying must come first. what will happen with <CSI>?9001$p ?
  • who needs scancodes?
  • repeat and keyup / keydown may be transferred as a single value
  • char codepoint may be the length of utf8 bytes that follow

here's my recent take on this topic ... (im really lost in these github interfaces with thousands of links etc, no centralized chat or somehting.. so lost it)

i think one more possible scenario will be moving from ReadConsoleInput to generic ReadFile bytes like in *nix systems..

@determin1st commented on GitHub (Mar 29, 2024): notes - it's not INPUT_RECORD, its KEY_RECORD, INPUT_RECORD includes MOUSE_RECORD and others - same negligence for parsers as in kitty's design. querying must come first. what will happen with `<CSI>?9001$p` ? - who needs scancodes? - repeat and keyup / keydown may be transferred as a single value - char codepoint may be the length of utf8 bytes that follow here's my recent take on this topic ... (im really lost in these github interfaces with thousands of links etc, no centralized chat or somehting.. so lost it) i think one more possible scenario will be moving from `ReadConsoleInput` to generic `ReadFile` bytes like in *nix systems..
Author
Owner

@unxed commented on GitHub (Aug 24, 2024):

FYI: kitty protocol escape sequences generation from Windows compatible Key Event Record, public domain.

https://github.com/microsoft/terminal/issues/11509#issuecomment-2308421220

@unxed commented on GitHub (Aug 24, 2024): FYI: kitty protocol escape sequences generation from Windows compatible Key Event Record, public domain. https://github.com/microsoft/terminal/issues/11509#issuecomment-2308421220
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#6973