ANSI ESC 39 and 49 seems to misbehave #17707

Closed
opened 2026-01-31 05:50:59 +00:00 by claunia · 8 comments
Owner

Originally created by @jredfox on GitHub (Jun 14, 2022).

Windows Terminal version

1.13.11431.0

Windows build number

10.0.19044 N/A Build 19044

Other Software

No response

Steps to reproduce

create a batch file

@Echo off
echo 
cls
pause
echo Hello world
cls
pause

run this in windows terminal using the command prompt profile

Expected Behavior

the background stays BLUE because 0m resets shouldn't reset the default BG and FG values. ANSI ESC 39 and 49 are to set the default bg and fg which should stay after 0m which is needed to clear alot of other ANSI escape codes
https://en.wikipedia.org/wiki/ANSI_escape_code

Actual Behavior

it goes purple then black. instead of staying the color it was previously

Originally created by @jredfox on GitHub (Jun 14, 2022). ### Windows Terminal version 1.13.11431.0 ### Windows build number 10.0.19044 N/A Build 19044 ### Other Software _No response_ ### Steps to reproduce create a batch file ```bat @Echo off echo  cls pause echo Hello world cls pause ``` run this in windows terminal using the command prompt profile ### Expected Behavior the background stays BLUE because 0m resets shouldn't reset the default BG and FG values. ANSI ESC 39 and 49 are to set the default bg and fg which should stay after 0m which is needed to clear alot of other ANSI escape codes https://en.wikipedia.org/wiki/ANSI_escape_code ### Actual Behavior it goes purple then black. instead of staying the color it was previously
claunia added the Needs-TriageIssue-BugNeeds-Tag-FixNeeds-Attention labels 2026-01-31 05:50:59 +00:00
Author
Owner

@zadjii-msft commented on GitHub (Jun 14, 2022):

Which Terminal version are you using? We've[1] been doing a lot of work to improve our VT support over the years, so knowing the exact build numbers matters here.

To me, that script looks like

  • set the active attributes to "default BG"
  • set the active attributes to have blinking text
  • set the active attributes to have a purple BG
  • clear the buffer (with the default attributes, not the active ones)
  • reset the active attributes to (default FG, default BG)
  • print "hello world"
  • clear the buffer (with the default attributes, which are the active ones)

[1]: and by we, I mean @j4james 😝

@zadjii-msft commented on GitHub (Jun 14, 2022): Which Terminal version are you using? We've[1] been doing a lot of work to improve our VT support over the years, so knowing the exact build numbers matters here. To me, that script looks like * set the active attributes to "default BG" * set the active attributes to have blinking text * set the active attributes to have a purple BG * clear the buffer (with the _default_ attributes, not the _active_ ones) * reset the active attributes to (default FG, default BG) * print "hello world" * clear the buffer (with the _default_ attributes, which are the _active_ ones) [1]: and by we, I mean @j4james 😝
Author
Owner

@jredfox commented on GitHub (Jun 14, 2022):

@zadjii-msft 1.13.11431.0
the cls is to avoid another bug where you have to clear the screen before the bg colors update.

@jredfox commented on GitHub (Jun 14, 2022): @zadjii-msft `1.13.11431.0` the cls is to avoid another bug where you have to clear the screen before the bg colors update.
Author
Owner

@jredfox commented on GitHub (Jun 14, 2022):

I also noticed that the xterm-256 color for 45 is actually a light blue while here it shows purple. something really wrong is happening. changing the ESC from 49 to 48 fixes the color from purple to be it's proper light blue.
https://www.ditig.com/256-colors-cheat-sheet

@jredfox commented on GitHub (Jun 14, 2022): I also noticed that the xterm-256 color for `45` is actually a light blue while here it shows purple. something really wrong is happening. changing the ESC from 49 to 48 fixes the color from purple to be it's proper light blue. https://www.ditig.com/256-colors-cheat-sheet
Author
Owner

@zadjii-msft commented on GitHub (Jun 14, 2022):

That makes sense to me. 49;5;45m is

  • switch to the default BG
  • enable blinking text
  • switch to a dark magenta BG

While 48;5;45m is "set the BG to the color at index 45 in the 256 color table"

