Add support for Double-Height and Double-Width text to Windows Terminal #15672

Closed
opened 2026-01-31 04:45:08 +00:00 by claunia · 8 comments
Owner

Originally created by @german-one on GitHub (Oct 24, 2021).

Description of the new feature/enhancement

At least Windows 11 ships with a conhost version which supports DECDHL and DECDWL. 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

Originally created by @german-one on GitHub (Oct 24, 2021). # Description of the new feature/enhancement At least Windows 11 ships with a conhost version which supports `DECDHL` and `DECDWL`. 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
Author
Owner

@j4james commented on GitHub (Oct 24, 2021):

There are two aspects to this:

  1. We need to get the DX renderer to support it, and that may be a good first step, because that can actually be tested in conhost now without involving conpty (thanks to #10770). The main reason I've been putting that off is because the double-width attributes touch on aspects of the DX renderer that are fundamentally broken, and it annoys me every time I look at it. Those issues aside, it may not be that much work, but I'm no expert on DX.

  2. Once the renderer is in place, we need to get it working over conpty. I had a hacky idea for that which shouldn't be that complicated, but I'm not certain it would work, and in the ideal world this would all be solved by the conpty passthrough mode (#1173). Since that's actually starting to look like it may be a real possibility, I'd rather not waste time on the hacky solution, and instead concentrate on the things that'll help make passthrough more feasible.

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.

@j4james commented on GitHub (Oct 24, 2021): There are two aspects to this: 1. We need to get the DX renderer to support it, and that may be a good first step, because that can actually be tested in conhost now without involving conpty (thanks to #10770). The main reason I've been putting that off is because the double-width attributes touch on aspects of the DX renderer that are fundamentally broken, and it annoys me every time I look at it. Those issues aside, it may not be that much work, but I'm no expert on DX. 2. Once the renderer is in place, we need to get it working over conpty. I had a hacky idea for that which shouldn't be that complicated, but I'm not certain it would work, and in the ideal world this would all be solved by the conpty passthrough mode (#1173). Since that's actually starting to look like it may be a real possibility, I'd rather not waste time on the hacky solution, and instead concentrate on the things that'll help make passthrough more feasible. 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.
Author
Owner

@zadjii-msft commented on GitHub (Oct 25, 2021):

Yep, I pretty much have nothing to add. If you'd like to take a stab at it, we'd love the help 😄

@zadjii-msft commented on GitHub (Oct 25, 2021): Yep, I pretty much have nothing to add. If you'd like to take a stab at it, we'd love the help 😄
Author
Owner

@j4james commented on GitHub (Sep 4, 2022):

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 commented on GitHub (Sep 4, 2022): 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?
Author
Owner

@german-one commented on GitHub (Sep 4, 2022):

@j4james
I second your ...

that's still better than nothing

... as long as you are satisfied. (I know you're actually fighting to get as close to the original behavior as possible.)

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

Sorry for my ignorance about graphics. This doesn't mean that the whole viewport is turned to double size incl. the existing text, right?

It remains in this mode until you do something like a cls

I hope something less drastic would work, too 😆

Would you be happy to accept a PR with this approach?

I guess you didn't ask me since my approval is worth nothing. However, yes I would.

@german-one commented on GitHub (Sep 4, 2022): @j4james I second your ... > that's still better than nothing ... as long as you are satisfied. (I know you're actually fighting to get as close to the original behavior as possible.) <br> > 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 Sorry for my ignorance about graphics. This doesn't mean that the whole viewport is turned to double size incl. the existing text, right? <br> > It remains in this mode until you do something like a cls I hope something less drastic would work, too 😆 <br> > Would you be happy to accept a PR with this approach? I guess you didn't ask me since my approval is worth nothing. However, yes I would.
Author
Owner

@j4james commented on GitHub (Sep 4, 2022):

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

Sorry for my ignorance about graphics. This doesn't mean that the whole viewport is turned to double size incl. the existing text, right?

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 (\e#5), until the system figures out that it's safe to stop doing that.

It remains in this mode until you do something like a cls

I hope something less drastic would work, too 😆

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.

@j4james commented on GitHub (Sep 4, 2022): > > 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 > > Sorry for my ignorance about graphics. This doesn't mean that the whole viewport is turned to double size incl. the existing text, right? 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 (`\e#5`), until the system figures out that it's safe to stop doing that. > > It remains in this mode until you do something like a cls > > I hope something less drastic would work, too 😆 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.
Author
Owner

@german-one commented on GitHub (Sep 5, 2022):

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.

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.

Not necessarily. It's a nice way to emphasize a heading to separate it from body text.

@german-one commented on GitHub (Sep 5, 2022): 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. > 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. Not necessarily. It's a nice way to emphasize a heading to separate it from body text.
Author
Owner

@DHowett commented on GitHub (Sep 6, 2022):

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. :)

@DHowett commented on GitHub (Sep 6, 2022): 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. :)
Author
Owner

@ghost commented on GitHub (Jan 24, 2023):

:tada:This issue was addressed in #13933, which has now been successfully released as Windows Terminal Preview v1.17.1023.🎉

Handy links:

@ghost commented on GitHub (Jan 24, 2023): :tada:This issue was addressed in #13933, which has now been successfully released as `Windows Terminal Preview v1.17.1023`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.17.1023) * [Store Download](https://www.microsoft.com/store/apps/9n8g5rfz9xk3?cid=storebadge&ocid=badge)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#15672