From: Rémi Bernon rbernon@codeweavers.com
This prevents WMs like KWin or Mutter from automatically maximizing windows which frames are larger than their monitor area.
The maximization otherwise gets fed back into the win32 state, and often confuses applications which are operating a fullscreen window change by resizing a window then later changing its decoration.
It isn't possible to tell between a maximization initiated by the user and one that is initiated by the WM responding to a window resize from us. This heuristic should hopefully be good enough, as it is unlikely that the user will ever be able to resize a window in a such a way that its *frame* covers a monitor entirely. Note that if the user resizes a window such that its *visible* area covers a monitor entirely, we are going to make it fullscreen already anyway. --- dlls/win32u/window.c | 2 ++ dlls/winex11.drv/window.c | 3 ++- dlls/winex11.drv/x11drv.h | 1 + include/wine/gdi_driver.h | 1 + 4 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 1e86d21ae07..abd7373bc7d 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2252,11 +2252,13 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru win->has_icons = need_icons = TRUE; }
+ if (win->dwStyle & WS_THICKFRAME) swp_flags |= WINE_SWP_RESIZABLE; if (is_child) monitor_rects = map_dpi_window_rects( *new_rects, dpi, raw_dpi ); else { MONITORINFO monitor_info = monitor_info_from_rect( new_rects->window, dpi ); if (is_fullscreen( &monitor_info, &new_rects->visible )) swp_flags |= WINE_SWP_FULLSCREEN; + if (is_fullscreen( &monitor_info, &new_rects->window )) swp_flags &= ~WINE_SWP_RESIZABLE; monitor_rects = map_window_rects_virt_to_raw( *new_rects, dpi ); } } diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 251492af8d6..e66a2d75260 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -444,7 +444,7 @@ static BOOL is_window_managed( HWND hwnd, UINT swp_flags, BOOL fullscreen ) */ static inline BOOL is_window_resizable( struct x11drv_win_data *data, DWORD style ) { - if (style & WS_THICKFRAME) return TRUE; + if (data->is_resizable) return TRUE; /* Metacity needs the window to be resizable to make it fullscreen */ return data->is_fullscreen; } @@ -3131,6 +3131,7 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN was_fullscreen = data->is_fullscreen; data->rects = *new_rects; data->is_fullscreen = fullscreen; + data->is_resizable = !!(swp_flags & WINE_SWP_RESIZABLE);
TRACE( "win %p/%lx new_rects %s style %08x flags %08x\n", hwnd, data->whole_window, debugstr_window_rects(new_rects), new_style, swp_flags ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 9983d62b114..c9315934bee 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -662,6 +662,7 @@ struct x11drv_win_data UINT is_offscreen : 1; /* has been moved offscreen by the window manager */ UINT parent_invalid : 1; /* is the parent host window possibly invalid */ UINT reparenting : 1; /* window is being reparented, likely from a decoration change */ + UINT is_resizable : 1; /* window is allowed to be resized by the window manager */ Window embedder; /* window id of embedder */ Pixmap icon_pixmap; Pixmap icon_mask; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index b4880bb52eb..2c5a46768f3 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -354,6 +354,7 @@ struct gdi_device_manager
#define WINE_DM_UNSUPPORTED 0x80000000 #define WINE_SWP_FULLSCREEN 0x80000000 +#define WINE_SWP_RESIZABLE 0x40000000
struct vulkan_driver_funcs; struct opengl_driver_funcs;