From 917e86dd7a4cca1da47262caaded2bef9e022f99 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Fri, 8 Sep 2017 10:54:30 -0500 Subject: [PATCH] winemenubuilder: Set StartupWMClass for shortcuts to exe files. Signed-off-by: Vincent Povirk Signed-off-by: Alexandre Julliard --- programs/winemenubuilder/winemenubuilder.c | 44 +++++++++++++++------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c index 154b575d613..0013b04ceea 100644 --- a/programs/winemenubuilder/winemenubuilder.c +++ b/programs/winemenubuilder/winemenubuilder.c @@ -1446,13 +1446,14 @@ static DWORD register_menus_entry(const char *unix_file, const char *windows_fil static BOOL write_desktop_entry(const char *unix_link, const char *location, const char *linkname, const char *path, const char *args, const char *descr, - const char *workdir, const char *icon) + const char *workdir, const char *icon, const char *wmclass) { FILE *file; - WINE_TRACE("(%s,%s,%s,%s,%s,%s,%s,%s)\n", wine_dbgstr_a(unix_link), wine_dbgstr_a(location), + WINE_TRACE("(%s,%s,%s,%s,%s,%s,%s,%s,%s)\n", wine_dbgstr_a(unix_link), wine_dbgstr_a(location), wine_dbgstr_a(linkname), wine_dbgstr_a(path), wine_dbgstr_a(args), - wine_dbgstr_a(descr), wine_dbgstr_a(workdir), wine_dbgstr_a(icon)); + wine_dbgstr_a(descr), wine_dbgstr_a(workdir), wine_dbgstr_a(icon), + wine_dbgstr_a(wmclass)); file = fopen(location, "w"); if (file == NULL) @@ -1470,6 +1471,8 @@ static BOOL write_desktop_entry(const char *unix_link, const char *location, con fprintf(file, "Path=%s\n", workdir); if (icon && lstrlenA(icon)) fprintf(file, "Icon=%s\n", icon); + if (wmclass && lstrlenA(wmclass)) + fprintf(file, "StartupWMClass=%s\n", wmclass); fclose(file); @@ -1615,7 +1618,7 @@ end: } static BOOL write_menu_entry(const char *unix_link, const char *link, const char *path, const char *args, - const char *descr, const char *workdir, const char *icon) + const char *descr, const char *workdir, const char *icon, const char *wmclass) { const char *linkname; char *desktopPath = NULL; @@ -1623,9 +1626,9 @@ static BOOL write_menu_entry(const char *unix_link, const char *link, const char char *filename = NULL; BOOL ret = TRUE; - WINE_TRACE("(%s, %s, %s, %s, %s, %s, %s)\n", wine_dbgstr_a(unix_link), wine_dbgstr_a(link), + WINE_TRACE("(%s, %s, %s, %s, %s, %s, %s, %s)\n", wine_dbgstr_a(unix_link), wine_dbgstr_a(link), wine_dbgstr_a(path), wine_dbgstr_a(args), wine_dbgstr_a(descr), - wine_dbgstr_a(workdir), wine_dbgstr_a(icon)); + wine_dbgstr_a(workdir), wine_dbgstr_a(icon), wine_dbgstr_a(wmclass)); linkname = strrchr(link, '/'); if (linkname == NULL) @@ -1649,7 +1652,7 @@ static BOOL write_menu_entry(const char *unix_link, const char *link, const char goto end; } *desktopDir = '/'; - if (!write_desktop_entry(unix_link, desktopPath, linkname, path, args, descr, workdir, icon)) + if (!write_desktop_entry(unix_link, desktopPath, linkname, path, args, descr, workdir, icon, wmclass)) { WINE_WARN("couldn't make desktop entry %s\n", wine_dbgstr_a(desktopPath)); ret = FALSE; @@ -2771,9 +2774,10 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait ) '\\','s','t','a','r','t','.','e','x','e',0}; char *link_name = NULL, *icon_name = NULL, *work_dir = NULL; char *escaped_path = NULL, *escaped_args = NULL, *description = NULL; + char *wmclass = NULL; WCHAR szTmp[INFOTIPSIZE]; WCHAR szDescription[INFOTIPSIZE], szPath[MAX_PATH], szWorkDir[MAX_PATH]; - WCHAR szArgs[INFOTIPSIZE], szIconPath[MAX_PATH]; + WCHAR szArgs[INFOTIPSIZE], szIconPath[MAX_PATH], szWMClass[MAX_PATH]; int iIconId = 0, r = -1; DWORD csidl = -1; HANDLE hsem = NULL; @@ -2818,6 +2822,8 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait ) ExpandEnvironmentStringsW(szTmp, szIconPath, MAX_PATH); WINE_TRACE("icon file : %s\n", wine_dbgstr_w(szIconPath) ); + szWMClass[0] = 0; + if( !szPath[0] ) { LPITEMIDLIST pidl = NULL; @@ -2880,6 +2886,14 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait ) GetWindowsDirectoryW(szPath, MAX_PATH); lstrcatW(szPath, startW); } + else + { + /* FIXME: Use AppUserModelID if present. */ + WCHAR *p = PathFindFileNameW(szPath); + + lstrcpyW(szWMClass, p); + CharLowerW(szWMClass); + } /* convert app working dir */ if (szWorkDir[0]) @@ -2897,7 +2911,8 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait ) escaped_path = escape(szPath); escaped_args = escape(szArgs); description = wchars_to_utf8_chars(szDescription); - if (escaped_path == NULL || escaped_args == NULL || description == NULL) + wmclass = wchars_to_utf8_chars(szWMClass); + if (escaped_path == NULL || escaped_args == NULL || description == NULL || wmclass == NULL) { WINE_ERR("out of memory allocating/escaping parameters\n"); goto cleanup; @@ -2936,12 +2951,12 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait ) if (link_arg) { r = !write_desktop_entry(unix_link, location, lastEntry, - start_path, link_arg, description, work_dir, icon_name); + start_path, link_arg, description, work_dir, icon_name, wmclass); HeapFree(GetProcessHeap(), 0, link_arg); } } else - r = !write_desktop_entry(NULL, location, lastEntry, escaped_path, escaped_args, description, work_dir, icon_name); + r = !write_desktop_entry(NULL, location, lastEntry, escaped_path, escaped_args, description, work_dir, icon_name, wmclass); if (r == 0) chmod(location, 0755); HeapFree(GetProcessHeap(), 0, location); @@ -2952,7 +2967,7 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait ) char *link_arg = escape_unix_link_arg(unix_link); if (link_arg) { - r = !write_menu_entry(unix_link, link_name, start_path, link_arg, description, work_dir, icon_name); + r = !write_menu_entry(unix_link, link_name, start_path, link_arg, description, work_dir, icon_name, wmclass); HeapFree(GetProcessHeap(), 0, link_arg); } } @@ -2967,6 +2982,7 @@ cleanup: HeapFree( GetProcessHeap(), 0, escaped_args ); HeapFree( GetProcessHeap(), 0, escaped_path ); HeapFree( GetProcessHeap(), 0, description ); + HeapFree( GetProcessHeap(), 0, wmclass ); HeapFree( GetProcessHeap(), 0, unix_link ); HeapFree( GetProcessHeap(), 0, start_path ); @@ -3102,14 +3118,14 @@ static BOOL InvokeShellLinkerForURL( IUniformResourceLocatorW *url, LPCWSTR link location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry); if (location) { - r = !write_desktop_entry(NULL, location, lastEntry, start_path, escaped_urlPath, NULL, NULL, icon_name); + r = !write_desktop_entry(NULL, location, lastEntry, start_path, escaped_urlPath, NULL, NULL, icon_name, NULL); if (r == 0) chmod(location, 0755); HeapFree(GetProcessHeap(), 0, location); } } else - r = !write_menu_entry(unix_link, link_name, start_path, escaped_urlPath, NULL, NULL, icon_name); + r = !write_menu_entry(unix_link, link_name, start_path, escaped_urlPath, NULL, NULL, icon_name, NULL); ret = (r == 0); ReleaseSemaphore(hSem, 1, NULL);