Should the bold/bright attribute apply to SGR 38/48 indexed colors? #7448

Closed
opened 2026-01-31 01:04:22 +00:00 by claunia · 10 comments
Owner

Originally created by @j4james on GitHub (Apr 17, 2020).

Environment

Windows build number: Version 10.0.18362.657
Windows Terminal version (if applicable): 0.10.781.0

Steps to reproduce

  1. Open a bash shell in conhost.
  2. Execute printf "\e[0;38;5;3mDARK \e[1mBRIGHT?\e[m\n"
  3. Open a bash shell in Window Terminal.
  4. Execute printf "\e[0;38;5;3mDARK \e[1mBRIGHT?\e[m\n"

Expected behavior

Both terminals should produce the same output showing the same colors.

Actual behavior

Conhost displays the "BRIGHT?" text in the same dark shade as the "DARK" text. Windows Terminal displays it brighter.

image

In some ways this could be considered a narrowing bug (issue #2661), because one reason for the difference is that conhost converts the indexed color into an RGB value before storing it, while the Windows Terminal doesn't. And the bold/bright attribute has no effect on RGB colors, but does affect indexed colors.

That said, I don't think the WT implementation is correct, so fixing the "narrowing" issue in conhost is just going to make both of them wrong. There is some room for interpretation here, but I've been looking at how other terminals handle this, and AFAICT most (including XTerm and VTE) will only apply the brightness attribute to the 8 basic colors, and not the 256 indexed colors from SGR 38/48.

So this is really a question as much as it is a bug report. Which behavior do we want to follow here? Because the answer to that is going to affect how we address issue #2661.

Originally created by @j4james on GitHub (Apr 17, 2020). # Environment Windows build number: Version 10.0.18362.657 Windows Terminal version (if applicable): 0.10.781.0 # Steps to reproduce 1. Open a bash shell in conhost. 2. Execute `printf "\e[0;38;5;3mDARK \e[1mBRIGHT?\e[m\n"` 3. Open a bash shell in Window Terminal. 4. Execute `printf "\e[0;38;5;3mDARK \e[1mBRIGHT?\e[m\n"` # Expected behavior Both terminals should produce the same output showing the same colors. # Actual behavior Conhost displays the "BRIGHT?" text in the same dark shade as the "DARK" text. Windows Terminal displays it brighter. ![image](https://user-images.githubusercontent.com/4181424/79517396-fa614980-8045-11ea-8485-2c6ade86a266.png) In some ways this could be considered a narrowing bug (issue #2661), because one reason for the difference is that conhost converts the indexed color into an RGB value before storing it, while the Windows Terminal doesn't. And the bold/bright attribute has no effect on RGB colors, but does affect indexed colors. That said, I don't think the WT implementation is correct, so fixing the "narrowing" issue in conhost is just going to make both of them wrong. There is some room for interpretation here, but I've been looking at how other terminals handle this, and AFAICT most (including XTerm and VTE) will only apply the brightness attribute to the 8 basic colors, and not the 256 indexed colors from SGR 38/48. So this is really a question as much as it is a bug report. Which behavior do we want to follow here? Because the answer to that is going to affect how we address issue #2661.
Author
Owner

@DHowett-MSFT commented on GitHub (Apr 17, 2020):

The WT behavior is a follow-on from #2661, actually. Here's what's coming out of the debug tap:

␛[33mDARK␣␛[1mBRIGHT?

We successfully preserve "the user only wants bright to be enabled for the second run", but that brightness applies to 33. The behavior with 33 is correct, but we're only getting the 33 because of #2661.

If #2661 is fixed, I think we'll get...

␛[38;5;3mDARK␣␛[1mBRIGHT?

and WT won't attempt to brighten it.

@DHowett-MSFT commented on GitHub (Apr 17, 2020): The WT behavior is a follow-on from #2661, actually. Here's what's coming out of the debug tap: `␛[33mDARK␣␛[1mBRIGHT?` We successfully preserve "the user only wants bright to be enabled for the second run", but that brightness applies to `33`. The behavior with _33_ is correct, but we're only getting the 33 because of #2661. If #2661 is fixed, I think we'll get... `␛[38;5;3mDARK␣␛[1mBRIGHT?` and WT won't attempt to brighten it.
Author
Owner

@j4james commented on GitHub (Apr 17, 2020):

If #2661 is fixed, I think we'll get...

␛[38;5;3mDARK␣␛[1mBRIGHT?

and WT won't attempt to brighten it.

Hmmm... I could have sworn I was getting ␛[38;5;3m when I looked at this in the debugger, but I must have been mistaken. So my test case doesn't actually prove anything, but the problem still wouldn't be fixed by #2661, because both ␛[33m and ␛[38;5;3m follow the same code path.

The former calls SetTextForegroundIndex from here:
d711d731d7/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp (L204)

and the latter calls the same method from here:
d711d731d7/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp (L124)

So either way you're going to end up with an indexed color, and any indexed color less than 8 gets brightened.

@j4james commented on GitHub (Apr 17, 2020): > If #2661 is fixed, I think we'll get... > > `␛[38;5;3mDARK␣␛[1mBRIGHT?` > > and WT won't attempt to brighten it. Hmmm... I could have sworn I was getting `␛[38;5;3m` when I looked at this in the debugger, but I must have been mistaken. So my test case doesn't actually prove anything, but the problem still wouldn't be fixed by #2661, because both `␛[33m` and `␛[38;5;3m` follow the same code path. The former calls `SetTextForegroundIndex` from here: https://github.com/microsoft/terminal/blob/d711d731d7d00259b2e0fe5847928c9f1c1121ed/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp#L204 and the latter calls the same method from here: https://github.com/microsoft/terminal/blob/d711d731d7d00259b2e0fe5847928c9f1c1121ed/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp#L124 So either way you're going to end up with an indexed color, and any indexed color less than 8 gets brightened.
Author
Owner

@DHowett-MSFT commented on GitHub (Apr 17, 2020):

oh, you actually used 38;5;3. Yeah, that's not quite right eh. Conhost gets this right, so we should too. Thanks

@DHowett-MSFT commented on GitHub (Apr 17, 2020): _oh, you actually used `38;5;3`._ Yeah, that's not quite right eh. Conhost gets this right, so we should too. Thanks
Author
Owner

@DHowett-MSFT commented on GitHub (Apr 17, 2020):

Just another bug for the pile of bugs that we're growing because we have two AdaptDispatch implementations. Augh.

@DHowett-MSFT commented on GitHub (Apr 17, 2020): Just another bug for the pile of bugs that we're growing because we have _two AdaptDispatch_ implementations. Augh.
Author
Owner

@egmontkob commented on GitHub (Apr 17, 2020):

and AFAICT most (including XTerm and VTE) will only apply the brightness attribute to the 8 basic colors, and not the 256 indexed colors from SGR 38/48.

Xterm 331 changed this. See https://gitlab.gnome.org/GNOME/vte/-/issues/149.

@egmontkob commented on GitHub (Apr 17, 2020): > and AFAICT most (including XTerm and VTE) will only apply the brightness attribute to the 8 basic colors, and not the 256 indexed colors from SGR 38/48. Xterm 331 changed this. See https://gitlab.gnome.org/GNOME/vte/-/issues/149.
Author
Owner

@egmontkob commented on GitHub (Apr 17, 2020):

Just wondering: Before cleaning this up, don't you guys wish to

  • implement support for bold font weight (#109),
  • join Kitty, VTE, Alacritty in making SGR 1 stand for bold font only, without brightening the color, in order to push the world into a much cleaner state (#3613)?
@egmontkob commented on GitHub (Apr 17, 2020): Just wondering: Before cleaning this up, don't you guys wish to - implement support for bold font weight (#109), - join Kitty, VTE, Alacritty in making SGR 1 stand for bold font only, without brightening the color, in order to push the world into a much cleaner state (#3613)?
Author
Owner

@j4james commented on GitHub (Apr 18, 2020):

Xterm 331 changed this. See https://gitlab.gnome.org/GNOME/vte/-/issues/149.

I think that change must have been reverted, because the version I tested was definitely more recent than that. And I've now just rebuilt from the latest source (version 354), and that still does not brighten SGR 38 colors.

  • implement support for bold font weight (#109),

Not something I'm interested in doing.

  • join Kitty, VTE, Alacritty in making SGR 1 stand for bold font only, without brightening the color

I can put up with a lot of things, but the day we break the legacy brightness functionality is the day I stop contributing to this project and manage my own fork. Hopefully that'll never happen.

That said, I was thinking a nice compromise would be to treat SGR 1 as bright (but not bold) for "legacy" colors, and as a bold font (but not bright) for the extended ITU colors. That remains backwards compatible with the legacy behaviour, while still allowing for a bold font for those that do want it. And as far as I can tell, this is the default setting for Mintty, so we wouldn't be alone if we went that route.

@j4james commented on GitHub (Apr 18, 2020): > Xterm 331 changed this. See https://gitlab.gnome.org/GNOME/vte/-/issues/149. I think that change must have been reverted, because the version I tested was definitely more recent than that. And I've now just rebuilt from the latest source (version 354), and that still does not brighten SGR 38 colors. > * implement support for bold font weight (#109), Not something I'm interested in doing. > * join Kitty, VTE, Alacritty in making SGR 1 stand for bold font only, without brightening the color I can put up with a lot of things, but the day we break the legacy brightness functionality is the day I stop contributing to this project and manage my own fork. Hopefully that'll never happen. That said, I was thinking a nice compromise would be to treat SGR 1 as bright (but not bold) for "legacy" colors, and as a bold font (but not bright) for the extended ITU colors. That remains backwards compatible with the legacy behaviour, while still allowing for a bold font for those that do want it. And as far as I can tell, this is the default setting for Mintty, so we wouldn't be alone if we went that route.
Author
Owner

@egmontkob commented on GitHub (Apr 18, 2020):

I think that change must have been reverted

You're right, version 348 reverts the change. I didn't know this, thanks for the update! It's not mentioned in the changelog, though. Anyway, I think we can conclude that the other behavior was accidental.

implement support for bold font weight (#109),
Not something I'm interested in doing.

I personally don't care if it's you or someone else, I fully respect if you don't care about it; but if WT wishes to provide a decent, modern Unix-y terminal emulation experience then it really needs to have bold typeface (and while at it, italic too). I'd personally set it as 1.0-blocker.

IMO it doesn't make too much sense to talk about how the SGR codes exactly map to colors, without having bold (as in heavier font being displayed) support for now; and then at one point re-evaluate all of this with bold in the game. I'd find it much cleaner to have bold first, and then discuss how to resolve the SGR bold vs. colors nightmare.

but the day we break the legacy brightness functionality is the day I stop contributing to this project and manage my own fork. Hopefully that'll never happen.

I hope that too, first, because it would be a bad product decision, and second, because the team and the users would miss your truly valuable contributions!

I didn't repeat it here, but I think I made it clear in another thread that I do not want this behavior the only one; I do not even ask for it to be the default. However, modern Unix-y behavior with color schemes like Solarized require a mode where SGR 1 doesn't temper with the colors. It needs to be one of the modes supported by WT – along with, of course, other modes that you personally care about more, and are imporant for Windows backwards compatibility.

I was thinking a nice compromise would be to treat SGR 1 as bright (but not bold) for "legacy" colors, and as a bold font (but not bright) for the extended ITU colors.

I disagree with this. This doesn't clean up the current mess at all, just pushes it slightly elsewhere. Also note that terminfo-based apps (included ncurses-based ones, too) only have 256 indices to pick a color from, and they have no control over whether indices 0..15 map to the legacy or to the extended escape sequences. Some terminfo versions/entries do the legacy one, some do the 256-color one. Terminfo and ncurses expose the concept of 256 palette colors altogether, not 16+256 ones. So such apps would have no control whatsoever about which actual look they can achieve.

The only reasonable way forward, as Kitty, VTE and Alacritty (in this chronological order) already did as their default, and is available as an option in xterm, urxvt and probably many others too, is to fully separate bold typeface from the colors. Again, as an option, with other backwards compatibility options provided too, as the given project finds appropriate.

@egmontkob commented on GitHub (Apr 18, 2020): > I think that change must have been reverted You're right, version 348 reverts the change. I didn't know this, thanks for the update! It's not mentioned in the changelog, though. Anyway, I think we can conclude that the other behavior was accidental. > > implement support for bold font weight (#109), > Not something I'm interested in doing. I personally don't care if it's you or someone else, I fully respect if you don't care about it; but if WT wishes to provide a decent, modern Unix-y terminal emulation experience then it really needs to have bold typeface (and while at it, italic too). I'd personally set it as 1.0-blocker. IMO it doesn't make too much sense to talk about how the SGR codes exactly map to colors, without having bold (as in heavier font being displayed) support for now; and then at one point re-evaluate all of this with bold in the game. I'd find it much cleaner to have bold first, and then discuss how to resolve the SGR bold vs. colors nightmare. > but the day we break the legacy brightness functionality is the day I stop contributing to this project and manage my own fork. Hopefully that'll never happen. I hope that too, first, because it would be a bad product decision, and second, because the team and the users would miss your truly valuable contributions! I didn't repeat it here, but I think I made it clear in another thread that I do _not_ want this behavior the only one; I do _not_ even ask for it to be the default. However, modern Unix-y behavior with color schemes like Solarized require a mode where SGR 1 doesn't temper with the colors. It needs to be one of the modes supported by WT – along with, of course, other modes that you personally care about more, and are imporant for Windows backwards compatibility. > I was thinking a nice compromise would be to treat SGR 1 as bright (but not bold) for "legacy" colors, and as a bold font (but not bright) for the extended ITU colors. I disagree with this. This doesn't clean up the current mess at all, just pushes it slightly elsewhere. Also note that terminfo-based apps (included ncurses-based ones, too) only have 256 indices to pick a color from, and they have no control over whether indices 0..15 map to the legacy or to the extended escape sequences. Some terminfo versions/entries do the legacy one, some do the 256-color one. Terminfo and ncurses expose the concept of 256 palette colors altogether, not 16+256 ones. So such apps would have no control whatsoever about which actual look they can achieve. The only reasonable way forward, as Kitty, VTE and Alacritty (in this chronological order) already did as their default, and is available as an option in xterm, urxvt and probably many others too, is to _fully_ separate bold typeface from the colors. Again, as an _option_, with other backwards compatibility options provided too, as the given project finds appropriate.
Author
Owner

@j4james commented on GitHub (Apr 18, 2020):

IMO it doesn't make too much sense to talk about how the SGR codes exactly map to colors, without having bold (as in heavier font being displayed) support for now; and then at one point re-evaluate all of this with bold in the game. I'd find it much cleaner to have bold first, and then discuss how to resolve the SGR bold vs. colors nightmare.

I don't think this is an issue for us. The decision to render bold with a heavier font would happen in the renderer. It's going nothing to do with the SGR dispatching code that I'm working on now. The dispatcher simply records the bold state as a flag for the renderer to process. It's probably a bit messier than I'm making out, but it's still not relevant to this area of the code.

The only reasonable way forward...

"Reasonable" is not the word I'd use to describe what you're doing. But lets just agree to disagree.

@j4james commented on GitHub (Apr 18, 2020): > IMO it doesn't make too much sense to talk about how the SGR codes exactly map to colors, without having bold (as in heavier font being displayed) support for now; and then at one point re-evaluate all of this with bold in the game. I'd find it much cleaner to have bold first, and then discuss how to resolve the SGR bold vs. colors nightmare. I don't think this is an issue for us. The decision to render bold with a heavier font would happen in the renderer. It's going nothing to do with the SGR dispatching code that I'm working on now. The dispatcher simply records the bold state as a flag for the renderer to process. It's probably a bit messier than I'm making out, but it's still not relevant to this area of the code. > The only reasonable way forward... "Reasonable" is not the word I'd use to describe what you're doing. But lets just agree to disagree.
Author
Owner

@ghost commented on GitHub (Jul 22, 2020):

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

Handy links:

@ghost commented on GitHub (Jul 22, 2020): :tada:This issue was addressed in #6506, which has now been successfully released as `Windows Terminal Preview v1.2.2022.0`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.2.2022.0) * [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#7448