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.
This commit is contained in:
Alexandros Frantzis 2023-11-08 14:00:18 +02:00 committed by Alexandre Julliard
parent 65a4789a7c
commit 4c9c991fae
3 changed files with 39 additions and 2 deletions

View file

@ -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,

View file

@ -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;
wayland_surface_coords_from_window(surface, client_x, client_y, &x, &y);
client_width = window->client_rect.right - window->client_rect.left;
client_height = window->client_rect.bottom - window->client_rect.top;
TRACE("hwnd=%p subsurface=%d,%d\n", surface->hwnd, x, y);
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+%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;

View file

@ -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