Cursor movements distort wide cells in a different row #14265

Closed
opened 2026-01-31 04:05:27 +00:00 by claunia · 5 comments
Owner

Originally created by @alabuzhev on GitHub (Jun 18, 2021).

Windows Terminal version (or Windows build number)

10.0.19041.1055

Other Software

No response

Steps to reproduce

Compile and run the following code using the standard console host:

#include <windows.h>

int main()
{
	const auto Out = GetStdHandle(STD_OUTPUT_HANDLE);

	SetConsoleScreenBufferSize(Out, { 80, 25 });

	const auto JapaneseCP = 932;
	SetConsoleOutputCP(JapaneseCP);

	SetConsoleCursorPosition(Out, { 0, 0 });

	const wchar_t Text[] = L"あいうえおかきくけこさしすせそた";
	const auto Size = ARRAYSIZE(Text) - 1;

	CHAR_INFO Buffer[Size * 2]{};

	for (size_t i = 0; i != Size; ++i)
	{
		const auto BlackOnGrey = 0x70;
		Buffer[i * 2 + 0].Attributes = BlackOnGrey | COMMON_LVB_LEADING_BYTE;
		Buffer[i * 2 + 1].Attributes = BlackOnGrey | COMMON_LVB_TRAILING_BYTE;
		Buffer[i * 2 + 0].Char.UnicodeChar = Text[i];
		Buffer[i * 2 + 1].Char.UnicodeChar = Text[i];
	}

	SMALL_RECT WriteRegion1{ 0, 2, Size * 2 - 1, 2 };
	WriteConsoleOutput(Out, Buffer, { Size * 2, 1 }, {}, &WriteRegion1);

	short CursorX = 0;
	SetConsoleCursorPosition(Out, { CursorX, 1 });

	int Direction = 1;

	for (;;)
	{
		Sleep(20);

		CursorX += Direction;
		if (CursorX == Size * 2 - 1)
			Direction = -1;
		else if (!CursorX)
			Direction = +1;

		// Comment this line to make the bug go away:
		SetConsoleCursorPosition(Out, { CursorX, 0 });

		CHAR_INFO Buffer2{};
		Buffer2.Char.UnicodeChar = L'!';
		Buffer2.Attributes = 0xCF;
		SMALL_RECT WriteRegion2{ 40, 2, 41, 2 };
		WriteConsoleOutput(Out, &Buffer2, { 1, 1 }, {}, &WriteRegion2);
	}
}

Expected Behavior

The program draws two areas:

  • grey, only once
  • red, constantly

It also constantly moves the cursor left and right.

The grey area is expected to stay static and display the characters correctly:
image

Actual Behavior

The simultaneous cursor movements in another row distort the characters in the grey area:
image

Originally created by @alabuzhev on GitHub (Jun 18, 2021). ### Windows Terminal version (or Windows build number) 10.0.19041.1055 ### Other Software _No response_ ### Steps to reproduce Compile and run the following code using the standard console host: ```C++ #include <windows.h> int main() { const auto Out = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleScreenBufferSize(Out, { 80, 25 }); const auto JapaneseCP = 932; SetConsoleOutputCP(JapaneseCP); SetConsoleCursorPosition(Out, { 0, 0 }); const wchar_t Text[] = L"あいうえおかきくけこさしすせそた"; const auto Size = ARRAYSIZE(Text) - 1; CHAR_INFO Buffer[Size * 2]{}; for (size_t i = 0; i != Size; ++i) { const auto BlackOnGrey = 0x70; Buffer[i * 2 + 0].Attributes = BlackOnGrey | COMMON_LVB_LEADING_BYTE; Buffer[i * 2 + 1].Attributes = BlackOnGrey | COMMON_LVB_TRAILING_BYTE; Buffer[i * 2 + 0].Char.UnicodeChar = Text[i]; Buffer[i * 2 + 1].Char.UnicodeChar = Text[i]; } SMALL_RECT WriteRegion1{ 0, 2, Size * 2 - 1, 2 }; WriteConsoleOutput(Out, Buffer, { Size * 2, 1 }, {}, &WriteRegion1); short CursorX = 0; SetConsoleCursorPosition(Out, { CursorX, 1 }); int Direction = 1; for (;;) { Sleep(20); CursorX += Direction; if (CursorX == Size * 2 - 1) Direction = -1; else if (!CursorX) Direction = +1; // Comment this line to make the bug go away: SetConsoleCursorPosition(Out, { CursorX, 0 }); CHAR_INFO Buffer2{}; Buffer2.Char.UnicodeChar = L'!'; Buffer2.Attributes = 0xCF; SMALL_RECT WriteRegion2{ 40, 2, 41, 2 }; WriteConsoleOutput(Out, &Buffer2, { 1, 1 }, {}, &WriteRegion2); } } ``` ### Expected Behavior The program draws two areas: - grey, only once - red, constantly It also constantly moves the cursor left and right. The grey area is expected to stay static and display the characters correctly: ![image](https://user-images.githubusercontent.com/11453922/122611826-e82fd080-d079-11eb-917c-bc81c6d286bd.png) ### Actual Behavior The simultaneous cursor movements in another row distort the characters in the grey area: ![image](https://user-images.githubusercontent.com/11453922/122611951-262cf480-d07a-11eb-95d4-a8fb72239b3e.png)
claunia added the Resolution-Duplicate label 2026-01-31 04:05:27 +00:00
Author
Owner

