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

Gabriel Ivăncescu gabrielopcode at gmail.com
Thu Aug 26 09:59:45 CDT 2021


On 26/08/2021 09:47, Huw Davies wrote:
> On Wed, Aug 25, 2021 at 06:16:47PM +0300, Gabriel Ivăncescu wrote:
>> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51672
>> Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
> 
> I meant to mention this earlier but the commit summary message is a
> bit long.  Simply deleting the word "placement" would help.
> 
>> --- 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_maximized_area_rect
>> + *
>> + * Get the work area that a maximized window can cover, depending on style.
>> + */
>> +static BOOL get_work_rect_for_window( HWND hwnd, RECT *rect )
> 
> I'd call this get_work_rect (I don't thing the "for_window" adds anything.
> Also, note that the comment above is calling this something else.
> 
>> +{
>> +    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;
>> +}
>> +
>> +
>>   /*******************************************************************
>>    *           WINPOS_GetMinMaxInfo
>>    *
>> @@ -916,6 +929,35 @@ static POINT get_minimized_pos( HWND hwnd, POINT pt )
>>       return pt;
>>   }
>>   
>> +static void update_maximized_pos( WND *wnd )
>> +{
>> +    RECT rc_work;
>> +
>> +    /* 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.
>> +    */
>> +    if (wnd->parent && wnd->parent != GetDesktopWindow())
>> +        return;
>> +
>> +    if (wnd->dwStyle & WS_MAXIMIZE)
>> +    {
>> +        if (!get_work_rect_for_window( wnd->obj.handle, &rc_work ))
>> +            SetRect( &rc_work, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) );
> 
> As you pointed out in another email, you now have the user lock.  It
> doesn't seem very hard to avoid that, simply call get_work_rect()
> before taking the lock and pass the work rect to this function.
> There's a small wrinkle in that GetMonitorWindow() calls
> GetWindowPlacement() if the window is iconic, so you wouldn't
> want to call get_work_rect() in that case.
> 
> Huw.
> 

Thanks, I didn't really like the IsIconic thing, it seemed fragile, so I 
went with a slightly different approach, which also makes 
update_maximized_pos more typical like the other helpers, in that it 
takes a HWND rather than a WND, and does all the implementation details 
within. In one call site I just moved the call outside the lock, but for 
the other I had to release/re-acquire the lock, I hope it's not too big 
of a deal. It's still less code than special casing the work rect it in 
both callers.

I sent it so you can see if you like it better, if not I'll revert it to 
your suggestion.

Thanks,
Gabriel



More information about the wine-devel mailing list