From 2291da4e4211676acd16e0850c1079a5d8dc517a Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Tue, 6 Aug 2024 00:20:06 +0200 Subject: [PATCH] Fix cooked read reflow under ConPTY --- src/host/readDataCooked.cpp | 23 +++++++++++++++++++---- src/host/readDataCooked.hpp | 1 + 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/host/readDataCooked.cpp b/src/host/readDataCooked.cpp index f67b10c3302..117482f42e8 100644 --- a/src/host/readDataCooked.cpp +++ b/src/host/readDataCooked.cpp @@ -295,10 +295,14 @@ void COOKED_READ_DATA::EraseBeforeResize() _redrawPending = true; - std::wstring output; - _appendCUP(output, _originInViewport); - output.append(L"\x1b[J"); - WriteCharsVT(_screenInfo, output); + // Position the cursor the start of the prompt before reflow. + // Then, after reflow, we'll be able to ask the buffer where it went (the new origin). + // This uses the buffer APIs directly, so that we don't emit unnecessary VT into ConPTY's output. + auto& textBuffer = _screenInfo.GetTextBuffer(); + auto& cursor = textBuffer.GetCursor(); + auto cursorPos = _originInViewport; + _screenInfo.GetVtPageArea().ConvertFromOrigin(&cursorPos); + cursor.SetPosition(cursorPos); } // The counter-part to EraseBeforeResize(). @@ -322,6 +326,10 @@ void COOKED_READ_DATA::RedrawAfterResize() _bufferDirtyBeg = 0; _dirty = !_buffer.empty(); + // Let _redisplay() know to inject a CSI J at the start of the output. + // This ensures we fully erase the previous contents, that are now in disarray. + _clearPending = true; + _redisplay(); } @@ -1081,6 +1089,13 @@ void COOKED_READ_DATA::_redisplay() std::wstring output; + if (_clearPending) + { + _clearPending = false; + _appendCUP(output, _originInViewport); + output.append(L"\x1b[J"); + } + // Disable the cursor when opening a popup, reenable it when closing them. if (const auto popupOpened = !_popups.empty(); _popupOpened != popupOpened) { diff --git a/src/host/readDataCooked.hpp b/src/host/readDataCooked.hpp index e6f35397125..ecebda49da7 100644 --- a/src/host/readDataCooked.hpp +++ b/src/host/readDataCooked.hpp @@ -164,6 +164,7 @@ class COOKED_READ_DATA final : public ReadData bool _insertMode = false; bool _dirty = false; bool _redrawPending = false; + bool _clearPending = false; til::point _originInViewport; // This value is in the pager coordinate space. (0,0) is the first character of the