ansi terminal code reset breaks after scrolling #14397

Closed
opened 2026-01-31 04:09:14 +00:00 by claunia · 9 comments
Owner

Originally created by @akwebb1 on GitHub (Jul 4, 2021).

Windows Terminal version (or Windows build number)

wt 1.8.1521.0, wt 1.9.1523.0, windows 10.0.19043.0

Other Software

No response

Steps to reproduce

clear a powershell terminal screen with clear command.

run the following multiple times on the PowerShell command line until the terminal screen scrolls.

(0..255) | ForEach-Object {Write-Host "`e[48;5;$($_)m " -NoNewline};Write-Host "`e[0mX`n"

You can see the last output line does not properly reset the background and instead sets it to the background of the first character position on the line that the reset code is issued. There is an ansi reset terminal code sent just before the 'X' is displayed which works on all lines prior to the scrolling setting the background back to the default.

I get the same results with and without loading my PowerShell profile.

Screenshot 2021-07-04 130857

Expected Behavior

I expect that the output would be identical before and after the terminal window scrolls with the background being reset to the default.

Actual Behavior

After the terminal screen scrolls the background color after a reset code is sent is incorrect as shown above. If you clear the screen everything works as expected again until the terminal scrolls.

Originally created by @akwebb1 on GitHub (Jul 4, 2021). ### Windows Terminal version (or Windows build number) wt 1.8.1521.0, wt 1.9.1523.0, windows 10.0.19043.0 ### Other Software _No response_ ### Steps to reproduce clear a powershell terminal screen with clear command. run the following multiple times on the PowerShell command line until the terminal screen scrolls. ``` (0..255) | ForEach-Object {Write-Host "`e[48;5;$($_)m " -NoNewline};Write-Host "`e[0mX`n" ``` You can see the last output line does not properly reset the background and instead sets it to the background of the first character position on the line that the reset code is issued. There is an ansi reset terminal code sent just before the 'X' is displayed which works on all lines prior to the scrolling setting the background back to the default. I get the same results with and without loading my PowerShell profile. ![Screenshot 2021-07-04 130857](https://user-images.githubusercontent.com/2871794/124393683-9d44c880-dcc9-11eb-9a1b-ade2e9ee3117.png) ### Expected Behavior I expect that the output would be identical before and after the terminal window scrolls with the background being reset to the default. ### Actual Behavior After the terminal screen scrolls the background color after a reset code is sent is incorrect as shown above. If you clear the screen everything works as expected again until the terminal scrolls.
claunia added the Resolution-By-DesignNeeds-TriageNeeds-Tag-Fix labels 2026-01-31 04:09:14 +00:00
Author
Owner

@j4james commented on GitHub (Jul 4, 2021):

The effect you're seeing is by design, and is compatible with most modern terminals. When the screen scrolls, the newly revealed lines are initially filled with the active background color. In your test case, when that second last line wraps, the active background color is yellow, so the newly revealed line is filled with yellow. The active colors are eventually reset to default, so the X is output with the default colors, but unless you also fill to the end of the line that's not going to change the background color that the line was initially created with.

You can see the same effect in a Linux terminal with a simple bash command like printf "\e[43m\n\e[m". If you execute that on the last line of the page, you'll see the newly revealed line has a yellow background.

@j4james commented on GitHub (Jul 4, 2021): The effect you're seeing is by design, and is compatible with most modern terminals. When the screen scrolls, the newly revealed lines are initially filled with the active background color. In your test case, when that second last line wraps, the active background color is yellow, so the newly revealed line is filled with yellow. The active colors are eventually reset to default, so the X is output with the default colors, but unless you also fill to the end of the line that's not going to change the background color that the line was initially created with. You can see the same effect in a Linux terminal with a simple bash command like `printf "\e[43m\n\e[m"`. If you execute that on the last line of the page, you'll see the newly revealed line has a yellow background.
Author
Owner

@akwebb1 commented on GitHub (Jul 4, 2021):

From my testing this does not happen in any other terminal that supports ansi terminal codes. I tried several of them before reporting this (Gnome-Terminal, Konsole and a couple others). Windows Terminal is the only place this happens for me.

