[PATCH v2 0/2] MR11131: winewayland: Some prerequistes for server side decorations
The first commit fixes maximized + fullscreen state combined; these should just be treated as fullscreen. However, we still need to do unset_maximized in this case so the actual state that we get from the compositor remains unmodified in order to undo the maximize within one configure sequence. The second commit implements min/max size hints which are useful for compositors when using server side decorations like on winex11. -- v2: winewayland: Implement min/max size hints for non-resizeable windows. winewayland: Treat maximized+fullscreen state as fullscreen. https://gitlab.winehq.org/wine/wine/-/merge_requests/11131
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_surface.c | 14 +++++++++----- dlls/winewayland.drv/window.c | 3 ++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index b2a0f9d9836..288c1ab1b04 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -484,6 +484,14 @@ BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, static enum wayland_surface_config_state mask = WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED; + /* The fullscreen state requires a size smaller or equal to the configured + * size. If we have a larger size, we can use surface geometry during + * surface reconfiguration to provide the smaller size, so we are always + * compatible with a fullscreen state. + * NOTE: Fullscreen combined with maximized is the same as fullscreen. */ + if (conf->state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN) + return TRUE; + /* We require the same state. */ if ((state & mask) != (conf->state & mask)) return FALSE; @@ -496,11 +504,6 @@ BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, return FALSE; } - /* The fullscreen state requires a size smaller or equal to the configured - * size. If we have a larger size, we can use surface geometry during - * surface reconfiguration to provide the smaller size, so we are always - * compatible with a fullscreen state. */ - return TRUE; } @@ -554,6 +557,7 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface /* If the window rect in the monitor is smaller than required, * fall back to an appropriately sized rect at the top-left. */ if ((surface->current.state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) && + !(surface->current.state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN) && (rect.right - rect.left < surface->current.width || rect.bottom - rect.top < surface->current.height)) { diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index eb0ff222bf2..e3b3b0bed46 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -620,7 +620,8 @@ static void wayland_configure_window(HWND hwnd) if (window_width == 0 || window_height == 0) flags |= SWP_NOSIZE; style = NtUserGetWindowLongW(hwnd, GWL_STYLE); - if (!(state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) != !(style & WS_MAXIMIZE)) + if (!(state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) != !(style & WS_MAXIMIZE) + && !(state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN)) NtUserSetWindowLong(hwnd, GWL_STYLE, style ^ WS_MAXIMIZE, FALSE); /* The Wayland maximized and fullscreen states are very strict about -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11131
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_surface.c | 14 ++++++++++++-- dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/window.c | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 288c1ab1b04..b8749478c53 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -579,10 +579,20 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface if (!IsRectEmpty(&rect)) { + int width = rect.right - rect.left, height = rect.bottom - rect.top; xdg_surface_set_window_geometry(surface->xdg_surface, rect.left, rect.top, - rect.right - rect.left, - rect.bottom - rect.top); + width, height); + if (surface->window.resizeable) + { + xdg_toplevel_set_min_size(surface->xdg_toplevel, 0, 0); + xdg_toplevel_set_max_size(surface->xdg_toplevel, 0, 0); + } + else + { + xdg_toplevel_set_min_size(surface->xdg_toplevel, width, height); + xdg_toplevel_set_max_size(surface->xdg_toplevel, width, height); + } } } diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 53d3dbbfb15..e572e8632a5 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -240,6 +240,7 @@ struct wayland_window_config BOOL visible; BOOL managed; BOOL minimized; + BOOL resizeable; }; struct wayland_client_surface diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index e3b3b0bed46..4cae1b76e3b 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -174,6 +174,7 @@ static void wayland_win_data_get_config(struct wayland_win_data *data, window_state |= WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED; } + conf->resizeable = !!(style & WS_THICKFRAME); conf->state = window_state; conf->scale = NtUserGetSystemDpiForProcess(0) / 96.0; conf->visible = (style & WS_VISIBLE) == WS_VISIBLE; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11131
Rémi Bernon (@rbernon) commented about dlls/winewayland.drv/window.c:
window_state |= WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED; }
+ conf->resizeable = !!(style & WS_THICKFRAME);
There is a WINE_SWP_RESIZABLE (and a WINE_SWP_FULLSCREEN) flag passed from win32u to WindowPosChanged. We use them in winex11 to decide whether a window should be resizable from the host WM point of view, and I think winewayland should do the same. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11131#note_142927
On Fri Jun 12 07:23:22 2026 +0000, Rémi Bernon wrote:
There is a WINE_SWP_RESIZABLE (and a WINE_SWP_FULLSCREEN) flag passed from win32u to WindowPosChanged. We use them in winex11 to decide whether a window should be resizable from the host WM point of view, and I think winewayland should do the same. Correct, I forgot to switch to this since this was originally written in wine 10.0 era. Sorry about that
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/11131#note_142937
participants (3)
-
Etaash Mathamsetty -
Etaash Mathamsetty (@etaash.mathamsetty) -
Rémi Bernon (@rbernon)