public inbox for cygwin-xfree@sourceware.org
help / color / mirror / Atom feed
* Taskbar grouping in Windows 7
@ 2011-06-25 12:49 Tobias Häußler
  2011-06-29 13:26 ` Jon TURNEY
  0 siblings, 1 reply; 5+ messages in thread
From: Tobias Häußler @ 2011-06-25 12:49 UTC (permalink / raw)
  To: cygwin-xfree

[-- Attachment #1: Type: text/plain, Size: 328 bytes --]

Hi,

I created a small patch for XWin that adds correct grouping of taskbar
icons when 'Always combine, hide labels' is set in the taskbar
properties. It uses the new taskbar APIs introduced in Windows 7 to set
an application id for each window. The id is based on the X11 class hints.
Maybe it is useful for someone...

Tobias

[-- Attachment #2: taskbar.patch --]
[-- Type: text/plain, Size: 7096 bytes --]

diff -urN src/xserver-cygwin-1.10.1-1/hw/xwin/Makefile.am src/xserver-cygwin-1.10.1-1/hw/xwin/Makefile.am
--- src/xserver-cygwin-1.10.1-1/hw/xwin/Makefile.am	2011-04-22 18:03:27.000000000 +0200
+++ src/xserver-cygwin-1.10.1-1/hw/xwin/Makefile.am	2011-06-25 13:15:56.544510400 +0200
@@ -26,6 +26,7 @@
 	winmultiwindowwm.c \
 	winmultiwindowwndproc.c
 DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
+MULTIWINDOW_LIBS = -lshlwapi
 endif
 
 if XWIN_MULTIWINDOWEXTWM
@@ -149,7 +150,7 @@
 INCLUDES = -I$(top_srcdir)/miext/rootless
 
 XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS)
-XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
+XWin_LDADD = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
 XWin_LDFLAGS = -mwindows -static
 
 .rc.o:
diff -urN src/xserver-cygwin-1.10.1-1/hw/xwin/taskbar.h src/xserver-cygwin-1.10.1-1/hw/xwin/taskbar.h
--- src/xserver-cygwin-1.10.1-1/hw/xwin/taskbar.h	1970-01-01 01:00:00.000000000 +0100
+++ src/xserver-cygwin-1.10.1-1/hw/xwin/taskbar.h	2011-06-25 14:08:15.768141100 +0200
@@ -0,0 +1,44 @@
+#ifndef _TASKBAR_H
+#define _TASKBAR_H
+
+#include <winnt.h>
+#include <wingdi.h>
+#include <objbase.h>
+#include <initguid.h>
+
+typedef struct _tagpropertykey {
+    GUID fmtid;
+    DWORD pid;
+} PROPERTYKEY;
+#define REFPROPERTYKEY const PROPERTYKEY *
+#define REFPROPVARIANT const PROPVARIANT *
+
+#ifdef INTERFACE
+#undef INTERFACE
+#endif
+
+#define INTERFACE IPropertyStore
+DECLARE_INTERFACE_(IPropertyStore,IUnknown)
+{
+	STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
+	STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+	STDMETHOD_(ULONG,Release)(THIS) PURE;
+	STDMETHOD(GetCount)(THIS_ DWORD) PURE;
+	STDMETHOD(GetAt)(THIS_ DWORD,PROPERTYKEY) PURE;
+	STDMETHOD(GetValue)(THIS_ REFPROPERTYKEY,PROPVARIANT) PURE;
+	STDMETHOD(SetValue)(THIS_ REFPROPERTYKEY,REFPROPVARIANT) PURE;
+	STDMETHOD(Commit)(THIS) PURE;
+};
+#undef INTERFACE
+typedef IPropertyStore *LPPROPERTYSTORE;
+
+DEFINE_GUID(IID_IPropertyStore,0x886d8eeb, 0x8cf2, 0x4446, 0x8d,0x02, 0xcd,0xba,0x1d,0xbd,0xcf,0x99);
+
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) const PROPERTYKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }, pid }
+
+DEFINE_PROPERTYKEY(PKEY_AppUserModel_ID, 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, 5);
+
+typedef HRESULT (__stdcall *SHGETPROPERTYSTOREFORWINDOWPROC)(HWND,REFIID,void**);
+typedef HRESULT (__stdcall *PROPVARIANTCLEARPROC)(PROPVARIANT*);
+
+#endif
diff -urN src/xserver-cygwin-1.10.1-1/hw/xwin/winmultiwindowwm.c src/xserver-cygwin-1.10.1-1/hw/xwin/winmultiwindowwm.c
--- src/xserver-cygwin-1.10.1-1/hw/xwin/winmultiwindowwm.c	2011-04-22 18:03:27.000000000 +0200
+++ src/xserver-cygwin-1.10.1-1/hw/xwin/winmultiwindowwm.c	2011-06-25 14:11:05.671216100 +0200
@@ -61,6 +61,9 @@
 #include "window.h"
 #include "pixmapstr.h"
 #include "windowstr.h"
+#include "taskbar.h"
+
+#include <shlwapi.h>
 
 #ifdef XWIN_MULTIWINDOWEXTWM
 #include <X11/extensions/windowswmstr.h>
@@ -200,6 +203,9 @@
 void
 winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle);
 
+void
+winSetAppID (HWND hWnd, const char* AppID);
+
 /*
  * Local globals
  */
@@ -1671,19 +1677,36 @@
     XFree(normal_hint);
   }
 
-  /* Override hint settings from above with settings from config file */
+  /* 
+    Override hint settings from above with settings from config file and set
+    application id for grouping.
+  */
   {
     XClassHint class_hint = {0,0};
     char *window_name = 0;
-
+    char *application_id = 0;
+    
     if (XGetClassHint(pDisplay, iWindow, &class_hint))
       {
         XFetchName(pDisplay, iWindow, &window_name);
 
         style = winOverrideStyle(class_hint.res_name, class_hint.res_class, window_name);
 
+#define APPLICATION_ID_FORMAT	"%s.xwin.%s"
+#define APPLICATION_ID_UNKNOWN "unknown"
+        if (class_hint.res_class)
+          {         
+            asprintf (&application_id, APPLICATION_ID_FORMAT, XVENDORNAME, class_hint.res_class);
+          }
+        else
+          {
+            asprintf (&application_id, APPLICATION_ID_FORMAT, XVENDORNAME, APPLICATION_ID_UNKNOWN);
+          }
+        winSetAppID (hWnd, application_id);
+        
         if (class_hint.res_name) XFree(class_hint.res_name);
         if (class_hint.res_class) XFree(class_hint.res_class);
+        if (application_id) free(application_id);
         if (window_name) XFree(window_name);
       }
     else
@@ -1691,7 +1714,7 @@
         style = STYLE_NONE;
       }
   }
-
+  
   if (style & STYLE_TOPMOST) *zstyle = HWND_TOPMOST;
   else if (style & STYLE_MAXIMIZE) maxmin = (hint & ~HINT_MIN) | HINT_MAX;
   else if (style & STYLE_MINIMIZE) maxmin = (hint & ~HINT_MAX) | HINT_MIN;
@@ -1789,3 +1812,73 @@
     winUpdateRgnMultiWindow(pWin);
   }
 }
+
+void
+winSetAppID (HWND hWnd, const char* AppID)
+{
+  HMODULE hmodShell32Dll = NULL, hmodOle32Dll = NULL;
+  SHGETPROPERTYSTOREFORWINDOWPROC pSHGetPropertyStoreForWindow = NULL;
+  PROPVARIANTCLEARPROC pPropVariantClear = NULL;
+  PROPVARIANT pv;
+  IPropertyStore *pps = NULL;
+  HRESULT hr;
+
+  hmodShell32Dll = LoadLibrary ("shell32.dll");
+  if (hmodShell32Dll == NULL)
+    {
+      ErrorF ("winSetAppID - Could not load shell32.dll\n");
+      return;
+    }
+    
+  pSHGetPropertyStoreForWindow = (SHGETPROPERTYSTOREFORWINDOWPROC)
+                                        GetProcAddress (hmodShell32Dll,
+                                          "SHGetPropertyStoreForWindow");
+  if (pSHGetPropertyStoreForWindow == NULL)
+    {
+      ErrorF ("winSetAppID - Could not get "
+              "SHGetPropertyStoreForWindow address\n");
+      FreeLibrary (hmodShell32Dll);
+      return;
+    }
+
+    
+  hmodOle32Dll = LoadLibrary ("ole32.dll");
+  if (hmodOle32Dll == NULL)
+    {
+      ErrorF ("winSetAppID - Could not load ole32.dll\n");
+      FreeLibrary (hmodShell32Dll);
+      return;
+    }
+    
+  pPropVariantClear = (PROPVARIANTCLEARPROC)
+                            GetProcAddress (hmodOle32Dll,
+                              "PropVariantClear");
+  if (pPropVariantClear == NULL)
+    {
+      ErrorF ("winSetAppID - Could not get "
+              "PropVariantClear address\n");
+      FreeLibrary (hmodShell32Dll);
+      FreeLibrary (hmodOle32Dll);
+      return;
+    }
+  
+  hr = pSHGetPropertyStoreForWindow (hWnd, &IID_IPropertyStore, (void**)&pps);
+  if(SUCCEEDED(hr) && pps)
+  {
+    memset(&pv, 0, sizeof(PROPVARIANT));
+    pv.vt = VT_LPWSTR;
+    hr = SHStrDupA(AppID, &pv.pwszVal);
+    if(SUCCEEDED(hr))
+    {
+      hr = pps->lpVtbl->SetValue(pps, &PKEY_AppUserModel_ID, &pv);
+      if (pPropVariantClear != NULL )
+        {
+          pPropVariantClear(&pv);
+        }
+    }
+    pps->lpVtbl->Release(pps);
+  }
+  
+  FreeLibrary (hmodOle32Dll);
+  FreeLibrary (hmodShell32Dll);
+}


[-- Attachment #3: Type: text/plain, Size: 223 bytes --]

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://x.cygwin.com/docs/
FAQ:                   http://x.cygwin.com/docs/faq/

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-07-25 10:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-25 12:49 Taskbar grouping in Windows 7 Tobias Häußler
2011-06-29 13:26 ` Jon TURNEY
2011-07-02 16:51   ` Tobias Häußler
2011-07-19 15:31     ` Jon TURNEY
2011-07-25 11:20       ` Tobias Häußler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).