-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
COOKED_READ_DATA: Fix scrolling under ConPTY #15930
Conversation
1bc9a02
to
9a9cd5c
Compare
9a9cd5c
to
0e20dcd
Compare
@@ -3401,7 +3401,7 @@ void ConptyRoundtripTests::WrapNewLineAtBottomLikeMSYS() | |||
} | |||
else if (writingMethod == PrintWithWriteCharsLegacy) | |||
{ | |||
WriteCharsLegacy(si, str, true, nullptr); | |||
WriteCharsLegacy(si, str, false, nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes the tests pass. I don't think they ever relied on the interactive behavior of WriteCharsLegacy
.
@@ -752,7 +752,7 @@ void COOKED_READ_DATA::_flushBuffer() | |||
const auto distanceBeforeCursor = _writeChars(view.substr(0, _bufferCursor)); | |||
const auto distanceAfterCursor = _writeChars(view.substr(_bufferCursor)); | |||
const auto distanceEnd = distanceBeforeCursor + distanceAfterCursor; | |||
const auto eraseDistance = std::max(0, _distanceEnd - distanceEnd); | |||
const auto eraseDistance = std::max<ptrdiff_t>(0, _distanceEnd - distanceEnd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After a lot of back and forth, I went with ptrdiff_t
after all. That way we can have bigger buffers in the future and make full use of our int32_t
coordinates.
const auto initialCursorPos = cursor.GetPosition(); | ||
til::CoordType scrollY = 0; | ||
|
||
WriteCharsLegacy(_screenInfo, text, true, &scrollY); | ||
|
||
const auto finalCursorPos = cursor.GetPosition(); | ||
return (finalCursorPos.y - initialCursorPos.y + scrollY) * width + finalCursorPos.x - initialCursorPos.x; | ||
const auto distance = (finalCursorPos.y - initialCursorPos.y + scrollY) * width + finalCursorPos.x - initialCursorPos.x; | ||
assert(distance >= 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This helped me find the 2nd bug.
ptrdiff_t _distanceCursor = 0; | ||
ptrdiff_t _distanceEnd = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops. Forgot to 0 initialize.
This commit fixes 3 bugs:
COOKED_READ_DATA
failed to initialize its_distanceCursor
and_distanceEnd
members. I took this as an opportunity to make themptrdiff_t
, to reduce the likelihood of overflows in the future.COOKED_READ_DATA::_writeChars
addedscrollY
to the writtendistance, even though
WriteCharsLegacy
writes a negative value intothat out parameter. This was fixed by changing
WriteCharsLegacy
towrite positive values and by adding a debug assertion.
StreamScrollRegion
callsIncrementCircularBuffer
which causes asynchronous (!) ConPTY flush to the output pipe (side note: this is
the primary reason why newlines are so slow in ConPTY).
Since cooked reads are supposed to behave like a pager and not write
into the scrollback, we temporarily mark the buffer as inactive
which prevents
TextBuffer
from snitching about it to VtEngine.Even after this change, there's still some weird behavior left:
real pager-like implementation. That might be a neat future extension.
cursor and scroll the buffer, unless the cursor is at the end.
That might also be worth investigating in the future (minor issue).
(using Ctrl+Backspace) doesn't erase all of the affected lines,
because
COOKED_READ_DATA::_erase
uses the sameWriteCharsLegacy
function to write whitespace to erase that text. It's only gone
after typing one more character.
I've written the code to mostly fix this, but decided against it
as I considered the problem to be too niche to warrant extra code.
Closes #15899
Validation Steps Performed