Recalculate window size after a screen buffer resize - #20647
Open
leecher1337 wants to merge 3 commits into
Open
Conversation
SetConsoleScreenBufferSize/SetConsoleScreenBufferInfoEx only called UpdateScrollBars() after resizing the buffer, which hides or shows the scroll bar control but doesn't touch the window's outer pixel rect. Window::s_CalculateWindowRect reserves extra space for a scroll bar based on comparing the window's character size against the buffer's - if that comparison was true at some earlier point (e.g. mid-resize, while the buffer was still its old, larger size) but becomes false once the buffer catches up, the previously-reserved margin is never reclaimed, leaving a stretch of unpainted background where a scroll bar used to be needed. This is most visible with the classic safe console-resize sequence (shrink the window, resize the buffer, grow the window back if needed): if growing the window back isn't necessary because the target size doesn't exceed the window's original size, the sequence ends right after the buffer resize with no further window-size call to clean up the stale reservation. Fix: ResizeScreenBuffer also posts a window-size recalculation alongside the existing scroll bar update, so the window rect is always re-evaluated against the buffer's current (not previous) size. Gated on the same fDoScrollBarUpdate flag the scroll bar update itself already uses - callers that pass false already trigger their own window resize immediately afterward.
A small standalone console tool (src/tools/resizewindowtest) that performs the shrink-window / resize-buffer / grow-window-if-needed sequence described in the previous commit, then fills the buffer with a solid color so a reviewer can see at a glance whether stale scroll-bar-reserved space is left behind at the window's right/bottom edge - even when GetConsoleScreenBufferInfo reports the buffer and window character dimensions matching exactly. Usage: resizewindowtest.exe [width height] (defaults to 80x25, which reliably reproduces the bug without this fix - the "grow window back" step of the sequence is skipped for any target height at or below the console's default window height).
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Author
|
@microsoft-github-policy-service agree |
This comment has been minimized.
This comment has been minimized.
check-spelling flagged resizewindowtest as an unrecognized word - both in the new tool's source and, per docs.check-spelling.dev's check-file-path check, in the paths of the three files added under src/tools/resizewindowtest/.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of the Pull Request
Fixes a stale-window-space bug: after SetConsoleScreenBufferSize/SetConsoleScreenBufferInfoEx resizes the screen buffer, the
console window's outer pixel size was never re-evaluated against the new buffer dimensions. If the window had previously
reserved extra pixel space for a scroll bar (based on the buffer size at that time), and the buffer later shrinks so the scroll
bar is no longer needed, that reserved space is never reclaimed — leaving a permanent strip of unpainted background between the
actual content and the window's edge.
References and Relevant Issues
No existing tracked issue. Found while validating an unrelated console-buffer resize sequence that happened to exercise this
path.
Detailed Description of the Pull Request / Additional comments
Window::s_CalculateWindowRect (src/interactivity/win32/window.cpp) compares the window's character size against the buffer's
character size to decide whether to reserve extra pixel space for a scroll bar. SCREEN_INFORMATION::ResizeScreenBuffer
(src/host/screenInfo.cpp) calls UpdateScrollBars() after resizing the buffer, but that only shows/hides the scroll bar control —
it doesn't touch the window's outer rect. So if the reservation was computed against a stale, larger buffer size, it's only
cleaned up if a subsequent SetConsoleWindowInfo call happens to run afterward and re-triggers the rect calculation.
This is easy to hit with the standard safe console-resize sequence recommended for shrinking or growing a console (shrink window
→ resize buffer → grow window back only if the target exceeds the window's pre-resize size): whenever the final "grow" step is
skipped because it isn't needed, the sequence ends right after the buffer resize with the stale reservation never cleaned up.
Fix: ResizeScreenBuffer now also calls PostUpdateWindowSize() right after UpdateScrollBars(), gated on the same
fDoScrollBarUpdate flag the existing scroll bar update already uses — callers that pass false already trigger their own window
resize immediately afterward, so this avoids posting it twice there.
Validation Steps Performed
A reproduction tool is included in this PR (src/tools/resizewindowtest). It performs the shrink-window / resize-buffer /
grow-window-if-needed sequence described above, then fills the whole buffer with a solid color.
To reproduce:
resizewindowtest.exe (defaults to 80x25)
GetConsoleScreenBufferInfo reports the buffer and window character dimensions as identical.
change) to confirm no regression there.
PR Checklist