Manually copy trailing attributes on a resize#12637
Conversation
bunch of todos. It also totally takes care of #12567 as well
This comment was marked as resolved.
This comment was marked as resolved.
|
What if we resize down to the righthand edge of a color and then back to the left. Does it expand that color to the edge forever? |
|
I think I quite like it the way you have it now actually. This way if you've cleared the screen with a different background color, it should retain that color for the full width when you resize (or so I assume). But I don't think the default bookend idea would be bad either - both have their pros and cons. It's also worth noting that Gnome Terminal seems to treat cells with non-default attributes as wrappable content (even when they're just spaces). But that behaves quite weirdly when you've cleared the screen with a non-default color. I'm not a fan of that approach myself, but I don't think it's unreasonable either. |
|
BTW regarding performance: This PR increases the CPU cost of |
|
@msftbot make sure @miniksa signs off |
|
Hello @DHowett! Because you've given me some instructions on how to help merge this pull request, I'll be modifying my merge approach. Here's how I understand your requirements for merging this pull request:
If this doesn't seem right to you, you can tell me to cancel these instructions and use the auto-merge policy that has been configured for this repository. Try telling me "forget everything I just told you". |
How expensive would you estimate doing it this way would be? Code-time-wise? |
I could probably spend half a day sanity checking if that would take half a day or many days and bail if it's too hard. After {the esb bug, the nav view one, the win11 backports, the ppt} in the queue. |
I did this - thank you for bringing 61b0697 into my life. That's so so SO much faster. |
DHowett
left a comment
There was a problem hiding this comment.
I'll unmark after some questions :)
| const auto glyph = row.GetCharRow().GlyphAt(iOldCol); | ||
| const auto dbcsAttr = row.GetCharRow().DbcsAttrAt(iOldCol); | ||
| const auto textAttr = row.GetAttrRow().GetAttrByColumn(iOldCol); | ||
| const auto glyph = chars->Char(); |
There was a problem hiding this comment.
Hopefully this doesn't cause any trouble with DBCS. It might be worth just smoke testing that -- fill a buffer with U+30AB KATAKANA LETTER KA (カ) and size it around to make sure it reflows properly.
| if (iRight < cOldColsTotal && !row.WasWrapForced()) | ||
| { | ||
| if (iRight == cOldCursorPos.X && iOldRow == cOldCursorPos.Y) | ||
| if (!fFoundCursorPos && (iRight == cOldCursorPos.X && iOldRow == cOldCursorPos.Y)) |
There was a problem hiding this comment.
Unrelated condition change -- scary? I guess as long as the reflow tests still pass...
There was a problem hiding this comment.
It actually did end up being related. Because we're now also copying the trailing attrs, there was a case where we'd copy the attrs to the end of the row, but then set the new cursor position to the last column of the row the cursor was on.
(it may not be relevant anymore, but it's not more wrong.)
src/buffer/out/textBuffer.cpp
Outdated
|
|
||
| // Finish copying buffer attributes to remaining rows below the last | ||
| // printable character. This is to fix the `color 2f` scenario, where you | ||
| // change the buffer colors then resize and everything below the past |
There was a problem hiding this comment.
| // change the buffer colors then resize and everything below the past | |
| // change the buffer colors then resize and everything below the last |
There was a problem hiding this comment.
this comment suggests we'll have to inbox this change to fix COLOR
| { | ||
| auto iter = TestUtils::VerifyLineContains(tb, { 0, row }, L'#', greenAttrs, 1u); | ||
| TestUtils::VerifyLineContains(iter, L' ', (afterResize ? greenAttrs : actualDefaultAttrs), static_cast<size_t>(width - 1)); | ||
| TestUtils::VerifyLineContains(iter, L' ', (actualDefaultAttrs), static_cast<size_t>(width - 1)); |
There was a problem hiding this comment.
Confirming: this test was coded around the bad behavior, right?
| LOG_IF_FAILED(SetViewportOrigin(false, coordCursorHeightDiff, true)); | ||
|
|
||
| _textBuffer->SetCurrentAttributes(oldPrimaryAttributes); | ||
| newTextBuffer->SetCurrentAttributes(oldPrimaryAttributes); |
There was a problem hiding this comment.
HUH. This seems like an unrelated but important bug fix
There was a problem hiding this comment.
yea this was mentioned here: #12567 (comment) and in the previous reply
| // there are also 3 B's wrapped in spaces, and finally 5 trailing spaces. | ||
| Log::Comment(L"========== Checking the buffer state (after) =========="); | ||
| verifyBuffer(si.GetTextBuffer(), til::rect{ si.GetViewport().ToInclusive() }, false); | ||
| } |
There was a problem hiding this comment.
Do we need a test for the "copied the attributes after the last printable character" case?
There was a problem hiding this comment.
meh, I could write one
There was a problem hiding this comment.
I'll sign, but I would like to see that ^
|
Test harness is crashing -- not sure if it is this PR's fault |
|
Test failure is not from this PR, and is addressed in #17274 |
|
Fix the test, of course. But otherwise, I'm happy. |
|
Hello @DHowett! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
## THE WHITE WHALE This is a fairly naive fix for this bug. It's not terribly performant, but neither is resize in the first place. When the buffer gets resized, typically we only copy the text up to the `MeasureRight` point, the last printable char in the row. Then we'd just use the last char's attributes to fill the remainder of the row. Instead, this PR changes how reflow behaves when it gets to the end of the row. After we finish copying text, then manually walk through the attributes at the end of the row, and copy them over. This ensures that cells that just have a colored space in them get copied into the new buffer as well, and we don't just blat the last character's attributes into the rest of the row. We'll do a similar thing once we get to the last printable char in the buffer, copying the remaining attributes. This could DEFINITELY be more performant. I think this current implementation walks the attrs _on every cell_, then appends the new attrs to the new ATTR_ROW. That could be optimized by just using the actual iterator. The copy after the last printable char bit is also especially bad in this regard. That could likely be a blind copy - I just wanted to get this into the world. Finally, we now copy the final attributes to the correct buffer: the new one. We used to copy them to the _old_ buffer, which we were about to destroy. ## Validation I'll add more gifs in the morning, not enough time to finish spinning a release Terminal build with this tonight. Closes #32 🎉🎉🎉🎉🎉🎉🎉🎉🎉 Closes #12567 (cherry picked from commit 855e136)
## THE WHITE WHALE This is a fairly naive fix for this bug. It's not terribly performant, but neither is resize in the first place. When the buffer gets resized, typically we only copy the text up to the `MeasureRight` point, the last printable char in the row. Then we'd just use the last char's attributes to fill the remainder of the row. Instead, this PR changes how reflow behaves when it gets to the end of the row. After we finish copying text, then manually walk through the attributes at the end of the row, and copy them over. This ensures that cells that just have a colored space in them get copied into the new buffer as well, and we don't just blat the last character's attributes into the rest of the row. We'll do a similar thing once we get to the last printable char in the buffer, copying the remaining attributes. This could DEFINITELY be more performant. I think this current implementation walks the attrs _on every cell_, then appends the new attrs to the new ATTR_ROW. That could be optimized by just using the actual iterator. The copy after the last printable char bit is also especially bad in this regard. That could likely be a blind copy - I just wanted to get this into the world. Finally, we now copy the final attributes to the correct buffer: the new one. We used to copy them to the _old_ buffer, which we were about to destroy. ## Validation I'll add more gifs in the morning, not enough time to finish spinning a release Terminal build with this tonight. Closes #32 🎉🎉🎉🎉🎉🎉🎉🎉🎉 Closes #12567 (cherry picked from commit 855e136)
|
🎉 Handy links: |
|
🎉 Handy links: |
## THE WHITE WHALE This is a fairly naive fix for this bug. It's not terribly performant, but neither is resize in the first place. When the buffer gets resized, typically we only copy the text up to the `MeasureRight` point, the last printable char in the row. Then we'd just use the last char's attributes to fill the remainder of the row. Instead, this PR changes how reflow behaves when it gets to the end of the row. After we finish copying text, then manually walk through the attributes at the end of the row, and copy them over. This ensures that cells that just have a colored space in them get copied into the new buffer as well, and we don't just blat the last character's attributes into the rest of the row. We'll do a similar thing once we get to the last printable char in the buffer, copying the remaining attributes. This could DEFINITELY be more performant. I think this current implementation walks the attrs _on every cell_, then appends the new attrs to the new ATTR_ROW. That could be optimized by just using the actual iterator. The copy after the last printable char bit is also especially bad in this regard. That could likely be a blind copy - I just wanted to get this into the world. Finally, we now copy the final attributes to the correct buffer: the new one. We used to copy them to the _old_ buffer, which we were about to destroy. ## Validation I'll add more gifs in the morning, not enough time to finish spinning a release Terminal build with this tonight. Closes #32 🎉🎉🎉🎉🎉🎉🎉🎉🎉 Closes #12567 (cherry picked from commit 855e136)



THE WHITE WHALE
This is a fairly naive fix for this bug. It's not terribly performant,
but neither is resize in the first place.
When the buffer gets resized, typically we only copy the text up to the
MeasureRightpoint, the last printable char in the row. Then we'd justuse the last char's attributes to fill the remainder of the row.
Instead, this PR changes how reflow behaves when it gets to the end of
the row. After we finish copying text, then manually walk through the
attributes at the end of the row, and copy them over. This ensures that
cells that just have a colored space in them get copied into the new
buffer as well, and we don't just blat the last character's attributes
into the rest of the row. We'll do a similar thing once we get to the
last printable char in the buffer, copying the remaining attributes.
This could DEFINITELY be more performant. I think this current
implementation walks the attrs on every cell, then appends the new
attrs to the new ATTR_ROW. That could be optimized by just using the
actual iterator. The copy after the last printable char bit is also
especially bad in this regard. That could likely be a blind copy - I
just wanted to get this into the world.
Finally, we now copy the final attributes to the correct buffer: the new
one. We used to copy them to the old buffer, which we were about to
destroy.
Validation
I'll add more gifs in the morning, not enough time to finish spinning a
release Terminal build with this tonight.
Closes #32 🎉🎉🎉🎉🎉🎉🎉🎉🎉
Closes #12567