@zadjii-msft commented on GitHub (Jun 14, 2022): That makes sense to me. `49;5;45m` is * switch to the default BG * enable blinking text * switch to a dark magenta BG While `48;5;45m` is "set the BG to the color at index 45 in the 256 color table"
Author
Owner

@jredfox commented on GitHub (Jun 14, 2022):

According to Wikipedia it said 49 was set default background. So there is no set default bg? Only switch to? I assumed 49 was set default bg with the same Params as 48

@jredfox commented on GitHub (Jun 14, 2022): According to Wikipedia it said 49 was set default background. So there is no set default bg? Only switch to? I assumed 49 was set default bg with the same Params as 48
Author
Owner

@zadjii-msft commented on GitHub (Jun 14, 2022):

I'd refer to https://invisible-island.net/xterm/ctlseqs/ctlseqs.html, it's definitely the definitive guide.

In this case, Operating System Commands for OSC 10 and OSC 11, which can be used to change the RGB values of the default FG/BG (respectively).

As an example, this is a python script I have for changing the Terminal BG color

import colorsys

for i in range(0, 2560):
    h = i / 256.0
    (r, g, b) = tuple(round(j * 255) for j in colorsys.hsv_to_rgb(h,1.0,1.0))
    sys.stdout.write(f'\x1b]11;rgb:{r:x}/{g:x}/{b:x}\x1b\\')
    sys.stdout.write(f'\rrgb:{r:x}/{g:x}/{b:x}')
    sys.stdout.flush()
    time.sleep(.01)

which looks more or less like:
themes-tab-background-001

@zadjii-msft commented on GitHub (Jun 14, 2022): I'd refer to https://invisible-island.net/xterm/ctlseqs/ctlseqs.html, it's definitely the definitive guide. In this case, [Operating System Commands](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands) for `OSC 10` and `OSC 11`, which can be used to change the RGB values of the default FG/BG (respectively). As an example, this is a python script I have for changing the Terminal BG color ```py import colorsys for i in range(0, 2560): h = i / 256.0 (r, g, b) = tuple(round(j * 255) for j in colorsys.hsv_to_rgb(h,1.0,1.0)) sys.stdout.write(f'\x1b]11;rgb:{r:x}/{g:x}/{b:x}\x1b\\') sys.stdout.write(f'\rrgb:{r:x}/{g:x}/{b:x}') sys.stdout.flush() time.sleep(.01) ``` which looks more or less like: ![themes-tab-background-001](https://user-images.githubusercontent.com/18356694/173596090-2d2fbc2d-9027-4704-86c6-cbee758eb9cd.gif)
Author
Owner

@DHowett commented on GitHub (Jun 14, 2022):

Right, SGR 49 means "set the active background color for newly written text or cleared lines to the default background color." SGRs have no affordance for redefining what a color index means.

In Terminal 1.14+, you'll be able to set the default background color to one of the palette indices using DECAC. In Terminal <1.14, you can set the background color in RGB using OSC 11 (I think it's 11...). However, both of those will change the background in perpetuity, and will reassign what SGR 49 means.

@DHowett commented on GitHub (Jun 14, 2022): Right, SGR `49` means "set the active background color for newly written text or cleared lines to the default background color." SGRs have no affordance for redefining what a color index means. In Terminal 1.14+, you'll be able to set the default background color to one of the palette indices using `DECAC`. In Terminal <1.14, you can set the background color in RGB using `OSC 11` (I think it's 11...). However, both of those will change the background in perpetuity, and will reassign what SGR `49` means.
Author
Owner

@jredfox commented on GitHub (Jun 15, 2022):

No it won't be the exact color but generally they will be the same color as defined by xterm256 color or ansi 4 bit color. Like purple won't be blue or black or white on different terminals. It just happens that 39 and 49 behaved differently then 38 and 48 by requiring no parameters that's why I closed the issue

@jredfox commented on GitHub (Jun 15, 2022): No it won't be the exact color but generally they will be the same color as defined by xterm256 color or ansi 4 bit color. Like purple won't be blue or black or white on different terminals. It just happens that 39 and 49 behaved differently then 38 and 48 by requiring no parameters that's why I closed the issue
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#17707