-
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
Merge the TerminalDispatch and AdaptDispatch classes #13024
Conversation
i am so excited |
50c87e3
to
2a9a210
Compare
Yeah, me too. But be aware that the terminal side isn't fully functional as a standalone VT implementation yet. I think the two big things outstanding now are the |
We should merge this PR before we get to #13025. |
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 PR was surprisingly easy to review! Only TerminalApi.cpp
was a bit more complex...
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, I must admit that I reviewed this while it was still in draft . . . and I am still totally ready to sign off. I'll keep up to date on individual commits as they come in.
If anything, I've gotten more excited about this change. Passthrough mode is going to be pretty fun, sure, but this is going to unfetter us in a bunch of ways:
- I'm going to yeet TerminalAzBridge into the sun once we fill out some of those TODOs in Terminal's TerminalApi
- In theory, we could work on DRCS and Sixel support without having to figure out how they transit ConPTY up front, which will let us parallelize that work
- Eventually, we may want to split the
terminal/adapter
directory intoterminal/adapter
(the shared bits) andhost/*adapter*
(the conhost-specific bits, likeInteractDispatch
, that depend on GCI and ServiceLocator)
Technically it's ready for review - I don't have plans to add more code - I'm just still doing some testing, and I want to add some copy for the validation section of the commit message. And yeah Sixel is probably my number one reason for doing this. I've been putting off committing something because I didn't want to add yet another feature that only worked in conhost, but if I can get it to work in Terminal with the passthrough mode (even if imperfectly), I'd feel a lot better about 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.
Knocked it out of the park, as always. Thank you, @j4james
Meh, I was 40/42 on this so far, but I'm too excited. I didn't find anything so far. I trust the other guys, so: @msftbot merge this in 1 minute |
Hello @zadjii-msft! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
## Summary of the Pull Request When `TerminalDispatch` was merged with `AdaptDispatch` in PR #13024, that broke the Terminal's `EraseAll` operation in the alt buffer. The problem was that the `EraseAll` implementation makes a call to `SetViewportPosition` which wasn't taking the alt buffer into account, and thus modified the main viewport instead. This PR corrects that mistake. If we're in the alt buffer, the `SetViewportPosition` method now does nothing, since the alt buffer viewport should always be at 0,0. ## References This was a regression introduced in PR #13024. ## PR Checklist * [x] Closes #13038 * [x] CLA signed. * [ ] Tests added/passed * [ ] Documentation updated. * [ ] Schema updated. * [x] I've discussed this with core contributors already. Issue number where discussion took place: #13038 ## Validation Steps Performed I've confirmed that the test case reported in issue #13038 is no longer failing. I've also made sure the `ED 2` and `ED 3` sequences are still working correctly in the main buffer.
🎉 Handy links: |
In #13024, we removed `Terminal::GetCursorPosition` from TerminalCore. This has been widely regarded as a good move. Now, you might rightly be wondering: why didn't compilation immediately fail? Well. It turns out that there were _two_ copies of `GetCursorPosition`. One for `const Terminal`, and one for `Terminal`. This is important. `Terminal::GetCursorPosition()` returned the cursor position relative to the viewport. `Terminal::GetCursorPosition() const`, however, returns the cursor position in absolute. We removed the non-`const` one. Fortunately, thanks to the lookup rules for `const`-qualified members, this didn't matter. Code that called `GetCursorPosition()` still called `GetCursorPosition()`, and everything was fine. Except that part about the relative coordinates. That was not fine. The TSF control is the _only_ consumer of `ControlCore.CursorPosition`, and that was the _only_ consumer of relative-`GetCursorPosition()`. This commit restores equilibrium by introducing a new `GetViewportRelativeCursorPosition()` member to `Terminal` and switching over the only consumer of relative cursor position to use it. Closes #13769.
In #13024, we removed `Terminal::GetCursorPosition` from TerminalCore. This has been widely regarded as a good move. Now, you might rightly be wondering: why didn't compilation immediately fail? Well. It turns out that there were _two_ copies of `GetCursorPosition`. One for `const Terminal`, and one for `Terminal`. This is important. `Terminal::GetCursorPosition()` returned the cursor position relative to the viewport. `Terminal::GetCursorPosition() const`, however, returns the cursor position in absolute. We removed the non-`const` one. Fortunately, thanks to the lookup rules for `const`-qualified members, this didn't matter. Code that called `GetCursorPosition()` still called `GetCursorPosition()`, and everything was fine. Except that part about the relative coordinates. That was not fine. The TSF control is the _only_ consumer of `ControlCore.CursorPosition`, and that was the _only_ consumer of relative-`GetCursorPosition()`. This commit restores equilibrium by introducing a new `GetViewportRelativeCursorPosition()` member to `Terminal` and switching over the only consumer of relative cursor position to use it. Closes #13769.
In #13024, we removed `Terminal::GetCursorPosition` from TerminalCore. This has been widely regarded as a good move. Now, you might rightly be wondering: why didn't compilation immediately fail? Well. It turns out that there were _two_ copies of `GetCursorPosition`. One for `const Terminal`, and one for `Terminal`. This is important. `Terminal::GetCursorPosition()` returned the cursor position relative to the viewport. `Terminal::GetCursorPosition() const`, however, returns the cursor position in absolute. We removed the non-`const` one. Fortunately, thanks to the lookup rules for `const`-qualified members, this didn't matter. Code that called `GetCursorPosition()` still called `GetCursorPosition()`, and everything was fine. Except that part about the relative coordinates. That was not fine. The TSF control is the _only_ consumer of `ControlCore.CursorPosition`, and that was the _only_ consumer of relative-`GetCursorPosition()`. This commit restores equilibrium by introducing a new `GetViewportRelativeCursorPosition()` member to `Terminal` and switching over the only consumer of relative cursor position to use it. Closes #13769. Backport of #13785.
In #13024, we removed `Terminal::GetCursorPosition` from TerminalCore. This has been widely regarded as a good move. Now, you might rightly be wondering: why didn't compilation immediately fail? Well. It turns out that there were _two_ copies of `GetCursorPosition`. One for `const Terminal`, and one for `Terminal`. This is important. `Terminal::GetCursorPosition()` returned the cursor position relative to the viewport. `Terminal::GetCursorPosition() const`, however, returns the cursor position in absolute. We removed the non-`const` one. Fortunately, thanks to the lookup rules for `const`-qualified members, this didn't matter. Code that called `GetCursorPosition()` still called `GetCursorPosition()`, and everything was fine. Except that part about the relative coordinates. That was not fine. The TSF control is the _only_ consumer of `ControlCore.CursorPosition`, and that was the _only_ consumer of relative-`GetCursorPosition()`. This commit restores equilibrium by introducing a new `GetViewportRelativeCursorPosition()` member to `Terminal` and switching over the only consumer of relative cursor position to use it. Closes #13769.
In #13024, we removed `Terminal::GetCursorPosition` from TerminalCore. This has been widely regarded as a good move. Now, you might rightly be wondering: why didn't compilation immediately fail? Well. It turns out that there were _two_ copies of `GetCursorPosition`. One for `const Terminal`, and one for `Terminal`. This is important. `Terminal::GetCursorPosition()` returned the cursor position relative to the viewport. `Terminal::GetCursorPosition() const`, however, returns the cursor position in absolute. We removed the non-`const` one. Fortunately, thanks to the lookup rules for `const`-qualified members, this didn't matter. Code that called `GetCursorPosition()` still called `GetCursorPosition()`, and everything was fine. Except that part about the relative coordinates. That was not fine. The TSF control is the _only_ consumer of `ControlCore.CursorPosition`, and that was the _only_ consumer of relative-`GetCursorPosition()`. This commit restores equilibrium by introducing a new `GetViewportRelativeCursorPosition()` member to `Terminal` and switching over the only consumer of relative cursor position to use it. Closes #13769. (cherry picked from commit 2dedc9a) Service-Card-Id: 85131461 Service-Version: 1.15
Summary of the Pull Request
This PR replaces the
TerminalDispatch
class with theAdaptDispatch
class from conhost, so we're no longer duplicating the VT functionality in two places. It also gives us a more complete VT implementation on the Terminal side, so it should work better in pass-through mode.References
This is essentially part two of PR #12703.
PR Checklist
Detailed Description of the Pull Request / Additional comments
The first thing was to give the
ConGetSet
interface a new name, since it's now no longer specific to conhost. I went withITerminalApi
, since that was the equivalent interface on the terminal side, and it still seemed like a generic enough name. I also changed the way the api is managed by theAdaptDispatch
class, so it's now stored as a reference rather than aunique_ptr
, which more closely matches the way theTerminalDispatch
class worked.I then had to make sure that
AdaptDispatch
actually included all of the functionality currently inTerminalDispatch
. That meant copying across the code for bracketed paste mode, the copy to clipboard operation, and the various ConEmu OSC operations. This also required a few new methods to theConGetSet
/ITerminalApi
interface, but for now these are just stubs in conhost.Then there were a few thing in the api interface that needed cleaning up. The
ReparentWindow
method doesn't belong there, so I've moved that intoPtySignalInputThread
class. And theWriteInput
method was too low-level for the Terminal requirements, so I've replaced that with aReturnResponse
method which takes awstring_view
.It was then a matter of getting the
Terminal
class to implement all the methods in the newITerminalApi
interface that it didn't already have. This was mostly mapping to existing functionality, but there are still a number of methods that I've had to leave as stubs for now. However, what we have is still good enough that I could then nuke theTerminalDispatch
class from the Terminal code and replace it withAdaptDispatch
.One oddity that came up in testing, though, was the
AdaptDispatch
implementation ofEraseAll
would push a blank line into the scrollback when called on an empty buffer, whereas the previous terminal implementation did not. That caused problems for the conpty connection, because one of the first things it does on startup is send anED 2
sequence. I've now updated theAdaptDispatch
implementation to match the behavior of the terminal implementation in that regard.Another problem was that the terminal implementation of the color table commands had special handling for the background color to notify the application window that it needed to repaint the background. I didn't want to have to push the color table operations through the
ITerminalApi
interface, so I've instead moved the handling of the background update into the renderer, initiated by a flag on theTriggerRefreshAll
method.Validation Steps Performed
Surprisingly this PR didn't require a lot of changes to get the unit tests working again. There were just a few methods used from the original
ITerminalApi
that have now been removed, and which needed an equivalent replacement. Also the updated behavior of theEraseAll
method in conhost resulted in a change to the expected cursor position in one of the screen buffer tests.In terms of manual testing, I've tried out all the different shells in Windows Terminal to make sure there wasn't anything obviously wrong. And I've run a bunch of the tests from vttest to try and get a wider coverage of the VT functionality, and confirmed everything still works at least as well as it used to. I've also run some of my own tests to verify the operations that had to be copied from
TerminalDispatch
toAdaptDispatch
.