[PATCH 2/6] winex11.drv: Use process-wide AppUserModelID to populate WM_CLASS

Jonas Kümmerlin rgcjonas at gmail.com
Tue Jul 14 10:07:42 CDT 2015


If an explicit AppUserModelID is present, it is used, if not,
the full path of the executable is used as fallback.

This is fundamentally incompatible with the previous approach
of using the basename only, but ultimately more similar to
how Windows 7 and later work.
---
 dlls/winex11.drv/window.c | 72 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 51 insertions(+), 21 deletions(-)

diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 50c3290..7d9e33d 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -42,6 +42,10 @@
 #include "winuser.h"
 #include "wine/unicode.h"
 
+/* rpcasync.h declares ULONG Status; Xlib.h does #define Status int */
+#undef Status
+#include "shobjidl.h"
+
 #include "x11drv.h"
 #include "wine/debug.h"
 #include "wine/server.h"
@@ -797,34 +801,58 @@ static void set_style_hints( struct x11drv_win_data *data, DWORD style, DWORD ex
 
 
 /***********************************************************************
- *              get_process_name
+ *              get_appusermodel_id
  *
- * get the name of the current process for setting class hints
+ * Get the id of the current process for setting class hints.
+ * Free with HeapFree(GetProcessHeap(), ...).
  */
-static char *get_process_name(void)
+static char *get_appusermodel_id(void)
 {
-    static char *name;
+    WCHAR *explicit_id = NULL;
+    WCHAR module[MAX_PATH];
+    DWORD len;
+
+    /* TODO: Get the window-specific AppUserModelID */
 
-    if (!name)
+    /* A process-wide explicit AppUserModelID might be available */
+    if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID( &explicit_id )))
     {
-        WCHAR module[MAX_PATH];
-        DWORD len = GetModuleFileNameW( 0, module, MAX_PATH );
-        if (len && len < MAX_PATH)
+        char *ptr;
+        DWORD len;
+
+        len = WideCharToMultiByte( CP_UTF8, 0, explicit_id, -1, NULL, 0, NULL, NULL );
+        if ((ptr = HeapAlloc( GetProcessHeap(), 0, len )))
         {
-            char *ptr;
-            WCHAR *p, *appname = module;
+            WideCharToMultiByte( CP_UTF8, 0, explicit_id, -1, ptr, len, NULL, NULL );
 
-            if ((p = strrchrW( appname, '/' ))) appname = p + 1;
-            if ((p = strrchrW( appname, '\\' ))) appname = p + 1;
-            len = WideCharToMultiByte( CP_UNIXCP, 0, appname, -1, NULL, 0, NULL, NULL );
-            if ((ptr = HeapAlloc( GetProcessHeap(), 0, len )))
-            {
-                WideCharToMultiByte( CP_UNIXCP, 0, appname, -1, ptr, len, NULL, NULL );
-                name = ptr;
-            }
+            CoTaskMemFree( explicit_id );
+
+            return ptr;
         }
+
+        CoTaskMemFree( explicit_id );
+        return NULL;
     }
-    return name;
+
+    /* Employ a fallback algorithm */
+    len = GetModuleFileNameW( 0, module, MAX_PATH );
+    if (len && len < MAX_PATH)
+    {
+        char fallback_prefix[] = "Wine.Fallback.";
+        char *ptr;
+
+        len = WideCharToMultiByte( CP_UTF8, 0, module, -1, NULL, 0, NULL, NULL );
+        if ((ptr = HeapAlloc( GetProcessHeap(), 0, len + sizeof(fallback_prefix) - 1 )))
+        {
+            memcpy( ptr, fallback_prefix, sizeof(fallback_prefix) - 1 );
+            WideCharToMultiByte( CP_UTF8, 0, module, -1,
+                                 ptr + sizeof(fallback_prefix) - 1, len, NULL, NULL );
+
+            return ptr;
+        }
+    }
+
+    return NULL;
 }
 
 
@@ -839,7 +867,6 @@ static void set_initial_wm_hints( Display *display, Window window )
     Atom protocols[3];
     Atom dndVersion = WINE_XDND_VERSION;
     XClassHint *class_hints;
-    char *process_name = get_process_name();
 
     /* wm protocols */
     i = 0;
@@ -853,11 +880,14 @@ static void set_initial_wm_hints( Display *display, Window window )
     if ((class_hints = XAllocClassHint()))
     {
         static char wine[] = "Wine";
+        char *id = get_appusermodel_id();
 
-        class_hints->res_name = process_name;
+        class_hints->res_name = id;
         class_hints->res_class = wine;
         XSetClassHint( display, window, class_hints );
         XFree( class_hints );
+
+        HeapFree( GetProcessHeap(), 0, id );
     }
 
     /* set the WM_CLIENT_MACHINE and WM_LOCALE_NAME properties */
-- 
2.4.3




More information about the wine-devel mailing list