@DHowett commented on GitHub (Jun 18, 2021):

Ah, crap. I remember this bug, but I thought we'd fixed it before 19041. Let me go digging.

@DHowett commented on GitHub (Jun 18, 2021): Ah, crap. I remember this bug, but I thought we'd fixed it before 19041. Let me go digging.
Author
Owner

@DHowett commented on GitHub (Jun 18, 2021):

It looks like it's been fixed since 19041:

version working
18362 ✔️
19041
196xx (even worse)
203xx (same as above)
21xxx ✔️
22xxx ✔️

Trying to track down the change that fixed it.

@DHowett commented on GitHub (Jun 18, 2021): It looks like it's been fixed since 19041: version|working -|- 18362|✔️ 19041|❌ 196xx|❌ (even worse) 203xx|❌ (same as above) 21xxx|✔️ 22xxx|✔️ Trying to track down the change that fixed it.
Author
Owner

@alabuzhev commented on GitHub (Jun 19, 2021):

Thank you, I can't reproduce it with the latest OpenConsole indeed, at least in this particular scenario.

By the way, is there any "official" way to find out which host and which version of it is being used by the process?
Historically checking the Windows version was enough to fine-tune and enable specific workarounds, but now there's Terminal, which theoretically can be detected by the absence of specific host features, but can have any version, and there's OpenConsole, which is probably indistinguishable from Conhost and can also have any version.

I'm aware that no check can can be 100% reliable because of SSH / telnet etc.

@alabuzhev commented on GitHub (Jun 19, 2021): Thank you, I can't reproduce it with the latest OpenConsole indeed, at least in this particular scenario. By the way, is there any "official" way to find out which host and which version of it is being used by the process? Historically checking the Windows version was enough to fine-tune and enable specific workarounds, but now there's Terminal, which theoretically can be detected by the absence of specific host features, but can have any version, and there's OpenConsole, which is probably indistinguishable from Conhost and can also have any version. I'm aware that no check can can be 100% reliable because of SSH / telnet etc.
Author
Owner

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

I think this is /dup #2191, fixed by #4668


By the way, is there any "official" way to find out which host and which version of it is being used by the process?
Historically checking the Windows version was enough to fine-tune and enable specific workarounds, but now there's Terminal, which theoretically can be detected by the absence of specific host features, but can have any version, and there's OpenConsole, which is probably indistinguishable from Conhost and can also have any version.

Not really, no. If conhost.exe is the console host, then theoretically, that'll always be the same as the OS version. The openconsole that's used with the Terminal as the console host is just "whatever is in main" for that particular Terminal version. When in the Terminal, I'd probably avoid the version checking, and just assume that the user is on the most-recent terminal version. The bug either exists in stable/preview, or is fixed. Trying to compensate for moving monthly builds would be quite a lot of work 😛

@zadjii-msft commented on GitHub (Jul 6, 2021): I think this is /dup #2191, fixed by #4668 <hr> > By the way, is there any "official" way to find out which host and which version of it is being used by the process? Historically checking the Windows version was enough to fine-tune and enable specific workarounds, but now there's Terminal, which theoretically can be detected by the absence of specific host features, but can have any version, and there's OpenConsole, which is probably indistinguishable from Conhost and can also have any version. Not really, no. If `conhost.exe` is the console host, then theoretically, that'll always be the same as the OS version. The openconsole that's used with the Terminal as the console host is just "whatever is in `main`" for that particular Terminal version. When in the Terminal, I'd probably avoid the version checking, and just assume that the user is on the most-recent terminal version. The bug either exists in stable/preview, or is fixed. Trying to compensate for moving monthly builds would be quite a lot of work 😛
Author
Owner

@ghost commented on GitHub (Jul 6, 2021):

Hi! We've identified this issue as a duplicate of another one that already exists on this Issue Tracker. This specific instance is being closed in favor of tracking the concern over on the referenced thread. Thanks for your report!

@ghost commented on GitHub (Jul 6, 2021): Hi! We've identified this issue as a duplicate of another one that already exists on this Issue Tracker. This specific instance is being closed in favor of tracking the concern over on the referenced thread. Thanks for your report!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#14265