From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/wayland_surface.c | 42 +------------------------- dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/window.c | 40 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 41 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 488132ca8d5..13503cc849d 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -494,7 +494,7 @@ static void wayland_surface_reconfigure_size(struct wayland_surface *surface, * * Reconfigures the subsurface covering the client area. */ -static void wayland_surface_reconfigure_client(struct wayland_surface *surface) +void wayland_surface_reconfigure_client(struct wayland_surface *surface) { struct wayland_window_config *window = &surface->window; int client_x, client_y, x, y; @@ -815,46 +815,6 @@ err: return NULL; }
-/********************************************************************** - * wayland_surface_get_client - */ -struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) -{ - struct wayland_client_surface *client; - - if ((client = surface->client)) - { - InterlockedIncrement(&client->ref); - return client; - } - - if (!(client = wayland_client_surface_create(surface->hwnd))) - return NULL; - - client->wl_subsurface = - wl_subcompositor_get_subsurface(process_wayland.wl_subcompositor, - client->wl_surface, - surface->wl_surface); - if (!client->wl_subsurface) - { - ERR("Failed to create client wl_subsurface\n"); - goto err; - } - /* Present contents independently of the parent surface. */ - wl_subsurface_set_desync(client->wl_subsurface); - - wayland_surface_reconfigure_client(surface); - /* Commit to apply subsurface positioning. */ - wl_surface_commit(surface->wl_surface); - - surface->client = client; - return client; - -err: - wayland_client_surface_release(client); - return NULL; -} - static void dummy_buffer_release(void *data, struct wl_buffer *buffer) { struct wayland_shm_buffer *shm_buffer = data; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 4551540e0d4..bd6fcb50147 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -241,6 +241,7 @@ void wayland_surface_clear_role(struct wayland_surface *surface); void wayland_surface_attach_shm(struct wayland_surface *surface, struct wayland_shm_buffer *shm_buffer, HRGN surface_damage_region); +void wayland_surface_reconfigure_client(struct wayland_surface *surface); BOOL wayland_surface_reconfigure(struct wayland_surface *surface); BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, int width, int height, diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 942d56870a3..0874ec5121e 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -682,6 +682,46 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) return ret; }
+/********************************************************************** + * wayland_surface_get_client + */ +struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) +{ + struct wayland_client_surface *client; + + if ((client = surface->client)) + { + InterlockedIncrement(&client->ref); + return client; + } + + if (!(client = wayland_client_surface_create(surface->hwnd))) + return NULL; + + client->wl_subsurface = + wl_subcompositor_get_subsurface(process_wayland.wl_subcompositor, + client->wl_surface, + surface->wl_surface); + if (!client->wl_subsurface) + { + ERR("Failed to create client wl_subsurface\n"); + goto err; + } + /* Present contents independently of the parent surface. */ + wl_subsurface_set_desync(client->wl_subsurface); + + wayland_surface_reconfigure_client(surface); + /* Commit to apply subsurface positioning. */ + wl_surface_commit(surface->wl_surface); + + surface->client = client; + return client; + +err: + wayland_client_surface_release(client); + return NULL; +} + BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region) { struct wayland_surface *wayland_surface;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/wayland_surface.c | 19 +++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/window.c | 33 ++++++-------------------- 3 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 13503cc849d..5d3fe1e3938 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -815,6 +815,25 @@ err: return NULL; }
+void wayland_client_surface_attach(struct wayland_client_surface *client, struct wayland_surface *surface) +{ + client->wl_subsurface = + wl_subcompositor_get_subsurface(process_wayland.wl_subcompositor, + client->wl_surface, + surface->wl_surface); + if (!client->wl_subsurface) + { + ERR("Failed to create client wl_subsurface\n"); + return; + } + /* Present contents independently of the parent surface. */ + wl_subsurface_set_desync(client->wl_subsurface); + + wayland_surface_reconfigure_client(surface); + /* Commit to apply subsurface positioning. */ + wl_surface_commit(surface->wl_surface); +} + static void dummy_buffer_release(void *data, struct wl_buffer *buffer) { struct wayland_shm_buffer *shm_buffer = data; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index bd6fcb50147..39f1e831084 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -255,6 +255,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, struct wayland_client_surface *wayland_client_surface_create(HWND hwnd); struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface); BOOL wayland_client_surface_release(struct wayland_client_surface *client); +void wayland_client_surface_attach(struct wayland_client_surface *client, struct wayland_surface *surface); 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 0874ec5121e..028de2a2f21 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -687,39 +687,20 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) */ struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) { - struct wayland_client_surface *client; + struct wayland_client_surface *client = surface->client; + HWND hwnd = surface->hwnd;
- if ((client = surface->client)) - { - InterlockedIncrement(&client->ref); - return client; - } - - if (!(client = wayland_client_surface_create(surface->hwnd))) + if (!client && !(client = wayland_client_surface_create(hwnd))) return NULL;
- client->wl_subsurface = - wl_subcompositor_get_subsurface(process_wayland.wl_subcompositor, - client->wl_surface, - surface->wl_surface); - if (!client->wl_subsurface) + if (!surface->client) { - ERR("Failed to create client wl_subsurface\n"); - goto err; + wayland_client_surface_attach(client, surface); + InterlockedIncrement(&client->ref); + surface->client = client; } - /* Present contents independently of the parent surface. */ - wl_subsurface_set_desync(client->wl_subsurface); - - wayland_surface_reconfigure_client(surface); - /* Commit to apply subsurface positioning. */ - wl_surface_commit(surface->wl_surface);
- surface->client = client; return client; - -err: - wayland_client_surface_release(client); - return NULL; }
BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 31 +++++-------------------------- dlls/winewayland.drv/vulkan.c | 17 ++--------------- dlls/winewayland.drv/waylanddrv.h | 2 +- dlls/winewayland.drv/window.c | 30 +++++++++++++++++++++++++----- 4 files changed, 33 insertions(+), 47 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 94ff32c81f1..74c3cb02d8e 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -192,9 +192,8 @@ static inline EGLConfig egl_config_for_format(int format) static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, int format) { struct wayland_gl_drawable *gl; - struct wayland_surface *wayland_surface; int client_width = 0, client_height = 0; - struct wayland_win_data *data; + RECT client_rect;
TRACE("hwnd=%p format=%d\n", hwnd, format);
@@ -208,31 +207,11 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, int for /* Get the client surface for the HWND. If don't have a wayland surface * (e.g., HWND_MESSAGE windows) just create a dummy surface to act as the * target render surface. */ - if ((data = wayland_win_data_get(hwnd))) - { - if (!(wayland_surface = data->wayland_surface)) - { - gl->client = wayland_client_surface_create(hwnd); - client_width = client_height = 1; - } - else - { - gl->client = wayland_surface_get_client(wayland_surface); - client_width = wayland_surface->window.client_rect.right - - wayland_surface->window.client_rect.left; - client_height = wayland_surface->window.client_rect.bottom - - wayland_surface->window.client_rect.top; - if (client_width == 0 || client_height == 0) - client_width = client_height = 1; - } - wayland_win_data_release(data); - } - else - { - gl->client = wayland_client_surface_create(hwnd); + if (!(gl->client = get_client_surface(hwnd, &client_rect))) goto err; + client_width = client_rect.right - client_rect.left; + client_height = client_rect.bottom - client_rect.top; + if (client_width == 0 || client_height == 0) client_width = client_height = 1; - } - if (!gl->client) goto err;
gl->wl_egl_window = wl_egl_window_create(gl->client->wl_surface, client_width, client_height); diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 7a075a925b7..9628fd81fe5 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -73,25 +73,12 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, VkInstance instance, Vk { VkResult res; VkWaylandSurfaceCreateInfoKHR create_info_host; - struct wayland_surface *wayland_surface; struct wayland_client_surface *client; - struct wayland_win_data *data; + RECT client_rect;
TRACE("%p %p %p %p\n", hwnd, instance, surface, private);
- if (!(data = wayland_win_data_get(hwnd))) - { - ERR("Failed to find wayland surface for hwnd=%p\n", hwnd); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - if ((wayland_surface = data->wayland_surface)) - client = wayland_surface_get_client(wayland_surface); - else - client = wayland_client_surface_create(hwnd); - wayland_win_data_release(data); - - if (!client) + if (!(client = get_client_surface(hwnd, &client_rect))) { ERR("Failed to create client surface for hwnd=%p\n", hwnd); return VK_ERROR_OUT_OF_HOST_MEMORY; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 39f1e831084..8e1895b9b8d 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -253,7 +253,6 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, double surface_x, double surface_y, int *window_x, int *window_y); struct wayland_client_surface *wayland_client_surface_create(HWND hwnd); -struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface); BOOL wayland_client_surface_release(struct wayland_client_surface *client); void wayland_client_surface_attach(struct wayland_client_surface *client, struct wayland_surface *surface); void wayland_surface_ensure_contents(struct wayland_surface *surface); @@ -290,6 +289,7 @@ struct wayland_win_data struct wayland_win_data *wayland_win_data_get(HWND hwnd); void wayland_win_data_release(struct wayland_win_data *data);
+struct wayland_client_surface *get_client_surface(HWND hwnd, RECT *client_rect); BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region); struct wayland_shm_buffer *get_window_surface_contents(HWND hwnd); void ensure_window_surface_contents(HWND hwnd); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 028de2a2f21..2b6576cb4a4 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -683,23 +683,43 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) }
/********************************************************************** - * wayland_surface_get_client + * get_client_surface */ -struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) +struct wayland_client_surface *get_client_surface(HWND hwnd, RECT *client_rect) { - struct wayland_client_surface *client = surface->client; - HWND hwnd = surface->hwnd; + struct wayland_client_surface *client; + struct wayland_surface *surface; + struct wayland_win_data *data; + + if (!(data = wayland_win_data_get(hwnd))) surface = NULL; + else surface = data->wayland_surface; + + if (surface) + { + *client_rect = surface->window.client_rect; + client = surface->client; + } + else + { + SetRectEmpty(client_rect); + client = NULL; + }
if (!client && !(client = wayland_client_surface_create(hwnd))) + { + if (data) wayland_win_data_release(data); return NULL; + } + if (!data) return client;
- if (!surface->client) + if (surface && !surface->client) { wayland_client_surface_attach(client, surface); InterlockedIncrement(&client->ref); surface->client = client; }
+ wayland_win_data_release(data); return client; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 4 ++-- dlls/winewayland.drv/vulkan.c | 4 ++-- dlls/winewayland.drv/wayland_surface.c | 26 ++++++++++++-------------- dlls/winewayland.drv/waylanddrv.h | 10 ++++++---- dlls/winewayland.drv/window.c | 24 ++++++++++++------------ 5 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 74c3cb02d8e..ecb1a65c38c 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -168,8 +168,8 @@ static void wayland_gl_drawable_release(struct wayland_gl_drawable *gl) HWND hwnd = wl_surface_get_user_data(gl->client->wl_surface); struct wayland_win_data *data = wayland_win_data_get(hwnd);
- if (wayland_client_surface_release(gl->client) && data && data->wayland_surface) - data->wayland_surface->client = NULL; + if (wayland_client_surface_release(gl->client) && data) + data->client_surface = NULL;
if (data) wayland_win_data_release(data); } diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 9628fd81fe5..7c8537bfc40 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -63,8 +63,8 @@ static void wine_vk_surface_destroy(struct wayland_client_surface *client) HWND hwnd = wl_surface_get_user_data(client->wl_surface); struct wayland_win_data *data = wayland_win_data_get(hwnd);
- if (wayland_client_surface_release(client) && data && data->wayland_surface) - data->wayland_surface->client = NULL; + if (wayland_client_surface_release(client) && data) + data->client_surface = NULL;
if (data) wayland_win_data_release(data); } diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 5d3fe1e3938..27d1fde8c12 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -494,14 +494,12 @@ static void wayland_surface_reconfigure_size(struct wayland_surface *surface, * * Reconfigures the subsurface covering the client area. */ -void wayland_surface_reconfigure_client(struct wayland_surface *surface) +void wayland_surface_reconfigure_client(struct wayland_surface *surface, struct wayland_client_surface *client) { 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; - /* The offset of the client area origin relatively to the window origin. */ client_x = window->client_rect.left - window->rect.left; client_y = window->client_rect.top - window->rect.top; @@ -515,17 +513,16 @@ void wayland_surface_reconfigure_client(struct wayland_surface *surface)
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); + wl_subsurface_set_position(client->wl_subsurface, x, y);
if (width != 0 && height != 0) - wp_viewport_set_destination(surface->client->wp_viewport, - width, height); + wp_viewport_set_destination(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); + wp_viewport_set_destination(client->wp_viewport, 1, 1);
- wl_surface_commit(surface->client->wl_surface); + wl_surface_commit(client->wl_surface);
- wayland_resize_gl_drawable(surface->hwnd); + wayland_resize_gl_drawable(client->hwnd); }
/********************************************************************** @@ -534,7 +531,7 @@ void wayland_surface_reconfigure_client(struct wayland_surface *surface) * Reconfigures the wayland surface as needed to match the latest requested * state. */ -BOOL wayland_surface_reconfigure(struct wayland_surface *surface) +BOOL wayland_surface_reconfigure(struct wayland_surface *surface, struct wayland_client_surface *client) { struct wayland_window_config *window = &surface->window; int win_width, win_height, width, height; @@ -585,7 +582,7 @@ BOOL wayland_surface_reconfigure(struct wayland_surface *surface)
wayland_surface_reconfigure_geometry(surface, width, height); wayland_surface_reconfigure_size(surface, width, height); - wayland_surface_reconfigure_client(surface); + if (client) wayland_surface_reconfigure_client(surface, client);
return TRUE; } @@ -779,6 +776,7 @@ struct wayland_client_surface *wayland_client_surface_create(HWND hwnd) return NULL; } client->ref = 1; + client->hwnd = hwnd;
client->wl_surface = wl_compositor_create_surface(process_wayland.wl_compositor); @@ -829,7 +827,7 @@ void wayland_client_surface_attach(struct wayland_client_surface *client, struct /* Present contents independently of the parent surface. */ wl_subsurface_set_desync(client->wl_subsurface);
- wayland_surface_reconfigure_client(surface); + wayland_surface_reconfigure_client(surface, client); /* Commit to apply subsurface positioning. */ wl_surface_commit(surface->wl_surface); } @@ -852,7 +850,7 @@ static const struct wl_buffer_listener dummy_buffer_listener = * Ensure that the wayland surface has up-to-date contents, by committing * a dummy buffer if necessary. */ -void wayland_surface_ensure_contents(struct wayland_surface *surface) +void wayland_surface_ensure_contents(struct wayland_surface *surface, struct wayland_client_surface *client) { struct wayland_shm_buffer *dummy_shm_buffer; HRGN damage; @@ -883,7 +881,7 @@ void wayland_surface_ensure_contents(struct wayland_surface *surface) if (!(damage = NtGdiCreateRectRgn(0, 0, width, height))) WARN("Failed to create damage region for dummy buffer\n");
- if (wayland_surface_reconfigure(surface)) + if (wayland_surface_reconfigure(surface, client)) { wayland_surface_attach_shm(surface, dummy_shm_buffer, damage); wl_surface_commit(surface->wl_surface); diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 8e1895b9b8d..ecefeeb77af 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -184,6 +184,7 @@ struct wayland_window_config struct wayland_client_surface { LONG ref; + HWND hwnd; struct wl_surface *wl_surface; struct wl_subsurface *wl_subsurface; struct wp_viewport *wp_viewport; @@ -199,7 +200,6 @@ struct wayland_surface struct wayland_surface_config pending, requested, processing, current; BOOL resizing; struct wayland_window_config window; - struct wayland_client_surface *client; int content_width, content_height; HCURSOR hcursor; }; @@ -241,8 +241,8 @@ void wayland_surface_clear_role(struct wayland_surface *surface); void wayland_surface_attach_shm(struct wayland_surface *surface, struct wayland_shm_buffer *shm_buffer, HRGN surface_damage_region); -void wayland_surface_reconfigure_client(struct wayland_surface *surface); -BOOL wayland_surface_reconfigure(struct wayland_surface *surface); +BOOL wayland_surface_reconfigure(struct wayland_surface *surface, struct wayland_client_surface *client); +void wayland_surface_reconfigure_client(struct wayland_surface *surface, struct wayland_client_surface *client); BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, int width, int height, enum wayland_surface_config_state state); @@ -255,7 +255,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, struct wayland_client_surface *wayland_client_surface_create(HWND hwnd); BOOL wayland_client_surface_release(struct wayland_client_surface *client); void wayland_client_surface_attach(struct wayland_client_surface *client, struct wayland_surface *surface); -void wayland_surface_ensure_contents(struct wayland_surface *surface); +void wayland_surface_ensure_contents(struct wayland_surface *surface, struct wayland_client_surface *client); void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR title);
/********************************************************************** @@ -281,6 +281,8 @@ struct wayland_win_data struct wayland_shm_buffer *window_contents; /* wayland surface (if any) for this window */ struct wayland_surface *wayland_surface; + /* wayland client surface (if any) for this window */ + struct wayland_client_surface *client_surface; /* window rects, relative to parent client area */ struct window_rects rects; BOOL managed; diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 2b6576cb4a4..a839c14d537 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -691,18 +691,18 @@ struct wayland_client_surface *get_client_surface(HWND hwnd, RECT *client_rect) struct wayland_surface *surface; struct wayland_win_data *data;
- if (!(data = wayland_win_data_get(hwnd))) surface = NULL; - else surface = data->wayland_surface; - - if (surface) + if ((data = wayland_win_data_get(hwnd))) { - *client_rect = surface->window.client_rect; - client = surface->client; + *client_rect = data->wayland_surface ? data->wayland_surface->window.client_rect + : data->rects.client; + client = data->client_surface; + surface = data->wayland_surface; } else { SetRectEmpty(client_rect); client = NULL; + surface = NULL; }
if (!client && !(client = wayland_client_surface_create(hwnd))) @@ -712,11 +712,11 @@ struct wayland_client_surface *get_client_surface(HWND hwnd, RECT *client_rect) } if (!data) return client;
- if (surface && !surface->client) + if (!data->client_surface) { - wayland_client_surface_attach(client, surface); + if (surface) wayland_client_surface_attach(client, surface); InterlockedIncrement(&client->ref); - surface->client = client; + data->client_surface = client; }
wayland_win_data_release(data); @@ -733,7 +733,7 @@ BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffe
if ((wayland_surface = data->wayland_surface)) { - if (wayland_surface_reconfigure(wayland_surface)) + if (wayland_surface_reconfigure(wayland_surface, data->client_surface)) { wayland_surface_attach_shm(wayland_surface, shm_buffer, damage_region); wl_surface_commit(wayland_surface->wl_surface); @@ -778,13 +778,13 @@ void ensure_window_surface_contents(HWND hwnd)
if ((wayland_surface = data->wayland_surface)) { - wayland_surface_ensure_contents(wayland_surface); + wayland_surface_ensure_contents(wayland_surface, data->client_surface);
/* Handle any processed configure request, to ensure the related * surface state is applied by the compositor. */ if (wayland_surface->processing.serial && wayland_surface->processing.processed && - wayland_surface_reconfigure(wayland_surface)) + wayland_surface_reconfigure(wayland_surface, data->client_surface)) { wl_surface_commit(wayland_surface->wl_surface); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/wayland_surface.c | 17 ++++++++++++++++- dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/window.c | 6 +++++- 3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 27d1fde8c12..1cf5dd3f8ce 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -513,7 +513,11 @@ void wayland_surface_reconfigure_client(struct wayland_surface *surface, struct
TRACE("hwnd=%p subsurface=%d,%d+%dx%d\n", surface->hwnd, x, y, width, height);
- wl_subsurface_set_position(client->wl_subsurface, x, y); + if (client->wl_subsurface) + { + wl_subsurface_set_position(client->wl_subsurface, x, y); + wl_subsurface_place_above(client->wl_subsurface, surface->wl_surface); + }
if (width != 0 && height != 0) wp_viewport_set_destination(client->wp_viewport, width, height); @@ -815,6 +819,8 @@ err:
void wayland_client_surface_attach(struct wayland_client_surface *client, struct wayland_surface *surface) { + wayland_client_surface_detach(client); + client->wl_subsurface = wl_subcompositor_get_subsurface(process_wayland.wl_subcompositor, client->wl_surface, @@ -832,6 +838,15 @@ void wayland_client_surface_attach(struct wayland_client_surface *client, struct wl_surface_commit(surface->wl_surface); }
+void wayland_client_surface_detach(struct wayland_client_surface *client) +{ + if (client->wl_subsurface) + { + wl_subsurface_destroy(client->wl_subsurface); + client->wl_subsurface = NULL; + } +} + static void dummy_buffer_release(void *data, struct wl_buffer *buffer) { struct wayland_shm_buffer *shm_buffer = data; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index ecefeeb77af..9de42758aa1 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -255,6 +255,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, struct wayland_client_surface *wayland_client_surface_create(HWND hwnd); BOOL wayland_client_surface_release(struct wayland_client_surface *client); void wayland_client_surface_attach(struct wayland_client_surface *client, struct wayland_surface *surface); +void wayland_client_surface_detach(struct wayland_client_surface *client); void wayland_surface_ensure_contents(struct wayland_surface *surface, struct wayland_client_surface *client); 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 a839c14d537..025b0ea493d 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -712,9 +712,13 @@ struct wayland_client_surface *get_client_surface(HWND hwnd, RECT *client_rect) } if (!data) return client;
+ if (surface && NtUserIsWindowVisible(hwnd)) + wayland_client_surface_attach(client, surface); + else + wayland_client_surface_detach(client); + if (!data->client_surface) { - if (surface) wayland_client_surface_attach(client, surface); InterlockedIncrement(&client->ref); data->client_surface = client; }
Hi! I am seeing some issues stemming from the optional attachment logic in the final commit. In particular the decision to attach or not is made at GL/VK surface creation time, and is never revisited after that (unless the GL/VK surface is recreated). A few games I tested (e.g., supertuxkart) also seem to create the GL/VK surface while the window is hidden (so client surface is not attached), so the contents are never displayed even when the window is eventually shown.
Taking a step back, what's the reason for detaching the client surface when the window is hidden? The compositor will handle this for us, not showing any subsurfaces if the parent surface is not mapped.
Taking a step back, what's the reason for detaching the client surface when the window is hidden? The compositor will handle this for us, not showing any subsurfaces if the parent surface is not mapped.
(This compositor behavior is good enough for now, while we are not yet dealing with GL/VK in (possibly nested) child surfaces)
On Fri Sep 6 13:14:52 2024 +0000, Alexandros Frantzis wrote:
Taking a step back, what's the reason for detaching the client surface
when the window is hidden? The compositor will handle this for us, not showing any subsurfaces if the parent surface is not mapped. (This compositor behavior is good enough for now, while we are not yet dealing with GL/VK in (possibly nested) child surfaces)
I wanted to introduce the changes more gradually in preparation for the later changes which will attach/detach the clients to different toplevel surfaces. It's probably a matter of pulling more of the later changes in now, for instance attaching/detaching the client windows in `wayland_win_data_update_wayland_surface`, unless you mean that we don't need to bother and that we don't need to detach the client windows before destroying / clearing the toplevel surface role?
I wanted to introduce the changes more gradually in preparation for the later changes which will attach/detach the clients to different toplevel surfaces. It's probably a matter of pulling more of the later changes in now, for instance attaching/detaching the client windows in wayland_win_data_update_wayland_surface
Ack, the above is what I meant.