[2/2] winemenubuilder: Set StartupWMClass for shortcuts to exe files.

Vincent Povirk vincent at codeweavers.com
Fri Sep 8 10:54:30 CDT 2017


For bug 32699.

Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
---
 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 154b575..0013b04 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);
 
-- 
2.7.4




More information about the wine-patches mailing list