[PR #17290] Position the conpty cursor correctly when wrappedRow is set #31183

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

Original Pull Request: https://github.com/microsoft/terminal/pull/17290

State: closed
Merged: Yes


Summary of the Pull Request

If the VT render engine is moving the cursor to the start of a row, and
the previous row was marked as wrapped, it will assume that it doesn't
need to do anything, because the next output should automatically move
the cursor to the correct position anyway.

However, if that cursor movement is coming from the final PaintCursor
call for the frame, there isn't going to be any more output, so the
cursor will be left in the wrong position.

This PR fixes that issue by clearing the _wrappedRow field before the
_MoveCursor call in the PaintCursor method.

Validation Steps Performed

I've confirmed that this fixes all the test cases mentioned in issue
#17270, and issue #17013, and I've added a unit test to check the new
behavior is working as expected.

However, this change does break a couple of ConptyRoundtripTests that
were expecting the terminal row to be marked as wrapped when writing a
wrapped line in two parts using WriteCharsLegacy. This is because the
legacy way of wrapping a line isn't the same as a VT delayed wrap, so it
has to be emulated with cursor movement, and that can end up resetting
the wrap flag.

It's possible that could be fixed, but it's already broken in a number
of other ways, so I don't think this makes things much worse. For now,
I've just made the affected test cases skip the wrapping check.

PR Checklist

**Original Pull Request:** https://github.com/microsoft/terminal/pull/17290 **State:** closed **Merged:** Yes --- ## Summary of the Pull Request If the VT render engine is moving the cursor to the start of a row, and the previous row was marked as wrapped, it will assume that it doesn't need to do anything, because the next output should automatically move the cursor to the correct position anyway. However, if that cursor movement is coming from the final `PaintCursor` call for the frame, there isn't going to be any more output, so the cursor will be left in the wrong position. This PR fixes that issue by clearing the `_wrappedRow` field before the `_MoveCursor` call in the `PaintCursor` method. ## Validation Steps Performed I've confirmed that this fixes all the test cases mentioned in issue #17270, and issue #17013, and I've added a unit test to check the new behavior is working as expected. However, this change does break a couple of `ConptyRoundtripTests` that were expecting the terminal row to be marked as wrapped when writing a wrapped line in two parts using `WriteCharsLegacy`. This is because the legacy way of wrapping a line isn't the same as a VT delayed wrap, so it has to be emulated with cursor movement, and that can end up resetting the wrap flag. It's possible that could be fixed, but it's already broken in a number of other ways, so I don't think this makes things much worse. For now, I've just made the affected test cases skip the wrapping check. ## PR Checklist - [x] Closes #17013 - [x] Closes #17270 - [x] Tests added/passed
claunia added the pull-request label 2026-01-31 09:45:38 +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#31183