-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
ConPTY: Flush unhandled sequences to the buffer #17741
Conversation
if (!ok) | ||
{ | ||
FlushToTerminal(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the important bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we flush it even if it made us throw an exception?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's an edge case that's not too important, at least initially. There shouldn't be any exceptions unless it's an OOM or similar exceptional issue. Failure to parse a sequence should never raise an exception IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Largely mechanical, but this does change how passed-through VT input is encoded (from only keydown events with no scancode to full key events as though a human typed them on a keyboard), and I want to know whether that's scary.
You also got rid of most of the users of RETURN_BOOL_IF_FALSE
, which is a macro of our own creation. Want to go the rest of the way and kill it, too?
if (!ok) | ||
{ | ||
FlushToTerminal(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we flush it even if it made us throw an exception?
(I'd love to see a bit more validation on WSL as well, and I suspect @j4james will have some feelings about this! I'm in favor of the architectural shift.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still need to look at the InputStateMachine
. Just wanted to get the return value refactoring out of the way first. Btw, I'm very happy with this change - I was actually about to propose doing it myself.
Thank you so much for the exhaustive review @j4james! |
FYI I reverted that bit.
✅
I'm still somewhat squirmish about the change, as the bool returns were used in tests. On the other hand, I feel like there's better ways to test our parser than via bool returns (e.g. by testing side effects). I've tried reproducing any issues under WSL and couldn't find anything immediately obvious. It seemed fine with various key combinations and in vttest. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's go wild. We're already blowing up the world by removing conpty, so let's just go all-in.
I've been doing some testing of this branch, and there are still a bunch of queries that don't seem to work at the cmd prompt which previously used to work
There are many more, but I think they are all just variations of the above 3 cases. I'm also now seeing some issues with reports in a WSL shell, which I'm almost sure were working before. I think it's all just DCS reports. For example, |
|
@@ -452,9 +458,6 @@ bool InputStateMachineEngine::ActionCsiDispatch(const VTID id, const VTParameter | |||
case CsiActionCodes::CursorBackTab: | |||
_WriteSingleKey(VK_TAB, SHIFT_PRESSED); | |||
return true; | |||
case CsiActionCodes::DTTERM_WindowManipulation: | |||
_pDispatch->WindowManipulation(parameters.at(0), parameters.at(1), parameters.at(2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean we can unimplement InteractDispatch::WindowManipulation
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still used in OutputStateMachineEngine
isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but that goes through adaptDispatch
.
The one from ISM goes through InteractDispatch
.
And upon looking at InteractDispatch::WindowManipulation
, I fear that we actually might be using it (window manipulation) to help conpty's window transition through states ......
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is really just like 6 lines of meat and 1200 lines of meh
@@ -728,14 +726,14 @@ void StateMachine::_ActionDcsDispatch(const wchar_t wch) | |||
|
|||
const auto success = _SafeExecute([=]() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this lambda, combined with "the important bit" below, is like, the actual PR here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. I apologize for the complete mess of this PR.
Initially I thought this would be easy, but then the sunken cost fallacy hit me.
#17510 made it so that VT requests like DA1 are passed through to the
hosting terminal and so conhost stopped responding to them on its own.
But since our input parser doesn't support proper passthrough (yet),
it swallowed the response coming from the terminal.
To solve this issue, this PR repurposes the existing boolean return
values to indicate to the parser whether the current sequence should
be flushed to the dispatcher as-is. The output parser always returns
true (success) and leaves its pass-through handler empty, while the
input parser returns false for sequences it doesn't expect.
Validation Steps Performed
Ctrl+[
,[
,c
,Enter
(=^[[c
= DA1 request)