Repository: microsoft/terminal (language: cpp)

Issue:
Cursor invalidation failing when line renditions are used
### Windows Terminal version

1.21.1272.0

### Windows build number

10.0.19045.4291

### Other Software

_No response_

### Steps to reproduce

1. Open a WSL bash shell
2. Execute the following statement:
   ```
   printf "\ec\e[999B\n\e[H\e#6\n\e[1 q"; read
   ```
3. Type some text and note whether the cursor is blinking.
4. Backspace to the start of the line and check the cursor again.


### Expected Behavior

The final escape sequence in that `printf` is a `DECSCUSR` command, setting the cursor style to a blinking block, so it should be blinking the whole time (except maybe when it's actually moving).

### Actual Behavior

The cursor blinks at the start of the line, but doesn't blink in any other column. The issue isn't specifically related to blinking, though. It can also manifest as almost constant cursor "droppings", but this test case was the easiest to reproduce.

And note that it also fails on openconsole/conhost if you've configured it to use the Atlas engine, so it's not a conpty issue, but it appears to be Atlas only.

Line rendition has got something to do with it - the first line is set to double-width in this test - but it's not only the double-width line that is affected. And I think the scroll offset is also a factor, which is why this test case forces a linefeed at the bottom of the page.

As far as I can tell from a git bisect, it first broke in commit 20b0bed46df71c596b4fb68edfb6bb4b4ebf1c89 (PR #15500).



Discussion / hints:
Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

### Open similar issues:

- [Conpty cursor mispositioned when using double width lines (#15014)](https://github.com/microsoft/terminal/issues/15014),  similarity score: 0.77

### Closed similar issues:
- [Issues with cursor invalidation in GDI (#17150)](https://github.com/microsoft/terminal/issues/17150),  similarity score: 0.82
- [Cursor droppings are back in conhost (#12739)](https://github.com/microsoft/terminal/issues/12739),  similarity score: 0.78
- [Cursor droppings on wide chars in Windows Terminal (#14657)](https://github.com/microsoft/terminal/issues/14657),  similarity score: 0.77
- [More cursor droppings (#8213)](https://github.com/microsoft/terminal/issues/8213),  similarity score: 0.76

> Note: You can give me feedback by thumbs upping or thumbs downing this comment.
It looks to me like the problem is here:
https://github.com/microsoft/terminal/blob/49e4eea60f737b46b8aeda505f4693df8a9d44a6/src/renderer/base/renderer.cpp#L1179-L1182

The `_currentCursorOptions.coordCursor` value is relative to the top of the screen, while the `GetLineRendition` call is expecting a buffer row offset. 

That said, I don't think we need that call anyway, since the line renditions should already be cached in the `_currentCursorOptions` structure. Same goes for the `IsCursorDoubleWidth` call on the next line.

So unless I'm missing something, I'd suggest replacing those two lines with:
```cpp
const auto lineRendition = _currentCursorOptions.lineRendition;
const auto cursorWidth = _currentCursorOptions.fIsDoubleWidth ? 2 : 1;
```

Fix patch:
diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp
index 91e5772006e..c8ed8b28e7b 100644
--- a/src/renderer/base/renderer.cpp
+++ b/src/renderer/base/renderer.cpp
@@ -1178,8 +1178,8 @@ void Renderer::_invalidateCurrentCursor() const
     const auto view = buffer.GetSize();
     const auto coord = _currentCursorOptions.coordCursor;
 
-    const auto lineRendition = buffer.GetLineRendition(coord.y);
-    const auto cursorWidth = _pData->IsCursorDoubleWidth() ? 2 : 1;
+    const auto lineRendition = _currentCursorOptions.lineRendition;
+    const auto cursorWidth = _currentCursorOptions.fIsDoubleWidth ? 2 : 1;
 
     til::rect rect{ coord.x, coord.y, coord.x + cursorWidth, coord.y + 1 };
     rect = BufferToScreenLine(rect, lineRendition);


Test patch: