[PR #14650] [MERGED] Prevent horizontally scrolling wide chars erasing themselves #30190

Open
opened 2026-01-31 09:39:14 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/14650
Author: @j4james
Created: 1/8/2023
Status: Merged
Merged: 1/13/2023
Merged by: @undefined

Base: mainHead: fix-dbcs-scrolling


📝 Commits (2)

  • 43faa28 Prevent DBCS erasure when scrolling horizontally.
  • a2fc404 Add some unit tests.

📊 Changes

3 files changed (+72 additions, -8 deletions)

View changed files

📝 src/host/output.cpp (+7 -3)
📝 src/host/ut_host/ScreenBufferTests.cpp (+50 -0)
📝 src/terminal/adapter/adaptDispatch.cpp (+15 -5)

📄 Description

When the buffer contains wide characters that occupy more than one cell,
and those cells are scrolled horizontally by exactly one column, that
operation can result in the wide characters being completely erased.
This PR attempts to fix that bug, although it's not an ideal long term
solution.

Although not really to blame, it was PR #13626 that exposed this issue.

The root of the problem is that scrolling operations copy cells one by
one, but wide characters are written to the buffer two cells at a time.
So when you move a wide character one position to the left or right, it
can overwrite itself before it's finished copying, and the end result is
the whole character gets erased.

I've attempt to solve this by getting the affected operations to read
two cells in advance before they start writing, so there's no risk of
losing the source data before it's fully output. This may not work in
the long term, with characters wider than two cells, but it should at
least be good enough for now.

I've also changed the TextBuffer::Write call to a WriteLine call to
improve the handling of a wide character on the end of the line, where
moving it right by one column would place it half off screen. It should
just be dropped, but with the Write method, it would end up pushed
onto the following line.

Validation Steps Performed

I've manually confirmed this fixes all the test cases described in
#14626, and also added some unit tests that replicate those scenarios.

Closes #14626


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/14650 **Author:** [@j4james](https://github.com/j4james) **Created:** 1/8/2023 **Status:** ✅ Merged **Merged:** 1/13/2023 **Merged by:** [@undefined](undefined) **Base:** `main` ← **Head:** `fix-dbcs-scrolling` --- ### 📝 Commits (2) - [`43faa28`](https://github.com/microsoft/terminal/commit/43faa287b091ee0c0fa70940dafed4bba6014687) Prevent DBCS erasure when scrolling horizontally. - [`a2fc404`](https://github.com/microsoft/terminal/commit/a2fc40428124ef321b4d31225daaed215887d888) Add some unit tests. ### 📊 Changes **3 files changed** (+72 additions, -8 deletions) <details> <summary>View changed files</summary> 📝 `src/host/output.cpp` (+7 -3) 📝 `src/host/ut_host/ScreenBufferTests.cpp` (+50 -0) 📝 `src/terminal/adapter/adaptDispatch.cpp` (+15 -5) </details> ### 📄 Description When the buffer contains wide characters that occupy more than one cell, and those cells are scrolled horizontally by exactly one column, that operation can result in the wide characters being completely erased. This PR attempts to fix that bug, although it's not an ideal long term solution. Although not really to blame, it was PR #13626 that exposed this issue. The root of the problem is that scrolling operations copy cells one by one, but wide characters are written to the buffer two cells at a time. So when you move a wide character one position to the left or right, it can overwrite itself before it's finished copying, and the end result is the whole character gets erased. I've attempt to solve this by getting the affected operations to read two cells in advance before they start writing, so there's no risk of losing the source data before it's fully output. This may not work in the long term, with characters wider than two cells, but it should at least be good enough for now. I've also changed the `TextBuffer::Write` call to a `WriteLine` call to improve the handling of a wide character on the end of the line, where moving it right by one column would place it half off screen. It should just be dropped, but with the `Write` method, it would end up pushed onto the following line. ## Validation Steps Performed I've manually confirmed this fixes all the test cases described in #14626, and also added some unit tests that replicate those scenarios. Closes #14626 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:39:14 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#30190