On Windows, Windows with WS_THICKFRAME can be resized and can be larger than the work area, if shown afterwards. However, it does not resize them to fit the work area, but keeps them at that large size.
WMs on the other hand will try to resize the window if they can so that they fit in the work area, even if the window was larger prior. This generates ConfigureNotify events, and the window will receive size change messages after wine's X11 driver handles it, breaking some apps which don't expect them.
The caveat is that this will prevent the user from resizing the window (by e.g. dragging the corner), unlike on Windows. However, in practice, it's often hard to resize such large windows anyway.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51526 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Maybe a registry option would be more appropriate? Otherwise, some apps will always crash when managed by the WM.
dlls/winex11.drv/window.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 4e856a4..8ad018f 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -305,6 +305,31 @@ BOOL is_window_rect_full_screen( const RECT *rect ) return info.full_screen; }
+/*********************************************************************** + * prevent_wm_resize + * + * Check if we should prevent the Window Manager from resizing the window. + * WMs tend to resize windows larger than the work area so that they fit + * within it, but Windows does not. This breaks some apps which don't + * expect the resize messages to happen (e.g. The Longest Five Minutes). + */ +static BOOL prevent_wm_resize( struct x11drv_win_data *data, DWORD style ) +{ + HMONITOR monitor; + MONITORINFO mi; + + if (!(style & WS_THICKFRAME)) + return !is_window_resizable( data, style ); + + monitor = MonitorFromWindow( data->hwnd, MONITOR_DEFAULTTOPRIMARY ); + if (!monitor) return FALSE; + + mi.cbSize = sizeof( mi ); + GetMonitorInfoW( monitor, &mi ); + return data->whole_rect.right - data->whole_rect.left > mi.rcWork.right - mi.rcWork.left || + data->whole_rect.bottom - data->whole_rect.top > mi.rcWork.bottom - mi.rcWork.top; +} + /*********************************************************************** * get_mwm_decorations */ @@ -713,7 +738,7 @@ static void set_size_hints( struct x11drv_win_data *data, DWORD style ) } else size_hints->win_gravity = NorthWestGravity;
- if (!is_window_resizable( data, style )) + if (prevent_wm_resize( data, style )) { size_hints->max_width = data->whole_rect.right - data->whole_rect.left; size_hints->max_height = data->whole_rect.bottom - data->whole_rect.top;
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/user32/tests/win.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index e23ab81..ec69bad 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -8673,6 +8673,19 @@ static void test_fullscreen(void) ok(rc.bottom - rc.top == 100, "Expect height %d, got %d.\n", 100, rc.bottom - rc.top); DestroyWindow(hwnd);
+ /* Test a visible larger-than-fullscreen window with WS_THICKFRAME style, should keep its size */ + hwnd = CreateWindowA("static", NULL, WS_POPUP | WS_THICKFRAME, 0, 0, mi.rcMonitor.right + 10, + mi.rcMonitor.bottom + 10, NULL, NULL, GetModuleHandleA(NULL), NULL); + ok(!!hwnd, "CreateWindow failed, error %#x.\n", GetLastError()); + ShowWindow(hwnd, SW_SHOW); + flush_events(TRUE); + Sleep(200); + flush_events(TRUE); + GetWindowRect(hwnd, &rc); + ok(rc.right - rc.left == mi.rcMonitor.right + 10, "Expect width %d, got %d.\n", mi.rcMonitor.right + 10, rc.right - rc.left); + ok(rc.bottom - rc.top == mi.rcMonitor.bottom + 10, "Expect height %d, got %d.\n", mi.rcMonitor.bottom + 10, rc.bottom - rc.top); + DestroyWindow(hwnd); + UnregisterClassA("fullscreen_class", GetModuleHandleA(NULL)); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=98642
Your paranoid android.
=== w10pro64_zh_CN (64 bit report) ===
user32: win.c:10204: Test failed: pos = 00fa00fa win.c:10208: Test failed: pos = 00fa00fa win.c:10212: Test failed: pos = 00fa00fa