[PATCH v7] user32: Don't save maximized position for toplevel windows covering the entire work area.

Huw Davies huw at codeweavers.com
Tue Aug 31 05:54:13 CDT 2021


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.



More information about the wine-devel mailing list