Also, from your response I would think the active background color should be white, not yellow, since that is the last background color set before the reset is called and the X is displayed. The yellow color is from the first character of the line. The background was set to many other values after that so yellow it is not the active background color.

I only noticed this after testing a Rust application that was working fine under several Linux Distros but did not display properly in Windows Terminal. I already added the erase EOL code to fix it under Windows but I did not think it should be needed since I could not reproduce it anywhere else.

Thanks.

@akwebb1 commented on GitHub (Jul 4, 2021): From my testing this does not happen in any other terminal that supports ansi terminal codes. I tried several of them before reporting this (Gnome-Terminal, Konsole and a couple others). Windows Terminal is the only place this happens for me. Also, from your response I would think the active background color should be white, not yellow, since that is the last background color set before the reset is called and the X is displayed. The yellow color is from the first character of the line. The background was set to many other values after that so yellow it is not the active background color. I only noticed this after testing a Rust application that was working fine under several Linux Distros but did not display properly in Windows Terminal. I already added the erase EOL code to fix it under Windows but I did not think it should be needed since I could not reproduce it anywhere else. Thanks.
Author
Owner

@j4james commented on GitHub (Jul 4, 2021):

I recreated your test case in bash to double check on a few Linux terminals. This is the script I'm using:

for i in {0..255}; do printf "\e[48;5;$i""m "; done; printf "\e[mX\n"

