-
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
Add support for Double-Height and Double-Width text to Windows Terminal #11595
Comments
There are two aspects to this:
So I probably should take a stab at part 1 at some point, because we're going to need that either way. I'm less certain about part 2, but that's not to say it won't happen. At the moment I'm working on a bunch of other things, though, and I'm not the fastest of coders, but there's no reason why someone else couldn't take it on. |
Yep, I pretty much have nothing to add. If you'd like to take a stab at it, we'd love the help 😄 |
This PR adds support for the VT line rendition attributes in the DirectX renderer, which allows for double-width and double-height line renditions. Line renditions were first implemented in conhost (with the GDI renderer) in PR #8664. Supporting them in the DX renderer now is a small step towards #11595. The DX implementation is very similar to the GDI one. When a particular line rendition is requested, we create a transform that is applied to the render target. And in the case of double-height renditions, we also initialize some clipping offsets to allow for the fact that we only render half of a line at a time. One additional complication exists when drawing the cursor, which requires a two part process where it first renders to a command list, and then draw the command list in a second step. We need to temporarily reset the transform in that first stage otherwise it ends up being applied twice. I've manually tested the renderer in conhost by setting the `UseDx` registry entry and confirmed that it passes the _Vttest_ double-size tests as well as several of my own tests. I've also checked that the renderer can now handle horizontal scrolling, which is a feature we get for free with the transforms.
FYI, I've been playing around with part two of this recently, and I've got a solution which I think is not too terrible. By default it won't affect the conpty output at all, but once you write anything with a double size, it switches to a mode where every line will be output with a line rendition prefix (it has to do this because it has no easy way of tracking the line rendition state in the client terminal). It remains in this mode until you do something like a cls, which resets everything to single width, and then it can safely switch back the initial mode. So it's a bit hacky, and not exactly optimal when you're using double size text, but that's still better than nothing. And for anyone that isn't using line attributes, it shouldn't impact them at all. What do you think? Would you be happy to accept a PR with this approach? |
@j4james
... as long as you are satisfied. (I know you're actually fighting to get as close to the original behavior as possible.)
Sorry for my ignorance about graphics. This doesn't mean that the whole viewport is turned to double size incl. the existing text, right?
I hope something less drastic would work, too 😆
I guess you didn't ask me since my approval is worth nothing. However, yes I would. |
No, it's not as bad as that. Each line has its own state - could be single width, double width, the top half of a double height line, or the bottom half of a double height line. What I mean is that we have to write out that line rendition state every time we refresh a line. So even if everything is single width, you'll still see all the lines prefixed with a single-width sequence (
It's basically any event that will force the full viewport to repaint. Clearing the screen is just the most common case. Some forms of scrolling could probably trigger it too. I suspect all of these cases are likely to be fairly drastic though. That said, I would have thought most times you're using double size text would be in a full screen application from which you'd exit with a clear screen, or alt buffer switch. And if not, worst case is you're getting a bunch of unnecessary 3-byte prefixes in your output for a while. If this turns out to be a massive performance issue, we can always look at optimising it further in the future. I just didn't want to overcomplicate the initial fix if it wasn't absolutely necessary. And long term I'm still hoping we'll get full passthrough mode working, but that seems to be stalled at the moment with miniksa gone. |
Haha, I've been under the impression that cls was necessary for turning back to default size 😄 Apparently I missed the fact that you've been only talking about the additional line state. I don't expect this to be a big performance issue btw.
Not necessarily. It's a nice way to emphasize a heading to separate it from body text. |
I'm actually really cool with this solution. ConPTY is an assemblage of tricks to get things "just right" (barring the instances where it is neither "just" nor "right") so this is totally in line with that. We can keep it until we either make ConPTY better or obviate the need for it. :) |
This PR introduces a mechanism for passing through line rendition attributes to the conpty client, so we can support double-width and double-height text in Windows Terminal. Line renditions were first implemented in conhost (with the GDI renderer) in PR #8664, and were implemented in the DX renderer in PR #13102. By default this won't add any additional overhead to the conpty output, but as soon as there is any usage of double-size text, we switch to a mode in which every line output will be prefixed with a line rendition sequence. This is to ensure that the line attributes in the client terminal are always in sync with the host. Since this does add some overhead to the conpty output, we'd prefer not to remain in this mode longer than necessary. So whenever there is a full repaint of the entire viewport, we check to see if all of the lines are single-width. If that is the case, we can then safely skip the line rendition sequences in future updates. One other small optimization is when the conpty update is only writing out a single character (this is something we already check for). When that is the case, we can safely skip the line rendition prefix, because a single character update should never include a change of the line rendition. ## Validation Steps Performed I've manually tested that Windows Terminal now passes the double-size tests in _Vttest_, and also confirmed various edge cases are working correctly in my own double-size tests. Closes #11595
🎉This issue was addressed in #13933, which has now been successfully released as Handy links: |
Description of the new feature/enhancement
At least Windows 11 ships with a conhost version which supports
DECDHL
andDECDWL
. I'm used to telling people who are asking for a better VT support something like "Hey, check out the shiny Windows Terminal. It supports quite some escape sequences that the console host does not, and you can even set it as default terminal app." Now I have to add "... unless you're looking for double height/width text where you explicitly have to use the good ol' console." This feels rather odd 😄Proposed technical implementation details (optional)
Consider adding this feature to Windows Terminal.
However, from what I've read, the current architecture of conpty doesn't seem to be ready yet. So, I suppose a lot of refactoring would be necessary to get to the preconditions 😧
Related: #7865, #8664
cc @j4james
The text was updated successfully, but these errors were encountered: