[PATCH 1/2] winex11.drv: Don't let the WM resize windows larger than the work area.

Gabriel Ivăncescu gabrielopcode at gmail.com
Thu Sep 23 09:24:45 CDT 2021


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 at 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;
-- 
2.31.1




More information about the wine-devel mailing list