Tmux redraws incorrectly when scrolling #19035

Closed
opened 2026-01-31 06:32:03 +00:00 by claunia · 17 comments
Owner

Originally created by @andyneff on GitHub (Dec 8, 2022).

Windows Terminal version

1.15.2875.0

Windows build number

10.0.22621.900

Other Software

tmux 3.3a

Steps to reproduce

I've been having this problem since I started using Terminal many month ago. It happens at random, and I've never really been able to reproduce it on demand.

  1. Use tmux for while (often days)
  2. Scroll up
  3. See that the scrolling mechanic is messed up

For a while today, I was able to reproduce it this way (but then it stopped reproducing, so I doubt these step will work for anyone)

  1. Start Terminal in WSL with Fedoraremix
  2. Maximize window (doubt this is important)
  3. tmux
  4. docker run -it --rm alpine
  5. find /usr
  6. Scroll up

Expected Behavior

Scrolling to always work correctly, like so:

image

Actual Behavior

You see the numbers in the upper right messed up, and the actual buffer on screen looks all wrong.
image

Many more details about the redrawing are incorrect, but this is the simplest to explain

The solution is to close Windows Terminal, and restart it again. Luckily, I'm in tmux so that's pretty straight forward. But anything less than restarting the tab does not work. Often creating a new tab usaully works and I don't have to close the entire Windows Terminal window

  • reset does not work
  • Closing tmux and attaching does not work

May be related to #8000 or #6987, but it seemed different enough it might not be.

Originally created by @andyneff on GitHub (Dec 8, 2022). ### Windows Terminal version 1.15.2875.0 ### Windows build number 10.0.22621.900 ### Other Software tmux 3.3a ### Steps to reproduce I've been having this problem since I started using Terminal many month ago. It happens at random, and I've never really been able to reproduce it on demand. 1. Use tmux for while (often days) 2. Scroll up 3. See that the scrolling mechanic is messed up For a while today, I was able to reproduce it this way (but then it stopped reproducing, so I doubt these step will work for anyone) 1. Start Terminal in WSL with Fedoraremix 2. Maximize window (doubt this is important) 3. `tmux` 4. `docker run -it --rm alpine` 5. `find /usr` 6. Scroll up ### Expected Behavior Scrolling to always work correctly, like so: ![image](https://user-images.githubusercontent.com/7596961/206561530-c4287b18-2b0b-42ee-9b95-15cce25ff613.png) ### Actual Behavior You see the numbers in the upper right messed up, and the actual buffer on screen looks all wrong. ![image](https://user-images.githubusercontent.com/7596961/206561215-9a4e4735-fa59-44fd-9a8f-10252df7601a.png) Many more details about the redrawing are incorrect, but this is the simplest to explain The solution is to close Windows Terminal, and restart it again. Luckily, I'm in tmux so that's pretty straight forward. But anything less than restarting the tab does not work. Often creating a new tab usaully works and I don't have to close the entire Windows Terminal window - `reset` does not work - Closing tmux and attaching does not work May be related to #8000 or #6987, but it seemed different enough it might not be.
Author
Owner

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

@j4james You think this is the same #3673 / #7687 / #9939 nexus of issues?

@zadjii-msft commented on GitHub (Dec 14, 2022): @j4james You think this is the same #3673 / #7687 / #9939 nexus of issues?
Author
Owner

@j4james commented on GitHub (Dec 15, 2022):

