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..8383c2c 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.left <= mi.rcWork.left && data->whole_rect.right >= mi.rcWork.right && + data->whole_rect.top <= mi.rcWork.top && data->whole_rect.bottom >= mi.rcWork.bottom; +} + /*********************************************************************** * 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=98630
Your paranoid android.
=== debiant2 (32 bit report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Arabic:Morocco report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Hebrew:Israel report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Hindi:India report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Japanese:Japan report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Chinese:China report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (64 bit WoW report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
Meh, it works for me, but it looks like other WMs don't. This seems to make the existing resize (via SetWindowPos) fail on the testbot WM, for some reason, it doesn't resize it anymore.
On 23/09/2021 17:43, Marvin wrote:
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=98630
Your paranoid android.
=== debiant2 (32 bit report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Arabic:Morocco report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Hebrew:Israel report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Hindi:India report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Japanese:Japan report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (32 bit Chinese:China report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.
=== debiant2 (64 bit WoW report) ===
user32: win.c:8672: Test failed: Expect width 100, got 1030. win.c:8673: Test failed: Expect height 100, got 774.