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

AtlasEngine: Fix invalidation when the cursor is invisible #15904

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions src/renderer/atlas/AtlasEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,16 @@ try
{
_flushBufferLine();

// PaintCursor() is only called when the cursor is visible, but we need to invalidate the cursor area
// even if it isn't. Otherwise a transition from a visible to an invisible cursor wouldn't be rendered.
Copy link
Member Author

@lhecker lhecker Aug 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The confusing part here (at least for me) and what led to this bug, is that there's a distinction in our code between a visible cursor and a cursor that's "on". !IsCursorVisible() forces the cursor to not be drawn, but it can still be on/off when it blinks while being invisible.
...and while it blinks it still gets invalidated (why tho?).

BTW there's also IsConversionArea() which is supposed to be an invisibility flag, but it must've gotten broken at some point in conhost's rewrite to C++ so now it is visible (whoops) but unlike !IsCursorVisible() it doesn't invalidate the area being drawn, so it just happens to work (unless you invalidate the cursor).
As mentioned yesterday, the cursor code is not in a great shape right now. 🥲

if (const auto r = _api.invalidatedCursorArea; r.non_empty())
{
_p.dirtyRectInPx.left = std::min(_p.dirtyRectInPx.left, r.left * _p.s->font->cellSize.x);
_p.dirtyRectInPx.top = std::min(_p.dirtyRectInPx.top, r.top * _p.s->font->cellSize.y);
_p.dirtyRectInPx.right = std::max(_p.dirtyRectInPx.right, r.right * _p.s->font->cellSize.x);
_p.dirtyRectInPx.bottom = std::max(_p.dirtyRectInPx.bottom, r.bottom * _p.s->font->cellSize.y);
}

_api.invalidatedCursorArea = invalidatedAreaNone;
_api.invalidatedRows = invalidatedRowsNone;
_api.scrollOffset = 0;
Expand Down Expand Up @@ -423,15 +433,6 @@ try
}
}

// Clear the previous cursor
if (const auto r = _api.invalidatedCursorArea; r.non_empty())
{
_p.dirtyRectInPx.left = std::min(_p.dirtyRectInPx.left, r.left * _p.s->font->cellSize.x);
_p.dirtyRectInPx.top = std::min(_p.dirtyRectInPx.top, r.top * _p.s->font->cellSize.y);
_p.dirtyRectInPx.right = std::max(_p.dirtyRectInPx.right, r.right * _p.s->font->cellSize.x);
_p.dirtyRectInPx.bottom = std::max(_p.dirtyRectInPx.bottom, r.bottom * _p.s->font->cellSize.y);
}

if (options.isOn)
{
const auto cursorWidth = 1 + (options.fIsDoubleWidth & (options.cursorType != CursorType::VerticalBar));
Expand Down