I don't think so, no. This shouldn't be a problem with our scrollback, because when you're in a tmux session, it manages the scrollback history itself. So if you're scrolling up (which I believe you initiate in tmux with Ctrl+b then [), it's actually tmux that's redrawing that history from its own buffers.

So if it's a dupe of anything, I'd guess #6987 and/or #8000, but I can't see anything in those screenshots that would trigger that kind of problem. Typically I'd expect to see some weird Unicode characters, but maybe there is something like a zero-width joiner, or the corruption occurred earlier with content that is no longer visible.

If we're lucky, this might get fixed with the #8000 improvements. If not, we're probably going to need an easily reproducible test case to figure out where exactly it's failing.

@j4james commented on GitHub (Dec 15, 2022): I don't think so, no. This shouldn't be a problem with our scrollback, because when you're in a tmux session, it manages the scrollback history itself. So if you're scrolling up (which I believe you initiate in tmux with `Ctrl+b` then `[`), it's actually tmux that's redrawing that history from its own buffers. So if it's a dupe of anything, I'd guess #6987 and/or #8000, but I can't see anything in those screenshots that would trigger that kind of problem. Typically I'd expect to see some weird Unicode characters, but maybe there is something like a zero-width joiner, or the corruption occurred earlier with content that is no longer visible. If we're lucky, this might get fixed with the #8000 improvements. If not, we're probably going to need an easily reproducible test case to figure out where exactly it's failing.
Author
Owner

@andyneff commented on GitHub (Jan 3, 2023):

While I do see similar artifacts when replicating #6987, I'm still able to scroll (in tmux) normally after it happens

@andyneff commented on GitHub (Jan 3, 2023): While I do see similar artifacts when replicating #6987, I'm still able to scroll (in tmux) normally after it happens
Author
Owner

@DHowett commented on GitHub (Jan 25, 2023):

Would you mind sharing a repro with the debug tap enabled + script running? Please note that this will capture any data you type or paste into Terminal including passwords and any data that comes back out of the application.

  1. Enable the terminal debug tap and launch a terminal with it open.
    • This will capture all I/O from the Terminal side into a split pane.
  2. In bash, run script
    • This will capture all I/O from the client application side into a file named typescript.
  3. Reproduce the issue (launch tmux, cause the issue, etc.)
  4. exit from inside bash-inside-script
  5. Share the typescript file and the backlog from the split debugging pane, either here or via private e-mail to the address on my GitHub profile

This may help us in pinning down exactly where in the stack the issue is.

Thanks!

@DHowett commented on GitHub (Jan 25, 2023): Would you mind sharing a repro with the debug tap enabled + `script` running? _Please note that this will capture any data you type or paste into Terminal **including passwords** and any data that comes back out of the application._ 1. Enable the [terminal debug tap](https://github.com/microsoft/terminal/wiki/Enabling-the-debug-tap) and launch a terminal with it open. * This will capture all I/O from the Terminal side into a split pane. 3. In bash, run `script` * This will capture all I/O from the client application side into a file named `typescript`. 4. Reproduce the issue (launch tmux, cause the issue, etc.) 5. `exit` from inside bash-inside-script 6. Share the `typescript` file and the backlog from the split debugging pane, either here or via private e-mail to the address on my GitHub profile This _may_ help us in pinning down exactly where in the stack the issue is. Thanks!
Author
Owner

@andyneff commented on GitHub (Jan 26, 2023):

I will see what I can do. It will take me a while to do this as I do not have a consistent way to repro this :(

@andyneff commented on GitHub (Jan 26, 2023): I will see what I can do. It will take me a while to do this as I do not have a consistent way to repro this :(
Author
Owner

@andyneff commented on GitHub (Jan 26, 2023):

Ok, I spoke too soon. Got it on my first try!

image

Steps:

  1. Enabled debug feature
  2. Opened a new window (I have another one open, not involved in this process)
  3. Did the alt+alt+new tab
  4. Closed the old tab
  5. Typed script
  6. And the rest is all captured

14514_debug_output.txt
14514_typescript.txt

If it comes up, my PS1 is custom and complicated, but the current value is:

declare -- PS1="\\[\\e[40;93m\\]\\w\\[\\e[0m\\]\\n[\\u@\\[\\e[38;5;190m\\]\\h\\[\\e[0m\\] 0 \\[\\e[33m\\]fedoraremix\\[\\e[0m\\] \\W]\$ "
@andyneff commented on GitHub (Jan 26, 2023): Ok, I spoke too soon. Got it on my first try! ![image](https://user-images.githubusercontent.com/7596961/214882789-6575bc67-2a95-46fe-ac88-bfebe1689657.png) Steps: 1. Enabled debug feature 2. Opened a new window (I have another one open, not involved in this process) 3. Did the alt+alt+new tab 4. Closed the old tab 5. Typed `script` 6. And the rest is all captured [14514_debug_output.txt](https://github.com/microsoft/terminal/files/10510978/14514_debug_output.txt) [14514_typescript.txt](https://github.com/microsoft/terminal/files/10511000/14514_typescript.txt) If it comes up, my `PS1` is [custom and complicated](https://github.com/andyneff/dot_files/blob/main/files/.personal.bashrc#L248), but the current value is: ``` declare -- PS1="\\[\\e[40;93m\\]\\w\\[\\e[0m\\]\\n[\\u@\\[\\e[38;5;190m\\]\\h\\[\\e[0m\\] 0 \\[\\e[33m\\]fedoraremix\\[\\e[0m\\] \\W]\$ " ```
Author
Owner

@j4james commented on GitHub (Jan 26, 2023):

This looks to me like it could be a variation of #14690.

When you pan up in the scrollback buffer, this is what tmux does:

  1. Insert a blank line at the top of the screen to move the content down.
  2. Write out the start of the line retrieved from the scrollback, e.g. /usr/bin/comm.
  3. Move forward a few columns with CUF.
  4. Write out a bunch of spaces to pad the line out to column 96 (this is where the line indicator would be rendered).
  5. Move down a line with LF.
  6. Write out some more spaces to erase the old line indicator from before the scroll.
  7. Move back to column 96 in the first row to write the new line indicator.

The problem is that step 5 doesn't just move down a line, but also moves the cursor back to the first column. So instead of erasing the old line indicator, it's erasing the start of the line.

And I suspect the reason the LF is behaving incorrectly, is because the DISABLE_NEWLINE_AUTO_RETURN mode has been changed by something. I don't see wslsys used here, so docker maybe?

Assuming that is the correct interpretation, this should be fixed by PR #14735.

@j4james commented on GitHub (Jan 26, 2023): This looks to me like it could be a variation of #14690. When you pan up in the scrollback buffer, this is what tmux does: 1. Insert a blank line at the top of the screen to move the content down. 2. Write out the start of the line retrieved from the scrollback, e.g. `/usr/bin/comm`. 3. Move forward a few columns with `CUF`. 4. Write out a bunch of spaces to pad the line out to column 96 (this is where the line indicator would be rendered). 5. Move down a line with `LF`. 6. Write out some more spaces to erase the old line indicator from before the scroll. 7. Move back to column 96 in the first row to write the new line indicator. The problem is that step 5 doesn't just move down a line, but also moves the cursor back to the first column. So instead of erasing the old line indicator, it's erasing the start of the line. And I suspect the reason the `LF` is behaving incorrectly, is because the `DISABLE_NEWLINE_AUTO_RETURN` mode has been changed by something. I don't see wslsys used here, so docker maybe? Assuming that is the correct interpretation, this should be fixed by PR #14735.
Author
Owner

@andyneff commented on GitHub (Jan 26, 2023):

I don't know enough about the alt buffer, but I did exactly what you mentioned in your issue, and I did indeed get your result. So I tried a mix with my tmux scenario:

Test 1

  1. Start new window
  2. tmux
  3. Run long command and scroll and see it works
  4. wslsys
  5. Scroll again

Test 2

  1. Start new window
  2. tmux
  3. Run long command and scroll and see it works
  4. printf "\e[?1049h"
  5. Scroll and see it works again
  6. wslsys
  7. Scroll and see it works again
  8. printf "\e[?1049l"
  9. Scroll and see it works again
  10. wslsys
  11. Scroll and see it works again

So no error on these two attempt. If I'm just doing it wrong or this is a "not always" thing, then these results are meaningless

@andyneff commented on GitHub (Jan 26, 2023): I don't know enough about the alt buffer, but I did exactly what you mentioned in your issue, and I did indeed get your result. So I tried a mix with my tmux scenario: ## Test 1 1. Start new window 1. `tmux` 1. _Run long command and scroll_ and see it works 1. `wslsys` 1. Scroll again ## Test 2 1. Start new window 1. `tmux` 1. _Run long command and scroll_ and see it works 1. `printf "\e[?1049h"` 1. Scroll and see it works again 1. `wslsys` 1. Scroll and see it works again 1. `printf "\e[?1049l"` 1. Scroll and see it works again 1. `wslsys` 1. Scroll and see it works again --- So no error on these _two_ attempt. If I'm just doing it wrong or this is a "not always" thing, then these results are meaningless
Author
Owner

@j4james commented on GitHub (Jan 26, 2023):

The problem is that tmux introduces another level on indirection, which can make it difficult to reproduce the issue. There are three thing you need to do to trigger the problem:

  1. You need to be in the alt buffer.
  2. You need something to call the SetConsoleMode API.
  3. You need to make use of one the LF, VT, or FF control characters in a way that relies on them moving down without changing the column position.

Just running tmux should satisfy condition 1. And I'm fairly certain wslsys should trigger condition 2. But condition 3 is entirely dependent on how tmux redraws the screen.

In the typescript log that you sent before, I could clearly see it was using an LF from column 96 when it tried to clear the line indicator, and that's where things went wrong. But when I try to reproduce that on my system, tmux redrew the screen in a completely different way. It only ever used an LF in column 1, so it wasn't affected by the DISABLE_NEWLINE_AUTO_RETURN mode being wrong.

So if you want to confirm that this is the same problem as #14690, I'd suggest you eliminate tmux from the equation, and try and reproduce my test case from #14690, but see if you can trigger the mode change with docker rather than wslsys.

  1. Switch to the alt buffer with printf "\e[?1049h"
  2. Test the formfeed behavior with printf "\e[10CX\b\fY\n"
  3. Run docker however you normally would
  4. Run the formfeed test again with printf "\e[10CX\b\fY\n"

If docker is triggering the mode change then the output in step 4 should be different from step 2.

@j4james commented on GitHub (Jan 26, 2023): The problem is that `tmux` introduces another level on indirection, which can make it difficult to reproduce the issue. There are three thing you need to do to trigger the problem: 1. You need to be in the alt buffer. 2. You need something to call the `SetConsoleMode` API. 3. You need to make use of one the `LF`, `VT`, or `FF` control characters in a way that relies on them moving down without changing the column position. Just running `tmux` should satisfy condition 1. And I'm fairly certain `wslsys` should trigger condition 2. But condition 3 is entirely dependent on how `tmux` redraws the screen. In the `typescript` log that you sent before, I could clearly see it was using an `LF` from column 96 when it tried to clear the line indicator, and that's where things went wrong. But when I try to reproduce that on my system, `tmux` redrew the screen in a completely different way. It only ever used an `LF` in column 1, so it wasn't affected by the `DISABLE_NEWLINE_AUTO_RETURN` mode being wrong. So if you want to confirm that this is the same problem as #14690, I'd suggest you eliminate `tmux` from the equation, and try and reproduce my test case from #14690, but see if you can trigger the mode change with `docker` rather than `wslsys`. 1. Switch to the alt buffer with `printf "\e[?1049h"` 2. Test the formfeed behavior with `printf "\e[10CX\b\fY\n"` 3. Run `docker` however you normally would 4. Run the formfeed test again with `printf "\e[10CX\b\fY\n"` If `docker` is triggering the mode change then the output in step 4 should be different from step 2.
Author
Owner

@andyneff commented on GitHub (Feb 20, 2023):

Problem still happening on 1.16.10262.0

@andyneff commented on GitHub (Feb 20, 2023): Problem still happening on 1.16.10262.0
Author
Owner

@j4james commented on GitHub (Feb 20, 2023):

@andyneff Thanks for checking, but the fix hasn't been released yet, unless you're building from source. But if you subscribe to issue #14690, you should get a notification from the msftbot as soon as it is released, and that'll also tell you exactly which version has the fix (I'm assuming it'll be in a Preview build first).

@j4james commented on GitHub (Feb 20, 2023): @andyneff Thanks for checking, but the fix hasn't been released yet, unless you're building from source. But if you subscribe to issue #14690, you should get a notification from the msftbot as soon as it is released, and that'll also tell you exactly which version has the fix (I'm assuming it'll be in a _Preview_ build first).
Author
Owner

@zadjii-msft commented on GitHub (Feb 20, 2023):

I'm gonna leave this open so that once 1.18 is out we can absolutely confirm that this is fixed, but yea I'm inclined to believe this is the same thing.

@zadjii-msft commented on GitHub (Feb 20, 2023): I'm gonna leave this open so that once 1.18 is out we can absolutely confirm that this is fixed, but yea I'm inclined to believe this is the same thing.
Author
Owner

@zadjii-msft commented on GitHub (Sep 7, 2023):

@andyneff can you double check that this is fixed now that 1.18 is out/? You should be able to get it from https://github.com/microsoft/terminal/releases/tag/v1.18.1462.0

@zadjii-msft commented on GitHub (Sep 7, 2023): @andyneff can you double check that this is fixed now that 1.18 is out/? You should be able to get it from https://github.com/microsoft/terminal/releases/tag/v1.18.1462.0
Author
Owner

@andyneff commented on GitHub (Sep 7, 2023):

I'm having trouble reproducing it on 1.17.11461.0 today, and it is not producing any errors on 1.18.1462.0 today too.

@andyneff commented on GitHub (Sep 7, 2023): I'm having trouble reproducing it on 1.17.11461.0 today, and it is not producing any errors on 1.18.1462.0 today too.
Author
Owner

@zadjii-msft commented on GitHub (Sep 7, 2023):

Right on. Thanks for following up. Glad this got sorted out!

@zadjii-msft commented on GitHub (Sep 7, 2023): Right on. Thanks for following up. Glad this got sorted out!
Author
Owner

@valk commented on GitHub (Oct 10, 2024):

There seems to be a regression on Version: 3.3a-3, can others confirm?

I'm using iTerm2 on Mac, connected to a Docker container / Amazon Linux:

cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

and

uname -r
5.10.226-214.879.amzn2.x86_64
@valk commented on GitHub (Oct 10, 2024): There seems to be a regression on Version: 3.3a-3, can others confirm? I'm using iTerm2 on Mac, connected to a Docker container / Amazon Linux: ``` cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 12 (bookworm)" NAME="Debian GNU/Linux" VERSION_ID="12" VERSION="12 (bookworm)" VERSION_CODENAME=bookworm ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" ``` and ``` uname -r 5.10.226-214.879.amzn2.x86_64 ```
Author
Owner

@j4james commented on GitHub (Oct 10, 2024):

@valk I think you're in the wrong place. This is the issue tracker for Windows Terminal. If you're having a problem with iTerm2, you can file a report via one of the links here: https://iterm2.com/bugs/

@j4james commented on GitHub (Oct 10, 2024): @valk I think you're in the wrong place. This is the issue tracker for _Windows Terminal_. If you're having a problem with _iTerm2_, you can file a report via one of the links here: https://iterm2.com/bugs/
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#19035