-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
Fix potential cursor redrawing crash #2965
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -178,6 +178,18 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting | |
proposedTop -= (proposedBottom - bufferSize.Y); | ||
} | ||
|
||
Cursor& cursor = _buffer->GetCursor(); | ||
auto cursorPosition = cursor.GetPosition(); | ||
|
||
// If the cursor is positioned beyond the range of the viewport, then | ||
// set the cursor position to a legal value. | ||
cursorPosition.X = std::min(cursorPosition.X, static_cast<SHORT>(viewportSize.X - 1)); | ||
cursorPosition.Y = std::min(cursorPosition.Y, static_cast<SHORT>(viewportSize.Y - 1)); | ||
|
||
cursor.StartDeferDrawing(); | ||
cursor.SetPosition(cursorPosition); | ||
cursor.EndDeferDrawing(); | ||
|
||
_mutableViewport = Viewport::FromDimensions({ 0, proposedTop }, viewportSize); | ||
_scrollOffset = 0; | ||
_NotifyScrollEvent(); | ||
|
@@ -425,6 +437,11 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView) | |
} | ||
} | ||
|
||
if (proposedCursorPosition.X > bufferSize.RightInclusive()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you intentionally put this back? It looks like @DHowett-MSFT just removed this in #3212 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The line the caused regression was There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This unfortunately caused #3277. |
||
{ | ||
proposedCursorPosition.X = 0; | ||
} | ||
|
||
// If we're about to scroll past the bottom of the buffer, instead cycle the buffer. | ||
const auto newRows = proposedCursorPosition.Y - bufferSize.Height() + 1; | ||
if (newRows > 0) | ||
|
@@ -533,6 +550,8 @@ void Terminal::_InitializeColorTable() | |
// - isVisible: whether the cursor should be visible | ||
void Terminal::SetCursorVisible(const bool isVisible) noexcept | ||
{ | ||
auto lock = LockForWriting(); | ||
|
||
auto& cursor = _buffer->GetCursor(); | ||
cursor.SetIsVisible(isVisible); | ||
} | ||
|
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 looks strange but it's necessary. Because
SetPosition
will callRedrawCursor
, and eventually find its way toTerminal::IsCursorDoubleWidth()
, causing the crash. So I had to disable redrawing first, correct the position, and enable redrawing. IMO theSetPosition
(and related method) are too aggresive doing redrawing, which is not a good design.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.
Yeah, you're right. We should likely fix the design on the redrawing and come up with something better. We can take this for now. I know it's ugly and complicated to fix the right way, but I'm glad you found something workable.