More cursor droppings #11326

Closed
opened 2026-01-31 02:44:37 +00:00 by claunia · 2 comments
Owner

Originally created by @j4james on GitHub (Nov 10, 2020).

Environment

Windows build number: Version 10.0.18362.1082
Windows Terminal version (if applicable): commit 64aa911aee

Steps to reproduce

  1. Build a recent version of OpenConsole.
  2. Using that build, open a bash shell in conhost.
  3. Open the console properties and go to the Layout section.
  4. Uncheck the Wrap text output on resize option.
  5. Set the Screen Buffer Width to 100 and the Window Width to 80.
  6. Save these settings and then execute the following command in the bash shell:
printf "\e[2 q\e[2J\e[1;82H"; sleep 1; printf "\e[5B \b"; sleep 5

What this sequence is doing:

  1. Set the cursor to a non-blinking block so it's easier to see.
  2. Clear the screen.
  3. Move the cursor position to column 82 which forces the viewport to scroll right.
  4. Sleep for a second so the cursor becomes visible at that position.
  5. Move the cursor down a few lines.
  6. Output a space and backspace to force the cursor to redraw.
  7. Sleep a few seconds so you can see the results.

Expected behavior

When the cursor moves down, it should be erased from line 1, and then redrawn on line 5.

Actual behavior

When the cursor moves down, it isn't erased from line 1, so you end up with two copies of the cursor.

image

What's happening is that when the cursor is moved, the SetConsoleCursorPositionImpl method adjusts the viewport to make sure the new position will be visible onscreen. Before that happens, though, there's a call to SCREEN_INFORMATION::MoveToBottom which forces the viewport X coordinate to zero. So at the time of the actual move calculation, it briefly appears as if the cursor is offscreen, and thus not visible, so the code doesn't trigger a repaint.

So in step 5 of the test case, when the cursor moves down, there's no repaint to hide the old position, and also actually no repaint to render the new position. It's only the output in step 6 that forces the cursor to repaint, but by that point it's too late to erase the old cursor position.

I think the fix for this is just to make MoveToBottom preserve the current X coordinate. This would actually improve the behaviour of the unwrapped viewport in general, so either way I think it's a good thing. However, the catch is that it's then more likely for the console to trigger the crash from issue #1976, so that needs to be fixed first (I think I have a solution for that too).

Originally created by @j4james on GitHub (Nov 10, 2020). # Environment Windows build number: Version 10.0.18362.1082 Windows Terminal version (if applicable): commit 64aa911aeeaffac0e5dcd9368176483153cf5401 # Steps to reproduce 1. Build a recent version of OpenConsole. 2. Using that build, open a bash shell in conhost. 3. Open the console properties and go to the _Layout_ section. 4. Uncheck the _Wrap text output on resize_ option. 5. Set the Screen Buffer Width to 100 and the Window Width to 80. 6. Save these settings and then execute the following command in the bash shell: ```` printf "\e[2 q\e[2J\e[1;82H"; sleep 1; printf "\e[5B \b"; sleep 5 ```` What this sequence is doing: 1. Set the cursor to a non-blinking block so it's easier to see. 2. Clear the screen. 3. Move the cursor position to column 82 which forces the viewport to scroll right. 4. Sleep for a second so the cursor becomes visible at that position. 5. Move the cursor down a few lines. 6. Output a space and backspace to force the cursor to redraw. 7. Sleep a few seconds so you can see the results. # Expected behavior When the cursor moves down, it should be erased from line 1, and then redrawn on line 5. # Actual behavior When the cursor moves down, it *isn't* erased from line 1, so you end up with two copies of the cursor. ![image](https://user-images.githubusercontent.com/4181424/98683235-b5dc2900-235c-11eb-8d15-fbad00e9c0a9.png) What's happening is that when the cursor is moved, the `SetConsoleCursorPositionImpl` method adjusts the viewport to make sure the new position will be visible onscreen. Before that happens, though, there's a call to `SCREEN_INFORMATION::MoveToBottom` which forces the viewport X coordinate to zero. So at the time of the actual move calculation, it briefly appears as if the cursor is offscreen, and thus not visible, so the code doesn't trigger a repaint. So in step 5 of the test case, when the cursor moves down, there's no repaint to hide the old position, and also actually no repaint to render the new position. It's only the output in step 6 that forces the cursor to repaint, but by that point it's too late to erase the old cursor position. I think the fix for this is just to make `MoveToBottom` preserve the current X coordinate. This would actually improve the behaviour of the unwrapped viewport in general, so either way I think it's a good thing. However, the catch is that it's then more likely for the console to trigger the crash from issue #1976, so that needs to be fixed first (I think I have a solution for that too).
Author
Owner

@zadjii-msft commented on GitHub (Nov 12, 2020):

Oh gosh, welcome to the cursor turds rabbit hole 😄. Thanks for the investigation and the write up - best of luck to any who dare venture forth into madness

@zadjii-msft commented on GitHub (Nov 12, 2020): Oh gosh, welcome to the cursor turds rabbit hole 😄. Thanks for the investigation and the write up - best of luck to any who dare venture forth into madness
Author
Owner

@ghost commented on GitHub (Jan 28, 2021):

:tada:This issue was addressed in #8434, which has now been successfully released as Windows Terminal Preview v1.6.10272.0.🎉

Handy links:

@ghost commented on GitHub (Jan 28, 2021): :tada:This issue was addressed in #8434, which has now been successfully released as `Windows Terminal Preview v1.6.10272.0`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.6.10272.0) * [Store Download](https://www.microsoft.com/store/apps/9n8g5rfz9xk3?cid=storebadge&ocid=badge)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#11326