When restoring a window, so that the window gets restored to the size it currently has from the host point of view. Either the host already has restored it to its original size, or it will shortly, but we should avoid requesting config changes concurrently if possible.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 9cbf411fda3..df8f228b483 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1585,7 +1585,7 @@ static UINT window_update_client_state( struct x11drv_win_data *data )
if ((old_style & WS_MINIMIZE) && !(new_style & WS_MINIMIZE)) { - if ((old_style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) + if ((old_style & WS_CAPTION) == WS_CAPTION && (new_style & WS_MAXIMIZE)) { if ((old_style & WS_MAXIMIZEBOX) && !(old_style & WS_DISABLED)) { @@ -1609,16 +1609,30 @@ static UINT window_update_client_state( struct x11drv_win_data *data ) } }
+ if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen) + { + if ((new_style & WS_MAXIMIZE) && !(old_style & WS_MAXIMIZE)) + { + TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window ); + return SC_MAXIMIZE; + } + if (!(new_style & WS_MAXIMIZE) && (old_style & WS_MAXIMIZE)) + { + TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window ); + return SC_RESTORE; + } + } + return 0; }
static UINT window_update_client_config( struct x11drv_win_data *data ) { static const UINT fullscreen_mask = (1 << NET_WM_STATE_MAXIMIZED) | (1 << NET_WM_STATE_FULLSCREEN); - UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), flags; RECT rect, old_rect = data->rects.window, new_rect; unsigned int old_generation, generation; long old_monitors[4], monitors[4]; + UINT flags;
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */ if (is_virtual_desktop()) return 0; /* ignore window manager config changes in virtual desktop mode */ @@ -1641,20 +1655,6 @@ static UINT window_update_client_config( struct x11drv_win_data *data ) if (!memcmp( old_monitors, monitors, sizeof(monitors) )) return 0; }
- if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen) - { - if ((data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(old_style & WS_MAXIMIZE)) - { - TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window ); - return SC_MAXIMIZE; - } - if (!(data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (old_style & WS_MAXIMIZE)) - { - TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window ); - return SC_RESTORE; - } - } - flags = SWP_NOACTIVATE | SWP_NOZORDER; rect = new_rect = window_rect_from_visible( &data->rects, data->current_state.rect ); if (new_rect.left == old_rect.left && new_rect.top == old_rect.top) flags |= SWP_NOMOVE;
From: Rémi Bernon rbernon@codeweavers.com
And simply return the SWP flags from GetWindowStateUpdates. --- dlls/win32u/driver.c | 2 +- dlls/win32u/message.c | 12 ++++-------- dlls/winex11.drv/window.c | 14 +++++++------- dlls/winex11.drv/x11drv.h | 2 +- 4 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 2a269db8c65..75d45a708b1 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -875,7 +875,7 @@ static BOOL nulldrv_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, U return FALSE; }
-static BOOL nulldrv_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *config_cmd, RECT *rect, HWND *foreground ) +static BOOL nulldrv_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *swp_flags, RECT *rect, HWND *foreground ) { return FALSE; } diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index e8bbe229141..ba6299d3dcd 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2224,11 +2224,11 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR } case WM_WINE_WINDOW_STATE_CHANGED: { - UINT state_cmd, config_cmd; + UINT state_cmd, swp_flags; RECT window_rect; HWND foreground;
- if (!user_driver->pGetWindowStateUpdates( hwnd, &state_cmd, &config_cmd, &window_rect, &foreground )) return 0; + if (!user_driver->pGetWindowStateUpdates( hwnd, &state_cmd, &swp_flags, &window_rect, &foreground )) return 0; if (foreground) NtUserSetForegroundWindow( foreground ); if (state_cmd) { @@ -2236,15 +2236,11 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 );
/* state change might have changed the window config already, check again */ - user_driver->pGetWindowStateUpdates( hwnd, &state_cmd, &config_cmd, &window_rect, &foreground ); + user_driver->pGetWindowStateUpdates( hwnd, &state_cmd, &swp_flags, &window_rect, &foreground ); if (foreground) NtUserSetForegroundWindow( foreground ); if (state_cmd) WARN( "window %p state needs another update, ignoring\n", hwnd ); } - if (config_cmd) - { - if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, window_rect, HIWORD(config_cmd), FALSE ); - else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 ); - } + if (swp_flags) NtUserSetRawWindowPos( hwnd, window_rect, swp_flags, FALSE ); return 0; } case WM_WINE_UPDATEWINDOWSTATE: diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index df8f228b483..a042ac9bc52 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1672,19 +1672,19 @@ static UINT window_update_client_config( struct x11drv_win_data *data )
TRACE( "window %p/%lx config changed %s -> %s, flags %#x\n", data->hwnd, data->whole_window, wine_dbgstr_rect(&old_rect), wine_dbgstr_rect(&new_rect), flags ); - return MAKELONG(SC_MOVE, flags); + return flags; }
/*********************************************************************** * GetWindowStateUpdates (X11DRV.@) */ -BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *config_cmd, RECT *rect, HWND *foreground ) +BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *swp_flags, RECT *rect, HWND *foreground ) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); struct x11drv_win_data *data; HWND old_foreground;
- *state_cmd = *config_cmd = 0; + *state_cmd = *swp_flags = 0; *foreground = 0;
if (!(old_foreground = NtUserGetForegroundWindow())) old_foreground = NtUserGetDesktopWindow(); @@ -1699,14 +1699,14 @@ BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *config_cmd, if ((data = get_win_data( hwnd ))) { *state_cmd = window_update_client_state( data ); - *config_cmd = window_update_client_config( data ); + *swp_flags = window_update_client_config( data ); *rect = window_rect_from_visible( &data->rects, data->current_state.rect ); release_win_data( data ); }
- if (!*state_cmd && !*config_cmd && !*foreground) return FALSE; - TRACE( "hwnd %p, returning state_cmd %#x, config_cmd %#x, rect %s, foreground %p\n", - hwnd, *state_cmd, *config_cmd, wine_dbgstr_rect(rect), *foreground ); + if (!*state_cmd && !*swp_flags && !*foreground) return FALSE; + TRACE( "hwnd %p, returning state_cmd %#x, swp_flags %#x, rect %s, foreground %p\n", + hwnd, *state_cmd, *swp_flags, wine_dbgstr_rect(rect), *foreground ); return TRUE; }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index fdd4534a626..63d6a316642 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -243,7 +243,7 @@ extern void X11DRV_UpdateLayeredWindow( HWND hwnd, BYTE alpha, UINT flags ); extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); extern BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ); -extern BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *config_cmd, RECT *rect, HWND *foreground ); +extern BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *swp_flags, RECT *rect, HWND *foreground ); extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *old_rects, const struct window_rects *new_rects, const RECT *valid_rects );
From: Rémi Bernon rbernon@codeweavers.com
When restoring a window, so that the window gets restored to the size it currently has from the host point of view. Either the host already has restored it to its original size, or it will shortly, but we should avoid requesting config changes concurrently if possible.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58804 --- dlls/win32u/message.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index ba6299d3dcd..a38ac1eff77 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2229,18 +2229,27 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR HWND foreground;
if (!user_driver->pGetWindowStateUpdates( hwnd, &state_cmd, &swp_flags, &window_rect, &foreground )) return 0; + window_rect = map_rect_raw_to_virt( window_rect, get_thread_dpi() ); + if (foreground) NtUserSetForegroundWindow( foreground ); - if (state_cmd) + switch (LOWORD(state_cmd)) { - if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd ); + case SC_MAXIMIZE: + case SC_MINIMIZE: send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 ); - - /* state change might have changed the window config already, check again */ - user_driver->pGetWindowStateUpdates( hwnd, &state_cmd, &swp_flags, &window_rect, &foreground ); - if (foreground) NtUserSetForegroundWindow( foreground ); - if (state_cmd) WARN( "window %p state needs another update, ignoring\n", hwnd ); + break; + case SC_RESTORE: + if (HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd ); + NtUserSetInternalWindowPos( hwnd, SW_SHOW, &window_rect, NULL ); + send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 ); + break; + default: + if (!swp_flags) break; + NtUserSetWindowPos( hwnd, 0, window_rect.left, window_rect.top, window_rect.right - window_rect.left, + window_rect.bottom - window_rect.top, swp_flags ); + break; } - if (swp_flags) NtUserSetRawWindowPos( hwnd, window_rect, swp_flags, FALSE ); + return 0; } case WM_WINE_UPDATEWINDOWSTATE:
This merge request was approved by Huw Davies.