From b6813814d742a121181c2edd77d4e8df06eab813 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 20 Jul 2021 16:58:56 -0500 Subject: [PATCH] comments and cleanup. Fixes #10274 --- src/cascadia/WindowsTerminal/IslandWindow.cpp | 88 ++++++++++++------- src/cascadia/WindowsTerminal/IslandWindow.h | 1 - 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 18c6f3de28c..014c3e5b70d 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -510,45 +510,54 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize return 0; case WM_WINDOWPOSCHANGING: { + // GH#10274 - if the quake window gets moved to another monitor via aero + // snap (win+shift+arrows), then re-adjust the size for the new monitor. if (IsQuakeWindow()) { // Retrieve the suggested dimensions and make a rect and size. LPWINDOWPOS lpwpos = (LPWINDOWPOS)lparam; - // We only need to apply restrictions if the size is changing. - if (!WI_IsFlagSet(lpwpos->flags, SWP_NOSIZE)) + // We only need to apply restrictions if the position is changing. + // The SWP_ flags are confusing to read. This is + // "if we're not NOT moving the window" + if (!WI_IsFlagSet(lpwpos->flags, SWP_NOMOVE)) { - // Figure out the suggested dimensions + // Figure out the suggested dimensions and position. RECT rcSuggested; rcSuggested.left = lpwpos->x; rcSuggested.top = lpwpos->y; rcSuggested.right = rcSuggested.left + lpwpos->cx; rcSuggested.bottom = rcSuggested.top + lpwpos->cy; + // Find the bounds of the current monitor, and the monitor that + // we're suggested to be on. + RECT windowRect = GetWindowRect(); - HMONITOR currentMonitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONEAREST); - MONITORINFO currentMonitorInfo; - currentMonitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(currentMonitor, ¤tMonitorInfo); - - HMONITOR proposedMonitor = MonitorFromRect(&rcSuggested, MONITOR_DEFAULTTONEAREST); - MONITORINFO proposedMonitorInfo; - proposedMonitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(proposedMonitor, &proposedMonitorInfo); - - if (til::rectangle{ proposedMonitorInfo.rcMonitor } != - til::rectangle{ currentMonitorInfo.rcMonitor }) + HMONITOR current = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONEAREST); + MONITORINFO currentInfo; + currentInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(current, ¤tInfo); + + HMONITOR proposed = MonitorFromRect(&rcSuggested, MONITOR_DEFAULTTONEAREST); + MONITORINFO proposedInfo; + proposedInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(proposed, &proposedInfo); + + // If the monitor changed... + if (til::rectangle{ proposedInfo.rcMonitor } != + til::rectangle{ currentInfo.rcMonitor }) { - // _enterQuakeMode(proposedMonitor); - // til::rectangle newWindowRect{ GetWindowRect() }; - til::rectangle newWindowRect{ _getQuakeModeSize(proposedMonitor) }; + til::rectangle newWindowRect{ _getQuakeModeSize(proposed) }; + + // Inform User32 that we want to be placed at the position + // and dimensions that _getQuakeModeSize returned. When we + // snap across monitor boundaries, this will re-evaluate our + // size for the new monitor. lpwpos->x = newWindowRect.left(); lpwpos->y = newWindowRect.top(); lpwpos->cx = newWindowRect.width(); lpwpos->cy = newWindowRect.height(); - // OnSize(lpwpos->cx, lpwpos->cy); - return 0; } } @@ -1480,6 +1489,13 @@ void IslandWindow::IsQuakeWindow(bool isQuakeWindow) noexcept } } +// Method Description: +// - Enter quake mode for the monitor this window is currently on. This involves +// resizing it to the top half of the monitor. +// Arguments: +// - +// Return Value: +// - void IslandWindow::_enterQuakeMode() { if (!_window) @@ -1489,10 +1505,27 @@ void IslandWindow::_enterQuakeMode() RECT windowRect = GetWindowRect(); HMONITOR hmon = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONEAREST); - const auto newSize{ _getQuakeModeSize(hmon) }; - _enterQuakeMode(newSize); + + // Get the size and position of the window that we should occupy + const auto newRect{ _getQuakeModeSize(hmon) }; + + SetWindowPos(GetHandle(), + HWND_TOP, + newRect.left(), + newRect.top(), + newRect.width(), + newRect.height(), + SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOACTIVATE); } +// Method Description: +// - Get the size and position of the window that a "quake mode" should occupy +// on the given monitor. +// - The window will occupy the top half of the monitor. +// Arguments: +// - +// Return Value: +// - til::rectangle IslandWindow::_getQuakeModeSize(HMONITOR hmon) { MONITORINFO nearestMonitorInfo; @@ -1529,16 +1562,5 @@ til::rectangle IslandWindow::_getQuakeModeSize(HMONITOR hmon) return til::rectangle{ origin, dimensions }; } -void IslandWindow::_enterQuakeMode(const til::rectangle newRect) -{ - SetWindowPos(GetHandle(), - HWND_TOP, - newRect.left(), - newRect.top(), - newRect.width(), - newRect.height(), - SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOACTIVATE); -} - DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>); DEFINE_EVENT(IslandWindow, WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>); diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index 12f226b362f..51e57d47d02 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -114,7 +114,6 @@ class IslandWindow : void _enterQuakeMode(); til::rectangle _getQuakeModeSize(HMONITOR hmon); - void _enterQuakeMode(const til::rectangle newSize); void _summonWindowRoutineBody(winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior args);