Are here are some screenshot from XTerm, Konsole, and Alacritty (I've also tested on MLTerm, Mintty, Hyper, and Contour, with the same results).

image

Gnome Terminal (VTE) I know is different. A couple years back they decided they didn't like the way scrolling worked and figured they'd just change the "standard" behaviour (you can read more here). It's possible there are other terminals that have since copied them, but I suspect they are still in the minority, so I don't think we're likely to change unless XTerm does too (although I can't speak for the core devs - maybe they'll disagree).

That said, there is a VT525 mode (DECECM) which I was planning to implement at some point, which disables background color erasing entirely. That's very different from what VTE is doing, and you probably wouldn't want it disabled permanently (otherwise things like clearing the screen in a particular color wouldn't work), but it's something an app could turn off temporarily if it didn't want this effect when scrolling.

@j4james commented on GitHub (Jul 4, 2021): I recreated your test case in bash to double check on a few Linux terminals. This is the script I'm using: ``` for i in {0..255}; do printf "\e[48;5;$i""m "; done; printf "\e[mX\n" ``` Are here are some screenshot from XTerm, Konsole, and Alacritty (I've also tested on MLTerm, Mintty, Hyper, and Contour, with the same results). ![image](https://user-images.githubusercontent.com/4181424/124397259-d2bbd700-dd06-11eb-9740-88c11e3e877e.png) Gnome Terminal (VTE) I know is different. A couple years back they decided they didn't like the way scrolling worked and figured they'd just change the "standard" behaviour (you can read more [here](https://bugzilla.gnome.org/show_bug.cgi?id=754596)). It's possible there are other terminals that have since copied them, but I suspect they are still in the minority, so I don't think we're likely to change unless XTerm does too (although I can't speak for the core devs - maybe they'll disagree). That said, there is a VT525 mode (`DECECM`) which I was planning to implement at some point, which disables background color erasing entirely. That's very different from what VTE is doing, and you probably wouldn't want it disabled permanently (otherwise things like clearing the screen in a particular color wouldn't work), but it's something an app could turn off temporarily if it didn't want this effect when scrolling.
Author
Owner

@j4james commented on GitHub (Jul 4, 2021):

Also, from your response I would think the active background color should be white, not yellow, since that is the last background color set before the reset is called and the X is displayed.

Just to clarify this point, it's the active color at the time that the screen scrolls, and that occurs when the first character of the last line is output.

@j4james commented on GitHub (Jul 4, 2021): > Also, from your response I would think the active background color should be white, not yellow, since that is the last background color set before the reset is called and the X is displayed. Just to clarify this point, it's the active color at the time that the screen scrolls, and that occurs when the first character of the last line is output.
Author
Owner

@akwebb1 commented on GitHub (Jul 4, 2021):

How strange. I ran it under several of those terminals (gnome, konsole and alacritty) on my Ubuntu and KDE Neon machines and it did not happen to me. I just tried it again to make sure I did not miss something and I still can't reproduce it anywhere except for Windows Terminal.

At least I can fix my application under Windows Terminal with an extra terminal code.

Thanks for the investigation and thanks for the clarification on the active background color. I would not have expected that to be the case.

@akwebb1 commented on GitHub (Jul 4, 2021): How strange. I ran it under several of those terminals (gnome, konsole and alacritty) on my Ubuntu and KDE Neon machines and it did not happen to me. I just tried it again to make sure I did not miss something and I still can't reproduce it anywhere except for Windows Terminal. At least I can fix my application under Windows Terminal with an extra terminal code. Thanks for the investigation and thanks for the clarification on the active background color. I would not have expected that to be the case.
Author
Owner

@j4james commented on GitHub (Jul 4, 2021):

That is weird. When you say you still can't reproduce it on any other terminals, are you saying that my bash script produces different results for you than what I'm seeing on Alacritty and Konsole, or is it just that your app behaves differently on Windows than anywhere else? If it's the former, then it could just be version differences which wouldn't be too concerning. But if it's the latter, maybe there is still something else that we're doing wrong.

@j4james commented on GitHub (Jul 4, 2021): That is weird. When you say you still can't reproduce it on any other terminals, are you saying that my bash script produces different results for you than what I'm seeing on Alacritty and Konsole, or is it just that your app behaves differently on Windows than anywhere else? If it's the former, then it could just be version differences which wouldn't be too concerning. But if it's the latter, maybe there is still something else that we're doing wrong.
Author
Owner

@akwebb1 commented on GitHub (Jul 4, 2021):

Sorry for the lack of context. I meant I could not recreate it with my application anywhere else plus with a couple of terminals that I could access on my laptop.

I don't have access to my Linux machines at the moment since I just hit the road travelling to another location so I could only test the bash script using SecureCRT under Windows against a remote Linux host which did not exhibit that behavior. I also tested it on my laptop with a local Hyper-V image in Ubuntu gnome-terminal which also did not show the issue using your bash code. I won't be back at my physical Ubuntu and KDE machines for a couple of days to try the other terminals.

I am guessing you are correct about gnome-terminal doing things differently and of course SecureCRT is doing something on it's own. I expect that the other terminals will show the same results you provided. I will give it a shot when I get back. I will update when I get a chance.

Thanks again.

@akwebb1 commented on GitHub (Jul 4, 2021): Sorry for the lack of context. I meant I could not recreate it with my application anywhere else plus with a couple of terminals that I could access on my laptop. I don't have access to my Linux machines at the moment since I just hit the road travelling to another location so I could only test the bash script using SecureCRT under Windows against a remote Linux host which did not exhibit that behavior. I also tested it on my laptop with a local Hyper-V image in Ubuntu gnome-terminal which also did not show the issue using your bash code. I won't be back at my physical Ubuntu and KDE machines for a couple of days to try the other terminals. I am guessing you are correct about gnome-terminal doing things differently and of course SecureCRT is doing something on it's own. I expect that the other terminals will show the same results you provided. I will give it a shot when I get back. I will update when I get a chance. Thanks again.
Author
Owner

@akwebb1 commented on GitHub (Jul 8, 2021):

My brief travel has turned into extended travel so I will not have access to the machines that I was testing this on for a while. At some point I will try to recreate some local Hyper-V environments on my Laptop to test again. Since I don't know when I will be returning I think it might be best to close this.

@akwebb1 commented on GitHub (Jul 8, 2021): My brief travel has turned into extended travel so I will not have access to the machines that I was testing this on for a while. At some point I will try to recreate some local Hyper-V environments on my Laptop to test again. Since I don't know when I will be returning I think it might be best to close this.
Author
Owner

@zadjii-msft commented on GitHub (Jul 8, 2021):

I think it might be best to close this.

Combined with the plethora of examples above, I'm cool with that decision. Thanks for the discussion all!

@zadjii-msft commented on GitHub (Jul 8, 2021): > I think it might be best to close this. Combined with the plethora of examples above, I'm cool with that decision. Thanks for the discussion all!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#14397