From f058b08fdebcbe127640482c704f56a6731f27a0 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 28 Jul 2021 17:18:58 -0500 Subject: [PATCH] Account for the window borders when restoring from fullscreen (#10737) ## Summary of the Pull Request When we're restoring from fullscreen, we do a little adjustment to make sure to clamp the window bounds within the bounds of the active monitor. We unfortunately didn't account for the size of the non-client area (the invisible borders around our 1px border). This didn't matter most of the time, but if the window was within ~8px of the side of the monitor (any side), then restoring from fullscreen would actually move it to the wrong place. As it turns out, the `_quake` window is within ~8px of the edges of the monitor _very often_. ## References * regressed in #9737 ## PR Checklist * [x] Closes #10199 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated ## Validation Steps Performed The repro in the bug was fairly straightforward. It doesn't happen anymore. --- src/cascadia/WindowsTerminal/IslandWindow.cpp | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 230b9f6bf..27ed12f1e 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -884,23 +884,39 @@ void IslandWindow::_RestoreFullscreenPosition(const RECT rcWork) rcWork.left - _rcWorkBeforeFullscreen.left, rcWork.top - _rcWorkBeforeFullscreen.top); + const til::size ncSize{ GetTotalNonClientExclusiveSize(dpiWindow) }; + + RECT rcWorkAdjusted = rcWork; + + // GH#10199 - adjust the size of the "work" rect by the size of our borders. + // We want to make sure the window is restored within the bounds of the + // monitor we're on, but it's totally fine if the invisible borders are + // outside the monitor. + const auto halfWidth{ ncSize.width() / 2 }; + const auto halfHeight{ ncSize.height() / 2 }; + + rcWorkAdjusted.left -= halfWidth; + rcWorkAdjusted.right += halfWidth; + rcWorkAdjusted.top -= halfHeight; + rcWorkAdjusted.bottom += halfHeight; + // Enforce that our position is entirely within the bounds of our work area. // Prefer the top-left be on-screen rather than bottom-right (right before left, bottom before top). - if (rcRestore.right > rcWork.right) + if (rcRestore.right > rcWorkAdjusted.right) { - OffsetRect(&rcRestore, rcWork.right - rcRestore.right, 0); + OffsetRect(&rcRestore, rcWorkAdjusted.right - rcRestore.right, 0); } - if (rcRestore.left < rcWork.left) + if (rcRestore.left < rcWorkAdjusted.left) { - OffsetRect(&rcRestore, rcWork.left - rcRestore.left, 0); + OffsetRect(&rcRestore, rcWorkAdjusted.left - rcRestore.left, 0); } - if (rcRestore.bottom > rcWork.bottom) + if (rcRestore.bottom > rcWorkAdjusted.bottom) { - OffsetRect(&rcRestore, 0, rcWork.bottom - rcRestore.bottom); + OffsetRect(&rcRestore, 0, rcWorkAdjusted.bottom - rcRestore.bottom); } - if (rcRestore.top < rcWork.top) + if (rcRestore.top < rcWorkAdjusted.top) { - OffsetRect(&rcRestore, 0, rcWork.top - rcRestore.top); + OffsetRect(&rcRestore, 0, rcWorkAdjusted.top - rcRestore.top); } // Show the window at the computed position.