On Fri, Aug 27, 2021 at 08:11:15PM +0300, Gabriel Ivăncescu wrote:
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index 6e96a4b..e95f333 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -675,6 +675,33 @@ BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, }
+/******************************************************************* + * get_work_rect + * + * Get the work area that a maximized window can cover, depending on style. + */ +static BOOL get_work_rect( HWND hwnd, RECT *rect ) +{ + HMONITOR monitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY ); + MONITORINFO mon_info; + DWORD style; + + if (!monitor) return FALSE; + + mon_info.cbSize = sizeof(mon_info); + GetMonitorInfoW( monitor, &mon_info ); + + style = GetWindowLongW( hwnd, GWL_STYLE ); + *rect = mon_info.rcMonitor; + if (style & WS_MAXIMIZEBOX) + { + if ((style & WS_CAPTION) == WS_CAPTION || !(style & (WS_CHILD | WS_POPUP))) + *rect = mon_info.rcWork; + } + return TRUE; +}
I'd suggest splitting this patch into two. Adding the get_work_rect() helper in the first then adding the changes to [GS]etWindowPlacement() in the second.
+static RECT get_maximized_work_rect( HWND hwnd ) +{ + RECT work_rect = { 0 }; + + if ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_MINIMIZE | WS_MAXIMIZE)) == WS_MAXIMIZE) + { + if (!get_work_rect( hwnd, &work_rect )) + SetRect( &work_rect, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) );
Does this failure "SetRect" actually do anything? get_work_rect() is supposed to default to the primary monitor. If it really is needed shouldn't it use get_primary_monitor_rect()?
+ } + return work_rect; +} + +static void update_maximized_pos( WND *wnd, RECT *work_rect ) +{ + /* For top level windows covering the work area, we might have + to "forget" the maximized position. Windows presumably does + this to avoid situations where the border style changes, + which would lead the window to be outside the screen, or the + window gets reloaded on a different screen, and the "saved" + position no longer applies to it (despite being maximized). + + Some applications (e.g. Imperiums: Greek Wars) depend on this. + */
This sort of comment belongs above the function (like you did for get_work_rect()).
+ if (wnd->parent && wnd->parent != GetDesktopWindow()) + return; + + if (wnd->dwStyle & WS_MAXIMIZE) + { + if (wnd->window_rect.left <= work_rect->left && wnd->window_rect.top <= work_rect->top && + wnd->window_rect.right >= work_rect->right && wnd->window_rect.bottom >= work_rect->bottom) + wnd->max_pos.x = wnd->max_pos.y = -1; + } + else + wnd->max_pos.x = wnd->max_pos.y = -1; +} +
The above two helpers could be moved further down the file to just above when they're needed. (They're specific enough that nothing else is going to use them). Huw.