-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Win32 input mode breaks WSL .exe interop #16343
Comments
@craigloewen-msft as an FYI. We may have broken windows interop for WSL for insiders. We're looking into it. |
Probably also causes #16307 |
From what @DHowett said in #15476 (comment), my understanding was that the conpty DLL was tightly coupled to the openconsole version. So I'm wondering whether it's possible that you're getting a version mismatch by replacing the system conhost, if you aren't also using the corresponding conpty DLL? If it's not something like that, I have no idea what the issue could be. But I haven't had a chance to look at the code in detail (and probably won't have much time again until the weekend). |
I have an idea what the problem might be, but I don't really know how WSL works behind the scenes so my understanding may be incorrect.
If the above assumptions are correct, we're probably going to need to revert most if not all of PR #15476 in order to fix this, and come up with another solution for #15461. |
The way I see it, the fundamental problem is that the same By default it should only take affect when Do we support console clients requesting win32-input-sequences? If so, then that doesn't change the above IMO, because a client requesting it shouldn't change the encoding for any other attached client. Fixing the double-encoding is trivial with just a couple lines changed, but fixing the Win32 sequences being visible to console clients is difficult since it requires us to delay encoding to the time of I suspect we'll end up having to revert most of #15476 after all... 😢 |
I don't see why we shouldn't! It's not different from enabling mouse mode with
As above, it's not different from enabling mouse mode with |
In my vision, win32-input-sequences would be requested automatically by ConPTY at all times, just like it works right now. It's just that console clients (= in case of SSH on the server side) should not see those in form of 20 |
See... I'm actually an idiot. The reason it ACTUALLY happens is because of this: terminal/src/terminal/parser/stateMachine.cpp Lines 2139 to 2142 in 12318d9
Unfortunately, that statement is entirely wrong. The most basic example for this is that our input buffer is a basic char buffer[256]; and if your input pipe got more characters than that, the comment's assumption will be broken, because the read will be split up into multiple chunks. Second of all, however, WSL doesn't use anonymous pipes and so they can split up inputs into arbitrary chunks down to individual bytes. That's why we see broken win32 input sequences randomly in WSL. |
Yyeehehhhhh.. eh. Eaugh. When an application requests |
I did a little hack experiment with fixing the This fixes the problem with VT query responses not working correctly in conhost when win32-input mode is set (I'm almost sure we already had an issue for that, but I couldn't find it). It also fixes the conpty deadlock on startup that you're getting when running an exe from within WSL. I can't reproduce the second problem though. Running your That said, you still have a problem when you exit the exe and return to WSL, because the terminal is still in win32-input mode at that point. Since your typical WSL shell is not going to be expecting that, you get a lot of garbage output at the prompt when you type. I can work around that by adding a win32-input reset after the exe call, e.g. |
Since all VT parameters are treated to be at least 1 (and 1 if they're absent or 0), `modifierParam > 0` was always true. This meant that `ENHANCED_KEY` was always being set. It's unclear why `ENHANCED_KEY` was used there, but it's likely not needed in general. Closes #16266 ## Validation Steps Performed * Can't test this unless we fix the win32 input mode issue #16343 ❌
Since all VT parameters are treated to be at least 1 (and 1 if they're absent or 0), `modifierParam > 0` was always true. This meant that `ENHANCED_KEY` was always being set. It's unclear why `ENHANCED_KEY` was used there, but it's likely not needed in general. Closes #16266 ## Validation Steps Performed * Can't test this unless we fix the win32 input mode issue #16343 ❌ (cherry picked from commit be9fc20) Service-Card-Id: 91159301 Service-Version: 1.19
This changeset avoids re-encoding output from `AdaptDispatch` via the win32-input-mode mechanism when VT input is enabled. That is, an `AdaptDispatch` output like `\x1b[C` would otherwise result in dozens of characters of input. Related to #16343 ## Validation Steps Performed * Replace conhost with this * Launch a Win32 application inside WSL * ASCII keyboard inputs are represented as single `INPUT_RECORD`s ✅
This changeset avoids re-encoding output from `AdaptDispatch` via the win32-input-mode mechanism when VT input is enabled. That is, an `AdaptDispatch` output like `\x1b[C` would otherwise result in dozens of characters of input. Related to #16343 ## Validation Steps Performed * Replace conhost with this * Launch a Win32 application inside WSL * ASCII keyboard inputs are represented as single `INPUT_RECORD`s ✅ (cherry picked from commit 0da37a1) Service-Card-Id: 91246942 Service-Version: 1.19
When ConPTY exits it should attempt to restore the state as it was before it started. This is particularly important for the win32 input mode sequences, as Linux shells don't know what to do with it. Related to #16343 ## Validation Steps Performed * Replace conhost with this * Launch a Win32 application inside WSL * Exit that application * Shell prompt doesn't get filled with win32 input mode sequences ✅
When ConPTY exits it should attempt to restore the state as it was before it started. This is particularly important for the win32 input mode sequences, as Linux shells don't know what to do with it. Related to #16343 ## Validation Steps Performed * Replace conhost with this * Launch a Win32 application inside WSL * Exit that application * Shell prompt doesn't get filled with win32 input mode sequences ✅ (cherry picked from commit 70e51ae) Service-Card-Id: 91246943 Service-Version: 1.19
This is my proposal to avoid aborting ConPTY input parsing because a read accidentally got split up into more than one chunk. This happens a lot with WSL for me, as I often get (for instance) a `\x1b[67;46;99;0;32;` input followed immediately by a `1_` input. The current logic would cause both of these to be flushed out to the client application. This PR fixes the issue by only flushing either a standalone escape character or a escape+character combination. It basically limits the previous code to just `VTStates::Ground` and `VTStates::Escape`. I'm not using the `_state` member, because `VTStates::OscParam` makes no distinction between `\x1b]` and `\x1b]1234` and I only want to flush the former. I felt like checking the contents of `run` directly is easier to understand. Related to #16343 ## Validation Steps Performed * win32-input-mode sequences are now properly buffered ✅ * Standalone alt-key combinations are still being flushed ✅
This is my proposal to avoid aborting ConPTY input parsing because a read accidentally got split up into more than one chunk. This happens a lot with WSL for me, as I often get (for instance) a `\x1b[67;46;99;0;32;` input followed immediately by a `1_` input. The current logic would cause both of these to be flushed out to the client application. This PR fixes the issue by only flushing either a standalone escape character or a escape+character combination. It basically limits the previous code to just `VTStates::Ground` and `VTStates::Escape`. I'm not using the `_state` member, because `VTStates::OscParam` makes no distinction between `\x1b]` and `\x1b]1234` and I only want to flush the former. I felt like checking the contents of `run` directly is easier to understand. Related to #16343 ## Validation Steps Performed * win32-input-mode sequences are now properly buffered ✅ * Standalone alt-key combinations are still being flushed ✅ (cherry picked from commit 5f5ef10) Service-Card-Id: 91270261 Service-Version: 1.19
Even with the previous fixes we still randomly encounter win32- input-mode sequences that are broken up in exactly such a way that e.g. lone escape keys are encounters. Those for instance clear the current prompt. The remaining parts of the sequence are then visible. This changeset fixes the issue by skipping the entire force-to-ground code whenever we saw at least 1 win32-input-mode sequence. Related to #16343 ## Validation Steps Performed * Host a ConPTY inside ConPTY (= double the trouble) with cmd.exe * Paste random amounts of text * In the old code spurious `[..._` strings are seen * In the new code they're consistently gone ✅
Even with the previous fixes we still randomly encounter win32- input-mode sequences that are broken up in exactly such a way that e.g. lone escape keys are encounters. Those for instance clear the current prompt. The remaining parts of the sequence are then visible. This changeset fixes the issue by skipping the entire force-to-ground code whenever we saw at least 1 win32-input-mode sequence. Related to #16343 ## Validation Steps Performed * Host a ConPTY inside ConPTY (= double the trouble) with cmd.exe * Paste random amounts of text * In the old code spurious `[..._` strings are seen * In the new code they're consistently gone ✅ (cherry picked from commit bc18348) Service-Card-Id: 91337332 Service-Version: 1.19
We're pretty sure this was fixed, just not actually marked as closed. |
Windows Terminal version
1.19.2682.0
Windows build number
No response
Steps to reproduce
(I can send
sfpcopy.exe
(the recommended tool for this) on request if anyone wants to test this.)ReadConsoleInputW
, for instance: https://gist.github.com/lhecker/43e562d5a1370d2582bb5d6eed4e4f3eExpected Behavior
Input is preserved as it is typed.
Actual Behavior
There are two independent issues at play here:
ConhostInternalGetSet::ReturnResponse
translates a VT response into a sequence ofINPUT_RECORD
s and callsInputBuffer::Write
. That one callsTerminalInput::HandleKey
which translatesKEY_EVENT
s type into Win32 input sequences. In other words, VT responses are being double-encoded in conhost.At some point when ConPTY starts,
VtIo::StartIfNeeded()
is called which callsRequestCursor()
under WSL (="\x1b[6n"
request) and waits for a response. ConPTY now deadlocks because it won't double-decode the response.Even with that issue fixed, there's still a change in behavior, as the Win32 console application still receives undecoded Win32 input sequences as a series of
INPUT_RECORD
s. I.e. typing "a" yields 2 dozenINPUT_RECORD
s.Note to self:
The text was updated successfully, but these errors were encountered: