Skip to content
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

Full-screen COLOR command no longer works right when resizing conhost and Terminal #12567

Closed
zadjii-msft opened this issue Feb 24, 2022 · 10 comments · Fixed by #12637
Closed
Assignees
Labels
Area-Output Related to output processing (inserting text into buffer, retrieving buffer text, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Product-Conhost For issues in the Console codebase Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. Tracking-External This bug isn't resolved, but it's following an external workitem. zAskModeBug zPreview-Service-Queued-1.13 A floating label that tracks the current Preview version for servicing purposes. zStable-Service-Queued-1.12 A floating label that tracks the current Stable version for servicing purposes.

Comments

@zadjii-msft
Copy link
Member

Open cmd window, set the color to 2f (green background, white text); observe the color change
Resize the window, the color changes back to black, with the "text" portion of the window still left in 2f.
This behavior can be repeated every time a resize happens.

This is the external half of MSFT:34761400

Yep, okay this is weird in conhost now. I bet this was caused by fixing #3848.

Since this one's a partner bug, we've gotta get this sorted out in this OS release.

@zadjii-msft zadjii-msft added Product-Conhost For issues in the Console codebase Area-Output Related to output processing (inserting text into buffer, retrieving buffer text, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Tracking-External This bug isn't resolved, but it's following an external workitem. zStable-Service-Queued-1.12 A floating label that tracks the current Stable version for servicing purposes. zPreview-Service-Queued-1.13 A floating label that tracks the current Preview version for servicing purposes. labels Feb 24, 2022
@zadjii-msft zadjii-msft added this to the Terminal v1.14 milestone Feb 24, 2022
@ghost ghost added the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Feb 24, 2022
@zadjii-msft zadjii-msft removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Feb 25, 2022
@zadjii-msft zadjii-msft self-assigned this Mar 1, 2022
@zadjii-msft
Copy link
Member Author

#5792

image

yes, yes it does

@zadjii-msft
Copy link
Member Author

zadjii-msft commented Mar 2, 2022

for linking: #3848

Options

zadjii-msft added a commit that referenced this issue Mar 2, 2022
…. I was worng.

  My theory was "fuck perf, let's do it right, and figure out perf later". It didn't work.
  This wraps lines super weird, probably because I'm copying the whole line to the right side of the row, which is then starting to mark it as wrapped.
  Also like the test doesn't even pass.
@zadjii-msft
Copy link
Member Author

zadjii-msft commented Mar 2, 2022

So, this is totally low key #32. It was just never a problem before, because when you'd do color 2f before, we'd start the buffer off with the attributes set to 2f, so you wouldn't notice that the colors didn't get extended to the end of the buffer. Like, if you did

wsl printf "\x1b[2Jfoo\x1b[5b\nbar\x1b[5b\nbaz\x1b[5b"

color 2f

wsl printf "\x1b[s\x1b[2;2H\x1b[41m[ FOO ]\x1b[u"

<resize window>

I bet it would have done the same thing with the red FOO line in conhost before this change. (need to find an old conhost to confirm)

That being said, people love their color commands so I guess we gotta sort this out now.

  • ❌ vb_release: image
  • ❌ rs5_release: image
  • ✅ rs4_release: image

Look, this has been busted since RS5. That's like, since October 2018. I wasn't the murderer (this time)!

zadjii-msft added a commit that referenced this issue Mar 2, 2022
  bunch of todos. It also totally takes care of #12567 as well
@j4james
Copy link
Collaborator

j4james commented Mar 2, 2022

Yeah, I was going to say I thought this was probably the same thing as #32. Will be great if we can get that fixed.

@zadjii-msft
Copy link
Member Author

Will be great if we can get that fixed.

it's my white whale 😆

@zadjii-msft
Copy link
Member Author

Yo @j4james since you've probably spent more time in the buffer than anyone else recently, would you mind taking a quick look at https://github.com/microsoft/terminal/compare/dev/migrie/b/32-attempt-2 ? I feel like I have to be missing something obvious. Like, this bug (#32) dates back to Windows 10, there's no way fixing it should be that easy. It's not perfect:

  • it's not very performant (we're already in reflow here so this is unlikely to be the worst of our worries)
  • It will still extend the attrs of the last column to the end of the row when reflowed, which can still result in some artifacts, but much less aggressive than before
    • we may be able to mitigate that by inserting a TextAttribute{} "bookend" to the end of the attr row, when we encounter the end of the old row.
  • If you have a bunch of colored spaces, then resize smaller, then resize bigger, they'll be gone (again, no worse than today)

I just feel like I must have missed something obvious. It couldn't have been that easy

@j4james
Copy link
Collaborator

j4james commented Mar 3, 2022

The first thing I noticed is that it only works as far as the last non-blank line. For example, if you do printf "\e[42m\e[2J"; sleep 10, and then resizing while it's sleeping, the whole screen goes back to black. Is that an expected limitation?

Then there were a couple of things in the code that looked wrong to me, which I suspect might fail in certain edge cases. One example being the line widths not taking line rendition into account - I'd expect us to be using the TextBuffer GetLineWidth method to determine the max width, and in the case of the old buffer, that value should already be in cOldColsTotal.

And why are we using the min of the old width and new width for the source column range? Maybe I'm missing something, but that doesn't make sense to me. I would have thought the newAttrColumn only cared about the new width and the copyAttrCol only cared about the old width?

Then, not related to this fix per se, but I noticed that the active attributes are being reset when you resize. I suspect this is because the two lines below are in the wrong order (the old attributes are restored into the buffer that's about to be replaced):

_textBuffer->SetCurrentAttributes(oldPrimaryAttributes);
_textBuffer.swap(newTextBuffer);

I should also note that I've definitely had some other things looking wrong when messing about resizing randomly, but I need to experiment some more to get reproducible test cases.

@zadjii-msft
Copy link
Member Author

The first thing I noticed is that it only works as far as the last non-blank line. For example, if you do printf "\e[42m\e[2J"; sleep 10, and then resizing while it's sleeping, the whole screen goes back to black. Is that an expected limitation?

In that branch, yea. That's one of the TODOs that definitely needs to be done 😅

Then there were a couple of things in the code that looked wrong to me, which I suspect might fail in certain edge cases. One example being the line widths not taking line rendition into account - I'd expect us to be using the TextBuffer GetLineWidth method to determine the max width, and in the case of the old buffer, that value should already be in cOldColsTotal.

See this is exactly why I asked for your help - I totally forgot about that feature entirely. That can be fixed. Thanks!

And why are we using the min of the old width and new width for the source column range? Maybe I'm missing something, but that doesn't make sense to me. I would have thought the newAttrColumn only cared about the new width and the copyAttrCol only cared about the old width?

Yea, that's an artifact from the first iteration of the fix I forgot to remove. Whoops.

This was a great sanity check! I'll patch those up and see if I can't get some tests written too. If we can confidently say that the fix is "not perfect, but definitely no worse than before", that's good enough for me frankly.


Then, not related to this fix per se, but I noticed that the active attributes are being reset when you resize. I suspect this is because the two lines below are in the wrong order (the old attributes are restored into the buffer that's about to be replaced):

holy shit you're right, that's been there since forever. I wonder if that's a bug floating around on the repo somewhere.

@ghost ghost added the In-PR This issue has a related PR label Mar 7, 2022
@ghost ghost closed this as completed in #12637 Mar 21, 2022
ghost pushed a commit that referenced this issue Mar 21, 2022
## 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
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Mar 21, 2022
DHowett pushed a commit that referenced this issue Mar 28, 2022
## 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)
DHowett pushed a commit that referenced this issue Mar 28, 2022
## 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)
@ghost
Copy link

ghost commented Apr 19, 2022

🎉This issue was addressed in #12637, which has now been successfully released as Windows Terminal v1.12.1098.:tada:

Handy links:

@ghost
Copy link

ghost commented Apr 19, 2022

🎉This issue was addressed in #12637, which has now been successfully released as Windows Terminal Preview v1.13.1098.:tada:

Handy links:

DHowett pushed a commit that referenced this issue Jun 24, 2022
## 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)
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Output Related to output processing (inserting text into buffer, retrieving buffer text, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Product-Conhost For issues in the Console codebase Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. Tracking-External This bug isn't resolved, but it's following an external workitem. zAskModeBug zPreview-Service-Queued-1.13 A floating label that tracks the current Preview version for servicing purposes. zStable-Service-Queued-1.12 A floating label that tracks the current Stable version for servicing purposes.
Projects
Status: No status
Development

Successfully merging a pull request may close this issue.

3 participants