Skip to content

Prevent TerminalLogger corruption during terminal resize#14370

Open
AlesProkop with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-terminal-logger-resizing-issue
Open

Prevent TerminalLogger corruption during terminal resize#14370
AlesProkop with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-terminal-logger-resizing-issue

Conversation

Copilot AI commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Work item (Internal use):

Summary

  • Poll terminal dimensions on every refresh so resizes immediately invalidate stale frame geometry.
  • Preserve the existing erase-and-redraw path when dimensions change.

Customer Impact

Shrinking a terminal during a build no longer leaves wrapped duration fragments and corrupted status output.

Regression?

No. Unchanged dimensions retain the existing delta-rendering behavior.

Testing

Added regression coverage for shrinking an active terminal from 120 to 40 columns.

Risk

Low. The change adds inexpensive terminal dimension reads to the existing 30 Hz refresh loop.

Copilot AI linked an issue Jul 15, 2026 that may be closed by this pull request
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Hello @copilot, I noticed that you’re changing an .swr file or any file under src/Package/MSBuild.VSSetup.. Please make sure to validate this change by an experimental VS insertion. This is accomplished by pushing to an exp/* branch, which requires write permissions to this repo.

Co-authored-by: AlesProkop <276576870+AlesProkop@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix terminal logger display issue when resizing Prevent TerminalLogger corruption during terminal resize Jul 15, 2026
Copilot AI requested a review from AlesProkop July 15, 2026 12:24
github-actions Bot added a commit that referenced this pull request Jul 15, 2026
Recurring reviewer feedback (PRs #14356, #14370, rainersigwald) flagged
direct terminal writes for immediate messages instead of using the
established RenderImmediateMessage path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AlesProkop
AlesProkop marked this pull request as ready for review July 17, 2026 12:25
Copilot AI review requested due to automatic review settings July 17, 2026 12:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Improves TerminalLogger’s live node display rendering stability by making refreshes always consult the current terminal dimensions so a terminal resize triggers the existing erase-and-redraw path immediately, preventing corrupted/wrapped output during active builds.

Changes:

  • Simplified the refresher thread loop to call a new Refresh() method each frame.
  • Introduced TerminalLogger.Refresh() to centralize refresh locking and ensure terminal size is checked per refresh.
  • Added a regression unit test that simulates shrinking the terminal width and asserts the logger emits the erase sequence.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/Build/Logging/TerminalLogger/TerminalLogger.cs Refactors refresher loop to refresh each frame via Refresh(), ensuring terminal resize is detected promptly.
src/Build.UnitTests/TerminalLogger_Tests.cs Adds a resizable terminal test double and a regression test for resize-triggered redraw behavior.

Comment on lines +1483 to +1492
/// <summary>
/// Refreshes the node display using the current terminal dimensions.
/// </summary>
internal void Refresh()
{
lock (_lock)
{
DisplayNodes();
}
}
public void WriteLineFitToWidth(ReadOnlySpan<char> text) => _terminal.WriteLineFitToWidth(text);
public void WriteColor(TerminalColor color, string text) => _terminal.WriteColor(color, text);
public void WriteColorLine(TerminalColor color, string text) => _terminal.WriteColorLine(color, text);
public void Dispose() => _terminal.Dispose();
Comment on lines +924 to +939
MockBuildEventSink eventSource = new(0);
TerminalLogger terminalLogger = new(terminal);
terminalLogger.Initialize(eventSource, _nodeCount);
eventSource.InvokeBuildStarted(MakeBuildStartedEventArgs());
eventSource.InvokeStatusEventRaised(MakeProjectEvalFinishedArgs(_projectFile));
eventSource.InvokeProjectStarted(MakeProjectStartedEventArgs(_projectFile));
eventSource.InvokeTargetStarted(MakeTargetStartedEventArgs(_projectFile, "Build"));
eventSource.InvokeTaskStarted(MakeTaskStartedEventArgs(_projectFile, "Task"));

terminalLogger.Refresh();
output.GetStringBuilder().Clear();
terminal.Width = 40;
terminalLogger.Refresh();

output.ToString().ShouldContain($"{AnsiCodes.CSI}{AnsiCodes.EraseInDisplay}");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resizing TerminalLogger down is ugly

3 participants