From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 12 +-- dlls/winewayland.drv/wayland_surface.c | 97 ++++++++++------------- dlls/winewayland.drv/wayland_text_input.c | 2 +- dlls/winewayland.drv/waylanddrv.h | 23 ++++-- dlls/winewayland.drv/window.c | 8 +- 5 files changed, 69 insertions(+), 73 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..294ffa89977 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,15 @@ 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->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 +213,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 +289,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 +381,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 +407,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 +458,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 +553,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 +605,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 +615,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 +662,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 +689,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,8 +719,7 @@ 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); } /* If this is the initial configure, and we have a compatible requested @@ -740,8 +728,7 @@ 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); } else if (!surface->current.serial || @@ -774,7 +761,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 +1090,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 +1104,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 +1116,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 +1130,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..ca1cf2b6c18 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -503,10 +503,9 @@ 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; /* Ignore size hints if we don't have a state that requires strict @@ -556,8 +555,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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11321