Module: wine Branch: master Commit: 4c9c991faea025bf63a24a185daf05f99c486a91 URL: https://gitlab.winehq.org/wine/wine/-/commit/4c9c991faea025bf63a24a185daf05f...
Author: Alexandros Frantzis alexandros.frantzis@collabora.com Date: Wed Nov 8 14:00:18 2023 +0200
winewayland.drv: Set client area subsurface size.
Use the viewporter Wayland protocol to set the size of the client area subsurface, so that it always covers the client area bounds exactly. This may transiently lead to scaled contents.
---
dlls/winewayland.drv/wayland.c | 5 +++++ dlls/winewayland.drv/wayland_surface.c | 33 ++++++++++++++++++++++++++++++++- dlls/winewayland.drv/waylanddrv.h | 1 + 3 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/dlls/winewayland.drv/wayland.c b/dlls/winewayland.drv/wayland.c index 31cd27f7a76..f7119367543 100644 --- a/dlls/winewayland.drv/wayland.c +++ b/dlls/winewayland.drv/wayland.c @@ -154,6 +154,11 @@ static void registry_handle_global(void *data, struct wl_registry *registry, process_wayland.wl_subcompositor = wl_registry_bind(registry, id, &wl_subcompositor_interface, 1); } + else if (strcmp(interface, "wp_viewporter") == 0) + { + process_wayland.wp_viewporter = + wl_registry_bind(registry, id, &wp_viewporter_interface, 1); + } }
static void registry_handle_global_remove(void *data, struct wl_registry *registry, diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index f4a64d19ecd..b83709c5a8a 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -477,6 +477,7 @@ static void wayland_surface_reconfigure_client(struct wayland_surface *surface) { struct wayland_window_config *window = &surface->window; int client_x, client_y, x, y; + int client_width, client_height, width, height;
if (!surface->client) return;
@@ -484,11 +485,32 @@ static void wayland_surface_reconfigure_client(struct wayland_surface *surface) client_x = window->client_rect.left - window->rect.left; client_y = window->client_rect.top - window->rect.top;
+ client_width = window->client_rect.right - window->client_rect.left; + client_height = window->client_rect.bottom - window->client_rect.top; + wayland_surface_coords_from_window(surface, client_x, client_y, &x, &y); + wayland_surface_coords_from_window(surface, client_width, client_height, + &width, &height);
- TRACE("hwnd=%p subsurface=%d,%d\n", surface->hwnd, x, y); + TRACE("hwnd=%p subsurface=%d,%d+%dx%d\n", surface->hwnd, x, y, width, height);
wl_subsurface_set_position(surface->client->wl_subsurface, x, y); + + if (surface->client->wp_viewport) + { + if (width != 0 && height != 0) + { + wp_viewport_set_destination(surface->client->wp_viewport, + width, height); + } + else + { + /* We can't have a 0x0 destination, use 1x1 instead. */ + wp_viewport_set_destination(surface->client->wp_viewport, 1, 1); + } + } + + wl_surface_commit(surface->client->wl_surface); }
/********************************************************************** @@ -719,6 +741,8 @@ BOOL wayland_client_surface_release(struct wayland_client_surface *client) { if (InterlockedDecrement(&client->ref)) return FALSE;
+ if (client->wp_viewport) + wp_viewport_destroy(client->wp_viewport); if (client->wl_subsurface) wl_subsurface_destroy(client->wl_subsurface); if (client->wl_surface) @@ -768,6 +792,13 @@ struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface goto err; }
+ if (process_wayland.wp_viewporter) + { + surface->client->wp_viewport = + wp_viewporter_get_viewport(process_wayland.wp_viewporter, + surface->client->wl_surface); + } + wayland_surface_reconfigure_client(surface);
return surface->client; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 2dc49a2fd4b..00c9112d5de 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -170,6 +170,7 @@ struct wayland_client_surface LONG ref; struct wl_surface *wl_surface; struct wl_subsurface *wl_subsurface; + struct wp_viewport *wp_viewport; };
struct wayland_surface