[PATCH v6 0/2] MR5178: winewayland.drv: set wayland app-id from the process name
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56000 -- v6: winewayland.drv: Implement SetWindowText. winewayland.drv: Set wayland app-id from the process name. https://gitlab.winehq.org/wine/wine/-/merge_requests/5178
From: Gopal Prasad <llyyr(a)yukari.in> Co-authored-by: Ryan Hendrickson <ryan.hendrickson(a)alum.mit.edu> Co-authored-by: Alexandros Frantzis <alexandros.frantzis(a)collabora.com> --- dlls/winewayland.drv/wayland_surface.c | 30 +++++++++++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/waylanddrv_main.c | 34 ++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index a955f3688c5..4b45892435e 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -26,6 +26,7 @@ #include <stdlib.h> #include <unistd.h> +#include <assert.h> #include "waylanddrv.h" #include "wine/debug.h" @@ -253,6 +254,9 @@ void wayland_surface_make_toplevel(struct wayland_surface *surface) if (!surface->xdg_toplevel) goto err; xdg_toplevel_add_listener(surface->xdg_toplevel, &xdg_toplevel_listener, surface->hwnd); + 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); @@ -897,3 +901,29 @@ void wayland_surface_ensure_contents(struct wayland_surface *surface) if (damage) NtGdiDeleteObjectApp(damage); } + +/********************************************************************** + * wayland_surface_set_title + */ +void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR text) +{ + DWORD text_len; + DWORD utf8_count; + char *utf8 = NULL; + + assert(surface->xdg_toplevel); + + TRACE("surface=%p hwnd=%p text='%s'\n", + surface, surface->hwnd, wine_dbgstr_w(text)); + + text_len = (lstrlenW(text) + 1) * sizeof(WCHAR); + + if (!RtlUnicodeToUTF8N(NULL, 0, &utf8_count, text, text_len) && + (utf8 = malloc(utf8_count))) + { + RtlUnicodeToUTF8N(utf8, utf8_count, &utf8_count, text, text_len); + xdg_toplevel_set_title(surface->xdg_toplevel, utf8); + } + + free(utf8); +} diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index f030f6fc6a0..6359142300a 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -51,6 +51,7 @@ * Globals */ +extern char *process_name; extern struct wayland process_wayland; /********************************************************************** diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index b60d282aacb..935af8887f7 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -24,11 +24,15 @@ #include "config.h" +#include <stdlib.h> + #include "ntstatus.h" #define WIN32_NO_STATUS #include "waylanddrv.h" +char *process_name = NULL; + static const struct user_driver_funcs waylanddrv_funcs = { .pClipCursor = WAYLAND_ClipCursor, @@ -45,12 +49,42 @@ static const struct user_driver_funcs waylanddrv_funcs = .pwine_get_vulkan_driver = WAYLAND_wine_get_vulkan_driver, }; +static void wayland_init_process_name(void) +{ + WCHAR *p, *appname; + WCHAR appname_lower[MAX_PATH]; + DWORD appname_len; + DWORD appnamez_size; + DWORD utf8_size; + int i; + + appname = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer; + if ((p = wcsrchr(appname, '/'))) appname = p + 1; + if ((p = wcsrchr(appname, '\\'))) appname = p + 1; + appname_len = lstrlenW(appname); + + if (appname_len == 0 || appname_len >= MAX_PATH) return; + + for (i = 0; appname[i]; i++) appname_lower[i] = RtlDowncaseUnicodeChar(appname[i]); + appname_lower[i] = 0; + + appnamez_size = (appname_len + 1) * sizeof(WCHAR); + + if (!RtlUnicodeToUTF8N(NULL, 0, &utf8_size, appname_lower, appnamez_size) && + (process_name = malloc(utf8_size))) + { + RtlUnicodeToUTF8N(process_name, utf8_size, &utf8_size, appname_lower, appnamez_size); + } +} + static NTSTATUS waylanddrv_unix_init(void *arg) { /* Set the user driver functions now so that they are available during * our initialization. We clear them on error. */ __wine_set_user_driver(&waylanddrv_funcs, WINE_GDI_DRIVER_VERSION); + wayland_init_process_name(); + if (!wayland_process_init()) goto err; return 0; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5178
From: Gopal Prasad <llyyr(a)yukari.in> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56000 Co-authored-by: Alexandros Frantzis <alexandros.frantzis(a)collabora.com> --- dlls/winewayland.drv/waylanddrv.h | 2 ++ dlls/winewayland.drv/waylanddrv_main.c | 1 + dlls/winewayland.drv/window.c | 28 +++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 6359142300a..0496b23fd5d 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -257,6 +257,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface); BOOL wayland_client_surface_release(struct wayland_client_surface *client); void wayland_surface_ensure_contents(struct wayland_surface *surface); +void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR title); /********************************************************************** * Wayland SHM buffer @@ -321,6 +322,7 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset); LRESULT WAYLAND_DesktopWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); void WAYLAND_DestroyWindow(HWND hwnd); void WAYLAND_SetCursor(HWND hwnd, HCURSOR hcursor); +void WAYLAND_SetWindowText(HWND hwnd, LPCWSTR text); LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam); BOOL WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manager, BOOL force, void *param); diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 935af8887f7..55589f1acfc 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -41,6 +41,7 @@ static const struct user_driver_funcs waylanddrv_funcs = .pKbdLayerDescriptor = WAYLAND_KbdLayerDescriptor, .pReleaseKbdTables = WAYLAND_ReleaseKbdTables, .pSetCursor = WAYLAND_SetCursor, + .pSetWindowText = WAYLAND_SetWindowText, .pSysCommand = WAYLAND_SysCommand, .pUpdateDisplayDevices = WAYLAND_UpdateDisplayDevices, .pWindowMessage = WAYLAND_WindowMessage, diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index ac5da371e5c..7415ca2d374 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -195,6 +195,7 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat HWND parent = NtUserGetAncestor(data->hwnd, GA_PARENT); BOOL visible, xdg_visible; RECT clip; + WCHAR text[1024]; TRACE("hwnd=%p\n", data->hwnd); @@ -211,6 +212,7 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat /* Otherwise ensure that we have a wayland surface. */ if (!surface && !(surface = wayland_surface_create(data->hwnd))) return; + visible = (NtUserGetWindowLongW(data->hwnd, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE; xdg_visible = surface->xdg_toplevel != NULL; @@ -223,7 +225,14 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat /* If the window is a visible toplevel make it a wayland * xdg_toplevel. Otherwise keep it role-less to avoid polluting the * compositor with empty xdg_toplevels. */ - if (visible) wayland_surface_make_toplevel(surface); + if (visible) + { + wayland_surface_make_toplevel(surface); + if (!NtUserInternalGetWindowText(data->hwnd, text, ARRAY_SIZE(text))) + text[0] = 0; + wayland_surface_set_title(surface, text); + + } } wayland_win_data_get_config(data, &surface->window); @@ -668,6 +677,23 @@ static enum xdg_toplevel_resize_edge hittest_to_resize_edge(WPARAM hittest) } } +/***************************************************************** + * WAYLAND_SetWindowText + */ +void WAYLAND_SetWindowText(HWND hwnd, LPCWSTR text) +{ + struct wayland_surface *surface = wayland_surface_lock_hwnd(hwnd); + + TRACE("hwnd=%p text=%s\n", hwnd, wine_dbgstr_w(text)); + + if (surface) + { + if (surface->xdg_toplevel) wayland_surface_set_title(surface, text); + pthread_mutex_unlock(&surface->mutex); + } + +} + /*********************************************************************** * WAYLAND_SysCommand */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5178
Alexandros Frantzis (@afrantzis) commented about dlls/winewayland.drv/wayland_surface.c:
#include <stdlib.h> #include <unistd.h> +#include <assert.h>
Nit: We try to keep includes (within each group) in alphabetical order. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5178#note_63149
Alexandros Frantzis (@afrantzis) commented about dlls/winewayland.drv/window.c:
/* Otherwise ensure that we have a wayland surface. */ if (!surface && !(surface = wayland_surface_create(data->hwnd))) return;
+
Stray blank line. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5178#note_63150
Alexandros Frantzis (@afrantzis) commented about dlls/winewayland.drv/window.c:
/* If the window is a visible toplevel make it a wayland * xdg_toplevel. Otherwise keep it role-less to avoid polluting the * compositor with empty xdg_toplevels. */ - if (visible) wayland_surface_make_toplevel(surface); + if (visible) + { + wayland_surface_make_toplevel(surface); + if (!NtUserInternalGetWindowText(data->hwnd, text, ARRAY_SIZE(text))) + text[0] = 0; + wayland_surface_set_title(surface, text); +
Stray blank line. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5178#note_63151
Alexandros Frantzis (@afrantzis) commented about dlls/winewayland.drv/window.c:
/* If the window is a visible toplevel make it a wayland * xdg_toplevel. Otherwise keep it role-less to avoid polluting the * compositor with empty xdg_toplevels. */ - if (visible) wayland_surface_make_toplevel(surface); + if (visible) + { + wayland_surface_make_toplevel(surface); + if (!NtUserInternalGetWindowText(data->hwnd, text, ARRAY_SIZE(text)))
Although unlikely, the preceding call may have failed to create `surface->xdg_toplevel` so we still need to check it: ```suggestion:-0+2 if(surface->xdg_toplevel) { if (!NtUserInternalGetWindowText(data->hwnd, text, ARRAY_SIZE(text))) text[0] = 0; wayland_surface_set_title(surface, text); } ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5178#note_63152
Alexandros Frantzis (@afrantzis) commented about dlls/winewayland.drv/window.c:
+/***************************************************************** + * WAYLAND_SetWindowText + */ +void WAYLAND_SetWindowText(HWND hwnd, LPCWSTR text) +{ + struct wayland_surface *surface = wayland_surface_lock_hwnd(hwnd); + + TRACE("hwnd=%p text=%s\n", hwnd, wine_dbgstr_w(text)); + + if (surface) + { + if (surface->xdg_toplevel) wayland_surface_set_title(surface, text); + pthread_mutex_unlock(&surface->mutex); + } +
Stray blank line. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5178#note_63153
A few more suggestions, but with those addressed this looks good to me! -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5178#note_63154
participants (3)
-
Alexandros Frantzis (@afrantzis) -
Gopal Prasad -
llyyr (@llyyr)