Skip to content

Commit 9d0180a

Browse files
authored
Fix cooked read reflow under ConPTY (#17668)
This delays the CSI J until we know the new origin of the prompt. That way it's at the right (reflowed) position. ## Validation Steps Performed * conhost * Print a ton of text * Write a prompt of a hundred chars * Resize the window very narrow / wide * Works ✅ * Windows Terminal * Write a prompt of a hundred chars * Resize the window very narrow / wide * Works ✅
1 parent 2fab986 commit 9d0180a

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

src/host/readDataCooked.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,14 @@ void COOKED_READ_DATA::EraseBeforeResize()
295295

296296
_redrawPending = true;
297297

298-
std::wstring output;
299-
_appendCUP(output, _originInViewport);
300-
output.append(L"\x1b[J");
301-
WriteCharsVT(_screenInfo, output);
298+
// Position the cursor the start of the prompt before reflow.
299+
// Then, after reflow, we'll be able to ask the buffer where it went (the new origin).
300+
// This uses the buffer APIs directly, so that we don't emit unnecessary VT into ConPTY's output.
301+
auto& textBuffer = _screenInfo.GetTextBuffer();
302+
auto& cursor = textBuffer.GetCursor();
303+
auto cursorPos = _originInViewport;
304+
_screenInfo.GetVtPageArea().ConvertFromOrigin(&cursorPos);
305+
cursor.SetPosition(cursorPos);
302306
}
303307

304308
// The counter-part to EraseBeforeResize().
@@ -322,6 +326,10 @@ void COOKED_READ_DATA::RedrawAfterResize()
322326
_bufferDirtyBeg = 0;
323327
_dirty = !_buffer.empty();
324328

329+
// Let _redisplay() know to inject a CSI J at the start of the output.
330+
// This ensures we fully erase the previous contents, that are now in disarray.
331+
_clearPending = true;
332+
325333
_redisplay();
326334
}
327335

@@ -1081,6 +1089,13 @@ void COOKED_READ_DATA::_redisplay()
10811089

10821090
std::wstring output;
10831091

1092+
if (_clearPending)
1093+
{
1094+
_clearPending = false;
1095+
_appendCUP(output, _originInViewport);
1096+
output.append(L"\x1b[J");
1097+
}
1098+
10841099
// Disable the cursor when opening a popup, reenable it when closing them.
10851100
if (const auto popupOpened = !_popups.empty(); _popupOpened != popupOpened)
10861101
{

src/host/readDataCooked.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ class COOKED_READ_DATA final : public ReadData
164164
bool _insertMode = false;
165165
bool _dirty = false;
166166
bool _redrawPending = false;
167+
bool _clearPending = false;
167168

168169
til::point _originInViewport;
169170
// This value is in the pager coordinate space. (0,0) is the first character of the

0 commit comments

Comments
 (0)