From e1e2dae31719d56396887da373e2ca85e5f08d0b Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sun, 19 Feb 2023 19:28:08 +0100 Subject: [PATCH] Revert 104438: Windows Spanning Multiple Monitors Revert of commits that allowed non-temp Blender windows to be saved and restored that spanned multiple monitors on the Windows platform. This causes problems with temp windows (like Preferences & Render) that cannot currently be fixed. See 104956 for much more detail Differential Revision: https://projects.blender.org/blender/blender/pulls/104956 Reviewed by Ray Molenkamp --- intern/ghost/intern/GHOST_WindowWin32.cpp | 67 +++++------------------ intern/ghost/intern/GHOST_WindowWin32.h | 4 +- 2 files changed, 16 insertions(+), 55 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index ccd2980d77e..3e82f55c583 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -93,7 +93,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, } RECT win_rect = {left, top, long(left + width), long(top + height)}; - adjustWindowRectForDesktop(&win_rect, style, extended_style); + adjustWindowRectForClosestMonitor(&win_rect, style, extended_style); wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0); m_hWnd = ::CreateWindowExW(extended_style, /* window extended style */ @@ -298,55 +298,24 @@ GHOST_WindowWin32::~GHOST_WindowWin32() m_directManipulationHelper = NULL; } -void GHOST_WindowWin32::adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle) +void GHOST_WindowWin32::adjustWindowRectForClosestMonitor(LPRECT win_rect, + DWORD dwStyle, + DWORD dwExStyle) { - /* Windows can span multiple monitors, but must be usable. The desktop can have a larger - * surface than all monitors combined, for example when two monitors are aligned diagonally. - * Therefore we ensure that all the window's corners are within some monitor's Work area. */ - - POINT pt; - HMONITOR hmonitor; + /* Get Details of the closest monitor. */ + HMONITOR hmonitor = MonitorFromRect(win_rect, MONITOR_DEFAULTTONEAREST); MONITORINFOEX monitor; monitor.cbSize = sizeof(MONITORINFOEX); monitor.dwFlags = 0; - - /* We'll need this value before it is altered for checking later. */ - LONG requested_top = win_rect->top; - - /* Note that with MonitorFromPoint using MONITOR_DEFAULTTONEAREST, it will return - * the exact monitor if there is one at the location or the nearest monitor if not. */ - - /* Top-left. */ - pt.x = win_rect->left; - pt.y = win_rect->top; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); GetMonitorInfo(hmonitor, &monitor); - win_rect->top = max(win_rect->top, monitor.rcWork.top); - win_rect->left = max(win_rect->left, monitor.rcWork.left); - /* Top-right. */ - pt.x = win_rect->right; - pt.y = win_rect->top; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); - win_rect->top = max(win_rect->top, monitor.rcWork.top); - win_rect->right = min(win_rect->right, monitor.rcWork.right); - - /* Bottom-left. */ - pt.x = win_rect->left; - pt.y = win_rect->bottom; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); - win_rect->bottom = min(win_rect->bottom, monitor.rcWork.bottom); - win_rect->left = max(win_rect->left, monitor.rcWork.left); - - /* Bottom-right. */ - pt.x = win_rect->right; - pt.y = win_rect->bottom; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); - win_rect->bottom = min(win_rect->bottom, monitor.rcWork.bottom); - win_rect->right = min(win_rect->right, monitor.rcWork.right); + /* Constrain requested size and position to fit within this monitor. */ + LONG width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect->right - win_rect->left); + LONG height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect->bottom - win_rect->top); + win_rect->left = min(max(monitor.rcWork.left, win_rect->left), monitor.rcWork.right - width); + win_rect->right = win_rect->left + width; + win_rect->top = min(max(monitor.rcWork.top, win_rect->top), monitor.rcWork.bottom - height); + win_rect->bottom = win_rect->top + height; /* With Windows 10 and newer we can adjust for chrome that differs with DPI and scale. */ GHOST_WIN32_AdjustWindowRectExForDpi fpAdjustWindowRectExForDpi = nullptr; @@ -358,9 +327,6 @@ void GHOST_WindowWin32::adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyl /* Adjust to allow for caption, borders, shadows, scaling, etc. Resulting values can be * correctly outside of monitor bounds. NOTE: You cannot specify #WS_OVERLAPPED when calling. */ if (fpAdjustWindowRectExForDpi) { - /* Use the DPI of the monitor that is at the middle of the rect. */ - hmonitor = MonitorFromRect(win_rect, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); UINT dpiX, dpiY; GetDpiForMonitor(hmonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); fpAdjustWindowRectExForDpi(win_rect, dwStyle & ~WS_OVERLAPPED, FALSE, dwExStyle, dpiX); @@ -369,12 +335,7 @@ void GHOST_WindowWin32::adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyl AdjustWindowRectEx(win_rect, dwStyle & ~WS_OVERLAPPED, FALSE, dwExStyle); } - /* Don't hide the title bar. Check the working area of the monitor at the top-left corner, using - * the original top since the justWindowRects might have altered it to different monitor. */ - pt.x = win_rect->left; - pt.y = requested_top; - hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - GetMonitorInfo(hmonitor, &monitor); + /* But never allow a top position that can hide part of the title bar. */ win_rect->top = max(monitor.rcWork.top, win_rect->top); } diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index b6c4aa25c79..44071f0915e 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -87,12 +87,12 @@ class GHOST_WindowWin32 : public GHOST_Window { ~GHOST_WindowWin32(); /** - * Adjusts a requested window rect to fit and position within the desktop. + * Adjusts a requested window rect to fit and position correctly in monitor. * \param win_rect: pointer to rectangle that will be modified. * \param dwStyle: The Window Style of the window whose required size is to be calculated. * \param dwExStyle: The Extended Window Style of the window. */ - void adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle); + void adjustWindowRectForClosestMonitor(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle); /** * Returns indication as to whether the window is valid.