[PATCH v3 0/1] MR9865: winewayland: Separate icon buffers from toplevel role.
Fixes xdg-toplevel-icon support. Fixes regression caused by 0f21d771a48d1fec924014eb8368e11475dbf3fb -- v3: winewayland: Separate icon buffers from toplevel role. https://gitlab.winehq.org/wine/wine/-/merge_requests/9865
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_surface.c | 88 ++++++++++++++++---------- dlls/winewayland.drv/waylanddrv.h | 7 +- dlls/winewayland.drv/window.c | 9 ++- 3 files changed, 66 insertions(+), 38 deletions(-) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 14171cfb911..b0b51212ec6 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -224,6 +224,18 @@ void wayland_surface_destroy(struct wayland_surface *surface) surface->wl_surface = NULL; } + if (surface->big_icon_buffer) + { + wayland_shm_buffer_unref(surface->big_icon_buffer); + surface->big_icon_buffer = NULL; + } + + if (surface->small_icon_buffer) + { + wayland_shm_buffer_unref(surface->small_icon_buffer); + surface->small_icon_buffer = NULL; + } + wl_display_flush(process_wayland.wl_display); free(surface); @@ -258,13 +270,15 @@ void wayland_surface_make_toplevel(struct wayland_surface *surface) if (process_name) xdg_toplevel_set_app_id(surface->xdg_toplevel, process_name); - wl_surface_commit(surface->wl_surface); - wl_display_flush(process_wayland.wl_display); - if (!NtUserInternalGetWindowText(surface->hwnd, text, ARRAY_SIZE(text))) text[0] = 0; wayland_surface_set_title(surface, text); + wayland_surface_assign_icon(surface); + + wl_surface_commit(surface->wl_surface); + wl_display_flush(process_wayland.wl_display); + return; err: @@ -336,12 +350,6 @@ void wayland_surface_clear_role(struct wayland_surface *surface) process_wayland.xdg_toplevel_icon_manager_v1, surface->xdg_toplevel, NULL); xdg_toplevel_icon_v1_destroy(surface->xdg_toplevel_icon); - if (surface->big_icon_buffer) - wayland_shm_buffer_unref(surface->big_icon_buffer); - if (surface->small_icon_buffer) - wayland_shm_buffer_unref(surface->small_icon_buffer); - surface->big_icon_buffer = NULL; - surface->small_icon_buffer = NULL; surface->xdg_toplevel_icon = NULL; } @@ -1231,52 +1239,68 @@ void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR text) } /********************************************************************** - * wayland_surface_set_icon + * wayland_surface_set_icon_buffer */ -void wayland_surface_set_icon(struct wayland_surface *surface, UINT type, const ICONINFO *ii) +void wayland_surface_set_icon_buffer(struct wayland_surface *surface, UINT type, const ICONINFO *ii) { - HDC hDC; struct wayland_shm_buffer *icon_buf; + HDC hDC; + + if (!process_wayland.xdg_toplevel_icon_manager_v1) return; assert(ii); - assert(wayland_surface_is_toplevel(surface)); + + TRACE("surface=%p type=%x ii=%p\n", surface, type, ii); hDC = NtGdiCreateCompatibleDC(0); icon_buf = wayland_shm_buffer_from_color_bitmaps(hDC, ii->hbmColor, ii->hbmMask); NtGdiDeleteObjectApp(hDC); + if (surface->big_icon_buffer && type == ICON_BIG) + { + wayland_shm_buffer_unref(surface->big_icon_buffer); + surface->big_icon_buffer = NULL; + } + else if (surface->small_icon_buffer && type != ICON_BIG) + { + wayland_shm_buffer_unref(surface->small_icon_buffer); + surface->small_icon_buffer = NULL; + } + + if (icon_buf) + { + if (type == ICON_BIG) surface->big_icon_buffer = icon_buf; + else surface->small_icon_buffer = icon_buf; + } +} + +/********************************************************************** + * wayland_surface_assign_icon + */ +void wayland_surface_assign_icon(struct wayland_surface *surface) +{ + if (!process_wayland.xdg_toplevel_icon_manager_v1) return; + + assert(wayland_surface_is_toplevel(surface)); + + TRACE("surface=%p\n", surface); + if (surface->xdg_toplevel_icon) { xdg_toplevel_icon_manager_v1_set_icon(process_wayland.xdg_toplevel_icon_manager_v1, surface->xdg_toplevel, NULL); xdg_toplevel_icon_v1_destroy(surface->xdg_toplevel_icon); - if (surface->big_icon_buffer && type == ICON_BIG) - { - wayland_shm_buffer_unref(surface->big_icon_buffer); - surface->big_icon_buffer = NULL; - } - else if (surface->small_icon_buffer && type != ICON_BIG) - { - wayland_shm_buffer_unref(surface->small_icon_buffer); - surface->small_icon_buffer = NULL; - } surface->xdg_toplevel_icon = NULL; } - if (icon_buf) + if (surface->big_icon_buffer) { surface->xdg_toplevel_icon = xdg_toplevel_icon_manager_v1_create_icon(process_wayland.xdg_toplevel_icon_manager_v1); - if (type == ICON_BIG) surface->big_icon_buffer = icon_buf; - else surface->small_icon_buffer = icon_buf; - /* FIXME: what to do with scale ? */ - if (surface->big_icon_buffer) - { - xdg_toplevel_icon_v1_add_buffer(surface->xdg_toplevel_icon, - surface->big_icon_buffer->wl_buffer, 1); - } + xdg_toplevel_icon_v1_add_buffer(surface->xdg_toplevel_icon, + surface->big_icon_buffer->wl_buffer, 1); if (surface->small_icon_buffer) { xdg_toplevel_icon_v1_add_buffer(surface->xdg_toplevel_icon, diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 7ab1f58ba64..9452d237fa3 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -265,6 +265,8 @@ struct wayland_surface struct wl_surface *wl_surface; struct wp_viewport *wp_viewport; + struct wayland_shm_buffer *small_icon_buffer; + struct wayland_shm_buffer *big_icon_buffer; enum wayland_surface_role role; union @@ -274,8 +276,6 @@ struct wayland_surface struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; struct xdg_toplevel_icon_v1 *xdg_toplevel_icon; - struct wayland_shm_buffer *small_icon_buffer; - struct wayland_shm_buffer *big_icon_buffer; }; struct { @@ -332,7 +332,8 @@ struct wayland_client_surface *wayland_client_surface_create(HWND hwnd); void wayland_client_surface_attach(struct wayland_client_surface *client, HWND toplevel); void wayland_surface_ensure_contents(struct wayland_surface *surface); void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR title); -void wayland_surface_set_icon(struct wayland_surface *surface, UINT type, const ICONINFO *ii); +void wayland_surface_assign_icon(struct wayland_surface *surface); +void wayland_surface_set_icon_buffer(struct wayland_surface *surface, UINT type, const ICONINFO *ii); static inline BOOL wayland_surface_is_toplevel(struct wayland_surface *surface) { diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index b838fd84191..07e0858fb39 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -669,6 +669,7 @@ static enum xdg_toplevel_resize_edge hittest_to_resize_edge(WPARAM hittest) */ void WAYLAND_SetWindowIcons(HWND hwnd, HICON icon, const ICONINFO *ii, HICON icon_small, const ICONINFO *ii_small) { + struct wayland_surface *surface; struct wayland_win_data *data; TRACE("hwnd=%p icon=%p ii=%p icon_small=%p ii_small=%p\n", hwnd, icon, ii, icon_small, ii_small); @@ -677,10 +678,12 @@ void WAYLAND_SetWindowIcons(HWND hwnd, HICON icon, const ICONINFO *ii, HICON ico { if ((data = wayland_win_data_get(hwnd))) { - if (data->wayland_surface && wayland_surface_is_toplevel(data->wayland_surface)) + if ((surface = data->wayland_surface)) { - wayland_surface_set_icon(data->wayland_surface, ICON_BIG, ii); - wayland_surface_set_icon(data->wayland_surface, ICON_SMALL, ii_small); + wayland_surface_set_icon_buffer(surface, ICON_BIG, ii); + if (icon_small) wayland_surface_set_icon_buffer(surface, ICON_SMALL, ii_small); + if (wayland_surface_is_toplevel(surface)) + wayland_surface_assign_icon(surface); } wayland_win_data_release(data); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9865
This merge request was approved by Rémi Bernon. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9865
participants (3)
-
Etaash Mathamsetty -
Etaash Mathamsetty (@etaash.mathamsetty) -
Rémi Bernon (@rbernon)