[PATCH v2 0/6] MR11321: Draft: winewayland: surface config refactoring
This MR fixes race conditions in the fractional scaling implementation by moving the scale value to the surface config. In addition to avoiding the aforementioned race conditions, it also enables us to store the win32u unscaled rect within the surface config (that is not within this MR, though). It is based on some of the other refactoring present in !11248 This approach makes winewayland ignore the scale event until the next xdg_surface::configure. Since the scale factor is just a suggestion from the compositor to the client, we don't need to follow it strictly. I need to test this with more compositors, but I don't see why they wouldn't send fractional scale events (as needed) with configure events. Draft because still need to figure out how to deal with subsurface scaling using this approach -- v2: winewayland: Move scale to surface config. https://gitlab.winehq.org/wine/wine/-/merge_requests/11321
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_surface.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index c2b4c4be891..f7f0f094645 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -638,19 +638,15 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface } TRACE("Window is too large for Wayland state, using subregion\n"); } - else - { - OffsetRect(&rect, -rect.left, -rect.top); - } TRACE("hwnd=%p geometry=%s\n", surface->hwnd, wine_dbgstr_rect(&rect)); 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, - width, height); + + xdg_surface_set_window_geometry(surface->xdg_surface, 0, 0, width, height); + if (surface->window.resizeable) { xdg_toplevel_set_min_size(surface->xdg_toplevel, 0, 0); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11321
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winewayland.drv/wayland_surface.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index f7f0f094645..d64c21b30dd 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -543,6 +543,16 @@ void wayland_surface_attach_shm(struct wayland_surface *surface, surface->content_height = win_height; } +static BOOL is_rect_bigger(RECT a, RECT b) +{ + return a.right - a.left > b.right - b.left || a.bottom - a.top > b.bottom - b.top; +} + +static BOOL is_rect_smaller(RECT a, RECT b) +{ + return a.right - a.left < b.right - b.left || a.bottom - a.top < b.bottom - b.top; +} + /********************************************************************** * wayland_surface_config_is_compatible * @@ -569,12 +579,7 @@ BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, R /* The maximized state requires the configured size. During surface * reconfiguration we can use surface geometry to provide smaller areas * from larger sizes, so only smaller sizes are incompatible. */ - if ((conf->state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) && - (rect.right - rect.left < conf->rect.right - conf->rect.left || - rect.bottom - rect.top < conf->rect.bottom - conf->rect.top)) - { - return FALSE; - } + if ((conf->state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) && is_rect_smaller(rect, conf->rect)) return FALSE; return TRUE; } @@ -614,8 +619,7 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface * largest visible (from Windows' perspective) subregion of the window. */ if ((surface->current.state & (WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED | WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN)) && - (rect.right - rect.left > surface->current.rect.right - surface->current.rect.left || - rect.bottom - rect.top > surface->current.rect.bottom - surface->current.rect.top)) + is_rect_bigger(rect, surface->current.rect)) { wayland_surface_get_rect_in_monitor(surface, &rect); @@ -625,8 +629,7 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface * 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.rect.right - surface->current.rect.left || - rect.bottom - rect.top < surface->current.rect.bottom - surface->current.rect.top)) + is_rect_smaller(rect, surface->current.rect)) { SetRect(&rect, 0, 0, surface->current.rect.right - surface->current.rect.left, surface->current.rect.bottom - surface->current.rect.top); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11321
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winewayland.drv/wayland_surface.c | 44 +++++++++++--------------- dlls/winewayland.drv/waylanddrv.h | 3 +- dlls/winewayland.drv/window.c | 7 ++-- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index d64c21b30dd..f51fcd97142 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -559,11 +559,9 @@ static BOOL is_rect_smaller(RECT a, RECT b) * Checks whether a wayland_surface_config object is compatible with the * the provided arguments. */ -BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, RECT rect, - enum wayland_surface_config_state state) +BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struct wayland_surface_config *conf) { - static enum wayland_surface_config_state mask = - WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED; + RECT rect = map_rect_to_surface(surface, surface->window.rect); /* 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 @@ -574,7 +572,7 @@ BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, R return TRUE; /* We require the same state. */ - if ((state & mask) != (conf->state & mask)) return FALSE; + if ((surface->window.state ^ conf->state) & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) return FALSE; /* The maximized state requires the configured size. During surface * reconfiguration we can use surface geometry to provide smaller areas @@ -613,8 +611,10 @@ static void wayland_surface_get_rect_in_monitor(struct wayland_surface *surface, * * Sets the xdg_surface geometry */ -static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface, RECT rect) +static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface) { + RECT rect = map_rect_to_surface(surface, surface->window.rect); + /* If the window size is bigger than the current state accepts, use the * largest visible (from Windows' perspective) subregion of the window. */ if ((surface->current.state & (WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED | @@ -668,10 +668,12 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface * * Sets the surface size with viewporter */ -static void wayland_surface_reconfigure_size(struct wayland_surface *surface, - int width, int height) +static void wayland_surface_reconfigure_size(struct wayland_surface *surface) { - TRACE("hwnd=%p size=%dx%d\n", surface->hwnd, width, height); + RECT rect = map_rect_to_surface(surface, surface->window.rect); + int width = rect.right - rect.left, height = rect.bottom - rect.top; + + TRACE("hwnd=%p rect=%s\n", surface->hwnd, wine_dbgstr_rect(&rect)); if (width != 0 && height != 0) wp_viewport_set_destination(surface->wp_viewport, width, height); @@ -719,14 +721,11 @@ static void wayland_surface_reconfigure_client(struct wayland_surface *surface, * Reconfigures the xdg surface as needed to match the latest requested * state. */ -static BOOL wayland_surface_reconfigure_xdg(struct wayland_surface *surface, RECT rect) +static BOOL wayland_surface_reconfigure_xdg(struct wayland_surface *surface) { - struct wayland_window_config *window = &surface->window; - /* Acknowledge any compatible processed config. */ if (surface->processing.serial && surface->processing.processed && - wayland_surface_config_is_compatible(&surface->processing, rect, - window->state)) + wayland_surface_config_is_compatible(surface, &surface->processing)) { surface->current = surface->processing; memset(&surface->processing, 0, sizeof(surface->processing)); @@ -736,21 +735,19 @@ static BOOL wayland_surface_reconfigure_xdg(struct wayland_surface *surface, REC * config, use that, in order to draw windows that don't go through the * message loop (e.g., some splash screens). */ else if (!surface->current.serial && surface->requested.serial && - wayland_surface_config_is_compatible(&surface->requested, rect, - window->state)) + wayland_surface_config_is_compatible(surface, &surface->requested)) { surface->current = surface->requested; memset(&surface->requested, 0, sizeof(surface->requested)); xdg_surface_ack_configure(surface->xdg_surface, surface->current.serial); } else if (!surface->current.serial || - !wayland_surface_config_is_compatible(&surface->current, rect, - window->state)) + !wayland_surface_config_is_compatible(surface, &surface->current)) { return FALSE; } - wayland_surface_reconfigure_geometry(surface, rect); + wayland_surface_reconfigure_geometry(surface); return TRUE; } @@ -799,11 +796,8 @@ static void wayland_surface_reconfigure_subsurface(struct wayland_surface *surfa */ BOOL wayland_surface_reconfigure(struct wayland_surface *surface) { - struct wayland_window_config *window = &surface->window; - RECT rect = map_rect_to_surface(surface, surface->window.rect); - TRACE("hwnd=%p window=%s,%#x processing=%s,%#x current=%s,%#x\n", - surface->hwnd, wine_dbgstr_rect(&rect), window->state, + surface->hwnd, wine_dbgstr_rect(&surface->window.rect), surface->window.state, wine_dbgstr_rect(&surface->processing.rect), surface->processing.state, wine_dbgstr_rect(&surface->current.rect), surface->current.state); @@ -813,7 +807,7 @@ BOOL wayland_surface_reconfigure(struct wayland_surface *surface) break; case WAYLAND_SURFACE_ROLE_TOPLEVEL: if (!surface->xdg_surface) break; /* surface role has been cleared */ - if (!wayland_surface_reconfigure_xdg(surface, rect)) return FALSE; + if (!wayland_surface_reconfigure_xdg(surface)) return FALSE; break; case WAYLAND_SURFACE_ROLE_SUBSURFACE: if (!surface->wl_subsurface) break; /* surface role has been cleared */ @@ -821,7 +815,7 @@ BOOL wayland_surface_reconfigure(struct wayland_surface *surface) break; } - wayland_surface_reconfigure_size(surface, rect.right - rect.left, rect.bottom - rect.top); + wayland_surface_reconfigure_size(surface); return TRUE; } diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index da166c939d4..1aae646d2a9 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -332,8 +332,7 @@ void wayland_surface_attach_shm(struct wayland_surface *surface, struct wayland_shm_buffer *shm_buffer, HRGN surface_damage_region); BOOL wayland_surface_reconfigure(struct wayland_surface *surface); -BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, RECT rect, - enum wayland_surface_config_state state); +BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struct wayland_surface_config *conf); RECT map_rect_to_surface(struct wayland_surface *surface, RECT rect); POINT map_point_to_surface(struct wayland_surface *surface, POINT point); RECT map_rect_from_surface(struct wayland_surface *surface, RECT rect); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 55385eb3772..2f6f8adf3ca 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -481,7 +481,7 @@ static void wayland_configure_window(HWND hwnd) BOOL needs_exit_size_move = FALSE; BOOL restoring_from_minimize = FALSE; struct wayland_win_data *data; - RECT rect, surface_rect; + RECT rect; if (!(data = wayland_win_data_get(hwnd))) return; if (!(surface = data->wayland_surface)) @@ -540,15 +540,12 @@ static void wayland_configure_window(HWND hwnd) flags |= SWP_FRAMECHANGED; } - surface_rect = map_rect_to_surface(surface, surface->window.rect); - /* If the window is already fullscreen and its size is compatible with what * the compositor is requesting, don't force a resize, since some applications * are very insistent on a particular fullscreen size (which may not match * the monitor size). */ if ((surface->window.state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN) && - wayland_surface_config_is_compatible(&surface->processing, surface_rect, - surface->window.state)) + wayland_surface_config_is_compatible(surface, &surface->processing)) { flags |= SWP_NOSIZE; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11321
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winewayland.drv/window.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 2f6f8adf3ca..000f8001710 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -473,8 +473,7 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UIN static void wayland_configure_window(HWND hwnd) { struct wayland_surface *surface; - INT width, height; - UINT flags = 0; + UINT flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE; uint32_t state; DWORD style; BOOL needs_enter_size_move = FALSE; @@ -507,18 +506,12 @@ static void wayland_configure_window(HWND hwnd) surface->processing = surface->requested; memset(&surface->requested, 0, sizeof(surface->requested)); + rect = map_rect_from_surface(surface, surface->processing.rect); state = surface->processing.state; + /* Ignore size hints if we don't have a state that requires strict * size adherence, in order to avoid spurious resizes. */ - if (state) - { - width = surface->processing.rect.right - surface->processing.rect.left; - height = surface->processing.rect.bottom - surface->processing.rect.top; - } - else - { - width = height = 0; - } + if (!state) flags |= SWP_NOSIZE; if ((state & WAYLAND_SURFACE_CONFIG_STATE_RESIZING) && !surface->resizing) { @@ -572,20 +565,13 @@ static void wayland_configure_window(HWND hwnd) return; } - SetRect(&rect, 0, 0, width, height); - rect = map_rect_from_surface(surface, rect); - OffsetRect(&rect, data->rects.window.left, data->rects.window.top); - wayland_win_data_release(data); - TRACE("processing=%dx%d,%#x\n", width, height, state); + TRACE("processing rect=%s state=%#x flags=%#x\n", wine_dbgstr_rect(&rect), state, flags); if (needs_enter_size_move) send_message(hwnd, WM_ENTERSIZEMOVE, 0, 0); if (needs_exit_size_move) send_message(hwnd, WM_EXITSIZEMOVE, 0, 0); - flags |= SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE; - if (rect.left == rect.right || rect.bottom == rect.top) flags |= SWP_NOSIZE; - style = NtUserGetWindowLongW(hwnd, GWL_STYLE); if (!(state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) != !(style & WS_MAXIMIZE) && !(state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN)) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11321
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winewayland.drv/wayland_surface.c | 33 ++++++++++--------- dlls/winewayland.drv/waylanddrv.h | 30 ++++++++++-------- dlls/winewayland.drv/window.c | 44 +++++++++++++------------- 3 files changed, 57 insertions(+), 50 deletions(-) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index f51fcd97142..7ccdf2998d9 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -83,43 +83,46 @@ static void xdg_toplevel_handle_configure(void *private, int32_t width, int32_t height, struct wl_array *states) { + RECT rect; + enum surface_state config_state = 0; struct wayland_surface *surface; HWND hwnd = private; uint32_t *state; - enum wayland_surface_config_state config_state = 0; struct wayland_win_data *data; + SetRect(&rect, 0, 0, width, height); + wl_array_for_each(state, states) { switch(*state) { case XDG_TOPLEVEL_STATE_MAXIMIZED: - config_state |= WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED; + config_state |= SURFACE_STATE_MAXIMIZED; break; case XDG_TOPLEVEL_STATE_RESIZING: - config_state |= WAYLAND_SURFACE_CONFIG_STATE_RESIZING; + config_state |= SURFACE_STATE_RESIZING; break; case XDG_TOPLEVEL_STATE_TILED_LEFT: case XDG_TOPLEVEL_STATE_TILED_RIGHT: case XDG_TOPLEVEL_STATE_TILED_TOP: case XDG_TOPLEVEL_STATE_TILED_BOTTOM: - config_state |= WAYLAND_SURFACE_CONFIG_STATE_TILED; + config_state |= SURFACE_STATE_TILED; break; case XDG_TOPLEVEL_STATE_FULLSCREEN: - config_state |= WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN; + config_state |= SURFACE_STATE_FULLSCREEN; break; default: break; } } - TRACE("hwnd=%p %dx%d,%#x\n", hwnd, width, height, config_state); + TRACE("hwnd=%p rect=%s state=%#x\n", hwnd, wine_dbgstr_rect(&rect), config_state); if (!(data = wayland_win_data_get(hwnd))) return; if ((surface = data->wayland_surface) && wayland_surface_is_toplevel(surface)) { - SetRect(&surface->pending.rect, 0, 0, width, height); + surface->pending.rect = rect; surface->pending.state = config_state; } @@ -559,7 +562,7 @@ static BOOL is_rect_smaller(RECT a, RECT b) * Checks whether a wayland_surface_config object is compatible with the * the provided arguments. */ -BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struct wayland_surface_config *conf) +BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struct surface_config *conf) { RECT rect = map_rect_to_surface(surface, surface->window.rect); @@ -568,16 +571,16 @@ BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struc * 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) + if (conf->state & SURFACE_STATE_FULLSCREEN) return TRUE; /* We require the same state. */ - if ((surface->window.state ^ conf->state) & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) return FALSE; + if ((surface->window.state ^ conf->state) & SURFACE_STATE_MAXIMIZED) return FALSE; /* The maximized state requires the configured size. During surface * reconfiguration we can use surface geometry to provide smaller areas * from larger sizes, so only smaller sizes are incompatible. */ - if ((conf->state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) && is_rect_smaller(rect, conf->rect)) return FALSE; + if ((conf->state & SURFACE_STATE_MAXIMIZED) && is_rect_smaller(rect, conf->rect)) return FALSE; return TRUE; } @@ -617,8 +620,8 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface /* If the window size is bigger than the current state accepts, use the * largest visible (from Windows' perspective) subregion of the window. */ - if ((surface->current.state & (WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED | - WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN)) && + if ((surface->current.state & (SURFACE_STATE_MAXIMIZED | + SURFACE_STATE_FULLSCREEN)) && is_rect_bigger(rect, surface->current.rect)) { wayland_surface_get_rect_in_monitor(surface, &rect); @@ -627,8 +630,8 @@ 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) && + if ((surface->current.state & SURFACE_STATE_MAXIMIZED) && + !(surface->current.state & SURFACE_STATE_FULLSCREEN) && is_rect_smaller(rect, surface->current.rect)) { SetRect(&rect, 0, 0, surface->current.rect.right - surface->current.rect.left, diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 1aae646d2a9..551f14e76e9 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -72,12 +72,12 @@ enum wayland_window_message WM_WAYLAND_SET_FOREGROUND, }; -enum wayland_surface_config_state +enum surface_state { - WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED = (1 << 0), - WAYLAND_SURFACE_CONFIG_STATE_RESIZING = (1 << 1), - WAYLAND_SURFACE_CONFIG_STATE_TILED = (1 << 2), - WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN = (1 << 3) + SURFACE_STATE_MAXIMIZED = (1 << 0), + SURFACE_STATE_RESIZING = (1 << 1), + SURFACE_STATE_TILED = (1 << 2), + SURFACE_STATE_FULLSCREEN = (1 << 3) }; enum wayland_surface_role @@ -224,19 +224,19 @@ struct wayland_output struct wayland_output_state current; }; -struct wayland_surface_config +struct surface_config { - RECT rect; - enum wayland_surface_config_state state; - uint32_t serial; - BOOL processed; + RECT rect; /* rect of the compositor surface (in surface coordinates) */ + enum surface_state state; /* state of the compositor surface */ + uint32_t serial; /* serial of the corresponding xdg_surface_configure event */ + BOOL processed; /* config has been fully applied to the surface win32 window */ }; struct wayland_window_config { RECT rect; RECT client_rect; - enum wayland_surface_config_state state; + enum surface_state state; /* The scale (i.e., normalized dpi) the window is rendering at. */ double scale; BOOL visible; @@ -297,7 +297,11 @@ struct wayland_surface }; struct wp_alpha_modifier_surface_v1 *wp_alpha_modifier_surface_v1; - struct wayland_surface_config pending, requested, processing, current; + struct surface_config pending; /* incomplete surface config being received from the compositor */ + struct surface_config requested; /* latest complete surface config received from the compositor */ + struct surface_config processing; /* surface config being applied to the surface win32 window */ + struct surface_config current; /* latest config that has been applied to the surface win32 window */ + BOOL resizing; struct wayland_window_config window; int content_width, content_height; @@ -332,7 +336,7 @@ void wayland_surface_attach_shm(struct wayland_surface *surface, struct wayland_shm_buffer *shm_buffer, HRGN surface_damage_region); BOOL wayland_surface_reconfigure(struct wayland_surface *surface); -BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struct wayland_surface_config *conf); +BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struct surface_config *conf); RECT map_rect_to_surface(struct wayland_surface *surface, RECT rect); POINT map_point_to_surface(struct wayland_surface *surface, POINT point); RECT map_rect_from_surface(struct wayland_surface *surface, RECT rect); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 000f8001710..b3cc1e135aa 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -135,7 +135,7 @@ void wayland_win_data_release(struct wayland_win_data *data) static void wayland_win_data_get_config(struct wayland_win_data *data, struct wayland_window_config *conf) { - enum wayland_surface_config_state window_state = 0; + enum surface_state window_state = 0; DWORD style; conf->rect = data->rects.window; @@ -150,13 +150,13 @@ static void wayland_win_data_get_config(struct wayland_win_data *data, if (data->is_fullscreen) { if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION) - window_state |= WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED; + window_state |= SURFACE_STATE_MAXIMIZED; else if (!(style & WS_MINIMIZE)) - window_state |= WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN; + window_state |= SURFACE_STATE_FULLSCREEN; } else if (style & WS_MAXIMIZE) { - window_state |= WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED; + window_state |= SURFACE_STATE_MAXIMIZED; } conf->resizeable = data->resizeable; @@ -254,26 +254,26 @@ static void wayland_surface_update_state_toplevel(struct wayland_surface *surfac { /* First do all state unsettings, before setting new state. Some * Wayland compositors misbehave if the order is reversed. */ - if (!(surface->window.state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) && - (surface->current.state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) && + if (!(surface->window.state & SURFACE_STATE_MAXIMIZED) && + (surface->current.state & SURFACE_STATE_MAXIMIZED) && !surface->window.minimized) { xdg_toplevel_unset_maximized(surface->xdg_toplevel); } - if (!(surface->window.state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN) && - (surface->current.state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN) && + if (!(surface->window.state & SURFACE_STATE_FULLSCREEN) && + (surface->current.state & SURFACE_STATE_FULLSCREEN) && !surface->window.minimized) { xdg_toplevel_unset_fullscreen(surface->xdg_toplevel); } - if ((surface->window.state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) && - !(surface->current.state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED)) + if ((surface->window.state & SURFACE_STATE_MAXIMIZED) && + !(surface->current.state & SURFACE_STATE_MAXIMIZED)) { xdg_toplevel_set_maximized(surface->xdg_toplevel); } - if ((surface->window.state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN) && - !(surface->current.state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN)) + if ((surface->window.state & SURFACE_STATE_FULLSCREEN) && + !(surface->current.state & SURFACE_STATE_FULLSCREEN)) { xdg_toplevel_set_fullscreen(surface->xdg_toplevel, NULL); } @@ -513,13 +513,13 @@ static void wayland_configure_window(HWND hwnd) * size adherence, in order to avoid spurious resizes. */ if (!state) flags |= SWP_NOSIZE; - if ((state & WAYLAND_SURFACE_CONFIG_STATE_RESIZING) && !surface->resizing) + if ((state & SURFACE_STATE_RESIZING) && !surface->resizing) { surface->resizing = TRUE; needs_enter_size_move = TRUE; } - if (!(state & WAYLAND_SURFACE_CONFIG_STATE_RESIZING) && surface->resizing) + if (!(state & SURFACE_STATE_RESIZING) && surface->resizing) { surface->resizing = FALSE; needs_exit_size_move = TRUE; @@ -527,8 +527,8 @@ static void wayland_configure_window(HWND hwnd) /* Transitions between normal/max/fullscreen may entail a frame change. */ if ((state ^ surface->current.state) & - (WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED | - WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN)) + (SURFACE_STATE_MAXIMIZED | + SURFACE_STATE_FULLSCREEN)) { flags |= SWP_FRAMECHANGED; } @@ -537,7 +537,7 @@ static void wayland_configure_window(HWND hwnd) * the compositor is requesting, don't force a resize, since some applications * are very insistent on a particular fullscreen size (which may not match * the monitor size). */ - if ((surface->window.state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN) && + if ((surface->window.state & SURFACE_STATE_FULLSCREEN) && wayland_surface_config_is_compatible(surface, &surface->processing)) { flags |= SWP_NOSIZE; @@ -573,17 +573,17 @@ static void wayland_configure_window(HWND hwnd) if (needs_exit_size_move) send_message(hwnd, WM_EXITSIZEMOVE, 0, 0); style = NtUserGetWindowLongW(hwnd, GWL_STYLE); - if (!(state & WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED) != !(style & WS_MAXIMIZE) - && !(state & WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN)) + if (!(state & SURFACE_STATE_MAXIMIZED) != !(style & WS_MAXIMIZE) + && !(state & SURFACE_STATE_FULLSCREEN)) NtUserSetWindowLong(hwnd, GWL_STYLE, style ^ WS_MAXIMIZE, FALSE); /* The Wayland maximized and fullscreen states are very strict about * surface size, so don't let the application override it. The tiled state * is not as strict, but it indicates a strong size preference, so try to * respect it. */ - if (state & (WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED | - WAYLAND_SURFACE_CONFIG_STATE_FULLSCREEN | - WAYLAND_SURFACE_CONFIG_STATE_TILED)) + if (state & (SURFACE_STATE_MAXIMIZED | + SURFACE_STATE_FULLSCREEN | + SURFACE_STATE_TILED)) { flags |= SWP_NOSENDCHANGING; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11321
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 12 +-- dlls/winewayland.drv/wayland_surface.c | 96 +++++++++++------------ dlls/winewayland.drv/wayland_text_input.c | 2 +- dlls/winewayland.drv/waylanddrv.h | 23 ++++-- dlls/winewayland.drv/window.c | 12 +-- 5 files changed, 77 insertions(+), 68 deletions(-) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index af404994a44..155deb3cec9 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -140,7 +140,7 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) window_rect = &surface->window.rect; - screen = map_point_from_surface(surface, screen); + screen = map_point_from_surface(&surface->current, screen); screen.x += window_rect->left; screen.y += window_rect->top; /* Sometimes, due to rounding, we may end up with pointer coordinates @@ -347,8 +347,8 @@ static void wayland_motion_delta_to_window(struct wayland_surface *surface, double surface_x, double surface_y, double *window_x, double *window_y) { - *window_x = surface_x * surface->window.scale; - *window_y = surface_y * surface->window.scale; + *window_x = surface_x * surface->current.scale; + *window_y = surface_y * surface->current.scale; } static void relative_pointer_v1_relative_motion(void *private, @@ -765,7 +765,7 @@ static void wayland_set_cursor(HWND hwnd, HCURSOR hcursor, BOOL use_hcursor) wayland_win_data_release(data); return; } - scale = surface->window.scale; + scale = surface->current.scale; if (use_hcursor) surface->hcursor = hcursor; else hcursor = surface->hcursor; use_hcursor = TRUE; @@ -830,7 +830,7 @@ static void wayland_surface_calc_confine(struct wayland_surface *surface, } OffsetRect(&window_clip, -surface->window.rect.left, -surface->window.rect.top); - *confine = map_rect_to_surface(surface, window_clip); + *confine = map_rect_to_surface(&surface->current, window_clip); } /********************************************************************** @@ -1051,7 +1051,7 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset) covers_vscreen = wayland_surface_client_covers_vscreen(surface); warp.x = cursor_pos.x - surface->window.rect.left; warp.y = cursor_pos.y - surface->window.rect.top; - warp = map_point_to_surface(surface, warp); + warp = map_point_to_surface(&surface->current, warp); } wayland_win_data_release(data); diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 7ccdf2998d9..a902d972dcb 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -38,7 +38,7 @@ static void xdg_surface_handle_configure(void *private, struct xdg_surface *xdg_ uint32_t serial) { struct wayland_surface *surface; - BOOL should_post = FALSE, initial_configure = FALSE; + BOOL should_post = FALSE, should_expose = FALSE; struct wayland_win_data *data; HWND hwnd = private; @@ -55,10 +55,10 @@ static void xdg_surface_handle_configure(void *private, struct xdg_surface *xdg_ * WM_WAYLAND_CONFIGURE which hasn't been handled yet. In that case, * avoid sending another message to reduce message queue traffic. */ should_post = surface->requested.serial == 0; - initial_configure = surface->current.serial == 0; + should_expose = surface->current.serial == 0; surface->pending.serial = serial; - surface->requested = surface->pending; - memset(&surface->pending, 0, sizeof(surface->pending)); + if (!surface->pending.scale) surface->pending.scale = surface->current.scale; + surface_config_move(&surface->requested, &surface->pending); } wayland_win_data_release(data); @@ -67,10 +67,7 @@ static void xdg_surface_handle_configure(void *private, struct xdg_surface *xdg_ /* Flush the window surface in case there is content that we weren't * able to flush before due to the lack of the initial configure. */ - if (initial_configure) - { - NtUserExposeWindowSurface(hwnd, 0, NULL); - } + if (should_expose) NtUserExposeWindowSurface(hwnd, 0, NULL); } static const struct xdg_surface_listener xdg_surface_listener = @@ -152,27 +149,22 @@ void wp_fractional_scale_handle_scale(void* user_data, TRACE("hwnd=%p scale=%lf\n", hwnd, scale); if (!(data = wayland_win_data_get(hwnd))) return; - if (!(surface = data->wayland_surface) || scale == surface->window.scale) + if (!(surface = data->wayland_surface)) { wayland_win_data_release(data); return; } - surface->window.scale = scale; - - /* reattach client surfaces as their rects have changed */ - update_client_surfaces(hwnd); - - /* the subsurface rect has changed */ if (surface->role == WAYLAND_SURFACE_ROLE_SUBSURFACE) { surface->processing.serial = 1; surface->processing.processed = TRUE; + surface->current.scale = scale; + NtUserExposeWindowSurface(hwnd, 0, NULL); } + else surface->pending.scale = scale; wayland_win_data_release(data); - - NtUserExposeWindowSurface(hwnd, 0, NULL); } static const struct wp_fractional_scale_v1_listener wp_fractional_scale_listener = @@ -228,7 +220,7 @@ struct wayland_surface *wayland_surface_create(HWND hwnd) wayland_surface_set_opacity(surface, alpha, flags); } - surface->window.scale = 1.0; + surface->current.scale = 1.0; return surface; @@ -304,7 +296,7 @@ void wayland_surface_destroy(struct wayland_surface *surface) static void wayland_surface_init_fractional_scale(struct wayland_surface *surface, double initial_scale) { - surface->window.scale = initial_scale; + surface->current.scale = initial_scale; if (!process_wayland.wp_fractional_scale_manager_v1) return; @@ -396,7 +388,7 @@ void wayland_surface_make_subsurface(struct wayland_surface *surface, goto err; } - wayland_surface_init_fractional_scale(surface, owner->window.scale); + wayland_surface_init_fractional_scale(surface, owner->current.scale); surface->role = WAYLAND_SURFACE_ROLE_SUBSURFACE; surface->owner_hwnd = owner->hwnd; @@ -422,6 +414,8 @@ err: */ void wayland_surface_clear_role(struct wayland_surface *surface) { + double scale; + TRACE("surface=%p\n", surface); /* some objects are shared between several roles */ @@ -471,10 +465,12 @@ void wayland_surface_clear_role(struct wayland_surface *surface) break; } - memset(&surface->pending, 0, sizeof(surface->pending)); - memset(&surface->requested, 0, sizeof(surface->requested)); - memset(&surface->processing, 0, sizeof(surface->processing)); - memset(&surface->current, 0, sizeof(surface->current)); + scale = surface->current.scale; + surface_config_reset(&surface->pending); + surface_config_reset(&surface->requested); + surface_config_reset(&surface->processing); + surface_config_reset(&surface->current); + surface->current.scale = scale; /* Ensure no buffer is attached, otherwise future role assignments may fail. */ wl_surface_attach(surface->wl_surface, NULL, 0, 0); @@ -564,7 +560,7 @@ static BOOL is_rect_smaller(RECT a, RECT b) */ BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struct surface_config *conf) { - RECT rect = map_rect_to_surface(surface, surface->window.rect); + RECT rect = map_rect_to_surface(conf, surface->window.rect); /* 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 @@ -616,7 +612,7 @@ static void wayland_surface_get_rect_in_monitor(struct wayland_surface *surface, */ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface) { - RECT rect = map_rect_to_surface(surface, surface->window.rect); + RECT rect = map_rect_to_surface(&surface->current, surface->window.rect); /* If the window size is bigger than the current state accepts, use the * largest visible (from Windows' perspective) subregion of the window. */ @@ -626,7 +622,7 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface { wayland_surface_get_rect_in_monitor(surface, &rect); - rect = map_rect_to_surface(surface, rect); + rect = map_rect_to_surface(&surface->current, rect); /* If the window rect in the monitor is smaller than required, * fall back to an appropriately sized rect at the top-left. */ @@ -673,7 +669,7 @@ static void wayland_surface_reconfigure_geometry(struct wayland_surface *surface */ static void wayland_surface_reconfigure_size(struct wayland_surface *surface) { - RECT rect = map_rect_to_surface(surface, surface->window.rect); + RECT rect = map_rect_to_surface(&surface->current, surface->window.rect); int width = rect.right - rect.left, height = rect.bottom - rect.top; TRACE("hwnd=%p rect=%s\n", surface->hwnd, wine_dbgstr_rect(&rect)); @@ -700,7 +696,7 @@ static void wayland_surface_reconfigure_client(struct wayland_surface *surface, if (client_rect) rect = *client_rect; OffsetRect(&rect, window->client_rect.left - window->rect.left, window->client_rect.top - window->rect.top); - rect = map_rect_to_surface(surface, rect); + rect = map_rect_to_surface(&surface->current, rect); TRACE("hwnd=%p rect=%s\n", surface->hwnd, wine_dbgstr_rect(&rect)); @@ -730,9 +726,9 @@ static BOOL wayland_surface_reconfigure_xdg(struct wayland_surface *surface) if (surface->processing.serial && surface->processing.processed && wayland_surface_config_is_compatible(surface, &surface->processing)) { - surface->current = surface->processing; - memset(&surface->processing, 0, sizeof(surface->processing)); + surface_config_move(&surface->current, &surface->processing); xdg_surface_ack_configure(surface->xdg_surface, surface->current.serial); + update_client_surfaces(surface->hwnd); } /* If this is the initial configure, and we have a compatible requested * config, use that, in order to draw windows that don't go through the @@ -740,9 +736,9 @@ static BOOL wayland_surface_reconfigure_xdg(struct wayland_surface *surface) else if (!surface->current.serial && surface->requested.serial && wayland_surface_config_is_compatible(surface, &surface->requested)) { - surface->current = surface->requested; - memset(&surface->requested, 0, sizeof(surface->requested)); + surface_config_move(&surface->current, &surface->requested); xdg_surface_ack_configure(surface->xdg_surface, surface->current.serial); + update_client_surfaces(surface->hwnd); } else if (!surface->current.serial || !wayland_surface_config_is_compatible(surface, &surface->current)) @@ -774,7 +770,7 @@ static void wayland_surface_reconfigure_subsurface(struct wayland_surface *surfa RECT rect = surface->window.rect; OffsetRect(&rect, -owner_surface->window.rect.left, -owner_surface->window.rect.top); - rect = map_rect_to_surface(surface, rect); + rect = map_rect_to_surface(&surface->current, rect); TRACE("hwnd=%p rect=%s\n", surface->hwnd, wine_dbgstr_rect(&rect)); @@ -1103,12 +1099,12 @@ failed: * * Converts the window (logical) coordinates to wayland surface-local coordinates. */ -RECT map_rect_to_surface(struct wayland_surface *surface, RECT rect) +RECT map_rect_to_surface(struct surface_config *config, RECT rect) { - rect.left = round(rect.left / surface->window.scale); - rect.top = round(rect.top / surface->window.scale); - rect.right = round(rect.right / surface->window.scale); - rect.bottom = round(rect.bottom / surface->window.scale); + rect.left = round(rect.left / config->scale); + rect.top = round(rect.top / config->scale); + rect.right = round(rect.right / config->scale); + rect.bottom = round(rect.bottom / config->scale); return rect; } @@ -1117,10 +1113,10 @@ RECT map_rect_to_surface(struct wayland_surface *surface, RECT rect) * * Converts the window (logical) coordinates to wayland surface-local coordinates. */ -POINT map_point_to_surface(struct wayland_surface *surface, POINT point) +POINT map_point_to_surface(struct surface_config *config, POINT point) { - point.x = round(point.x / surface->window.scale); - point.y = round(point.y / surface->window.scale); + point.x = round(point.x / config->scale); + point.y = round(point.y / config->scale); return point; } @@ -1129,12 +1125,12 @@ POINT map_point_to_surface(struct wayland_surface *surface, POINT point) * * Converts the surface-local coordinates to window (logical) coordinates. */ -RECT map_rect_from_surface(struct wayland_surface *surface, RECT rect) +RECT map_rect_from_surface(struct surface_config *config, RECT rect) { - rect.left = round(rect.left * surface->window.scale); - rect.top = round(rect.top * surface->window.scale); - rect.right = round(rect.right * surface->window.scale); - rect.bottom = round(rect.bottom * surface->window.scale); + rect.left = round(rect.left * config->scale); + rect.top = round(rect.top * config->scale); + rect.right = round(rect.right * config->scale); + rect.bottom = round(rect.bottom * config->scale); return rect; } @@ -1143,10 +1139,10 @@ RECT map_rect_from_surface(struct wayland_surface *surface, RECT rect) * * Converts the surface-local coordinates to window (logical) coordinates. */ -POINT map_point_from_surface(struct wayland_surface *surface, POINT point) +POINT map_point_from_surface(struct surface_config *config, POINT point) { - point.x = round(point.x * surface->window.scale); - point.y = round(point.y * surface->window.scale); + point.x = round(point.x * config->scale); + point.y = round(point.y * config->scale); return point; } diff --git a/dlls/winewayland.drv/wayland_text_input.c b/dlls/winewayland.drv/wayland_text_input.c index 980f86728c8..1a3bc938c1d 100644 --- a/dlls/winewayland.drv/wayland_text_input.c +++ b/dlls/winewayland.drv/wayland_text_input.c @@ -248,7 +248,7 @@ BOOL WAYLAND_SetIMECompositionRect(HWND hwnd, RECT rect) OffsetRect(&rect, -surface->window.rect.left, -surface->window.rect.top); - surface_rect = map_rect_to_surface(surface, rect); + surface_rect = map_rect_to_surface(&surface->current, rect); wayland_win_data_release(data); zwp_text_input_v3_set_cursor_rectangle(text_input->zwp_text_input_v3, diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 551f14e76e9..6506c3890ab 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -227,18 +227,29 @@ struct wayland_output struct surface_config { RECT rect; /* rect of the compositor surface (in surface coordinates) */ + double scale; /* the scale used to convert from the rect of this surface config to win32u coordinates */ enum surface_state state; /* state of the compositor surface */ uint32_t serial; /* serial of the corresponding xdg_surface_configure event */ BOOL processed; /* config has been fully applied to the surface win32 window */ }; +static inline void surface_config_reset(struct surface_config *config) +{ + memset(config, 0, sizeof(*config)); + config->scale = 0.0; +} + +static inline void surface_config_move(struct surface_config *dest, struct surface_config *source) +{ + *dest = *source; + surface_config_reset(source); +} + struct wayland_window_config { RECT rect; RECT client_rect; enum surface_state state; - /* The scale (i.e., normalized dpi) the window is rendering at. */ - double scale; BOOL visible; BOOL managed; BOOL minimized; @@ -337,10 +348,10 @@ void wayland_surface_attach_shm(struct wayland_surface *surface, HRGN surface_damage_region); BOOL wayland_surface_reconfigure(struct wayland_surface *surface); BOOL wayland_surface_config_is_compatible(struct wayland_surface *surface, struct surface_config *conf); -RECT map_rect_to_surface(struct wayland_surface *surface, RECT rect); -POINT map_point_to_surface(struct wayland_surface *surface, POINT point); -RECT map_rect_from_surface(struct wayland_surface *surface, RECT rect); -POINT map_point_from_surface(struct wayland_surface *surface, POINT point); +RECT map_rect_to_surface(struct surface_config *config, RECT rect); +POINT map_point_to_surface(struct surface_config *config, POINT point); +RECT map_rect_from_surface(struct surface_config *config, RECT rect); +POINT map_point_from_surface(struct surface_config *config, POINT point); void wayland_client_surface_attach(struct wayland_client_surface *client, HWND toplevel, const RECT *rect); void wayland_surface_ensure_contents(struct wayland_surface *surface); void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR title); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index b3cc1e135aa..4cb70953e2f 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -479,6 +479,7 @@ static void wayland_configure_window(HWND hwnd) BOOL needs_enter_size_move = FALSE; BOOL needs_exit_size_move = FALSE; BOOL restoring_from_minimize = FALSE; + BOOL should_expose = FALSE; struct wayland_win_data *data; RECT rect; @@ -503,12 +504,13 @@ static void wayland_configure_window(HWND hwnd) return; } - surface->processing = surface->requested; - memset(&surface->requested, 0, sizeof(surface->requested)); + surface_config_move(&surface->processing, &surface->requested); - rect = map_rect_from_surface(surface, surface->processing.rect); + rect = map_rect_from_surface(&surface->processing, surface->processing.rect); state = surface->processing.state; + if (surface->processing.scale != surface->current.scale) should_expose = TRUE; + /* Ignore size hints if we don't have a state that requires strict * size adherence, in order to avoid spurious resizes. */ if (!state) flags |= SWP_NOSIZE; @@ -556,8 +558,7 @@ static void wayland_configure_window(HWND hwnd) if (restoring_from_minimize) { TRACE("hwnd=%p restoring from minimize\n", hwnd); - surface->current = surface->processing; - memset(&surface->processing, 0, sizeof(surface->processing)); + surface_config_move(&surface->current, &surface->processing); xdg_surface_ack_configure(surface->xdg_surface, surface->current.serial); wayland_win_data_release(data); @@ -589,6 +590,7 @@ static void wayland_configure_window(HWND hwnd) } NtUserSetRawWindowPos(hwnd, rect, flags, FALSE); + if (should_expose) NtUserExposeWindowSurface(hwnd, 0, NULL); } /********************************************************************** -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11321
participants (3)
-
Etaash Mathamsetty -
Etaash Mathamsetty (@etaash.mathamsetty) -
Rémi Bernon