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
* Re: Taskbar grouping in Windows 7
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
0 siblings, 1 reply; 5+ messages in thread
From: Jon TURNEY @ 2011-06-29 13:26 UTC (permalink / raw)
To: cygwin-xfree; +Cc: tobias.haeussler
On 25/06/2011 13:48, Tobias HäuÃler wrote:
> 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...
Firstly, thanks very much for this patch.
Getting Windows to correctly group XWin windows on the taskbar is something
that has needed fixing for a while, so it's great to have it done :-)
A few minor comments included inline:
> 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
Can you start this file with the license information, like all other files.
This should also serve to confirm that you are happy for me to forward this
upstream to be distributed under the MIT/X11 license [1]
> @@ -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);
> +
Looks like this function can be made static?
> /*
> * 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;
> + }
Since the results of LoadLibrary/GetProcAddress are invariant at run-time, I'd
rather these calls were done once, rather than every time we want to use those
results.
It would also be useful to include a comment mentioning which version of
Windows these interfaces were added in (so future generations will know when
they can directly link to those functions :-))
I assume that there is no way to achieve this functionality prior for Windows
7, rather than an alternative interface which you chose not to use?
> +
> + 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));
Should be PropVariantInit() ?
> + 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);
> + }
The MSDN description of SHGetPropertyStoreForWindow() says:
"A window's properties must be removed before the window is closed. If this is
not done, the resources used by those properties are not returned to the system."
Does this not apply in this case, or is some cleanup needed?
> +
> + FreeLibrary (hmodOle32Dll);
> + FreeLibrary (hmodShell32Dll);
> +}
[1] http://cgit.freedesktop.org/xorg/xserver/tree/COPYING
--
Jon TURNEY
Volunteer Cygwin/X X Server maintainer
--
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
* Re: Taskbar grouping in Windows 7
2011-06-29 13:26 ` Jon TURNEY
@ 2011-07-02 16:51 ` Tobias Häußler
2011-07-19 15:31 ` Jon TURNEY
0 siblings, 1 reply; 5+ messages in thread
From: Tobias Häußler @ 2011-07-02 16:51 UTC (permalink / raw)
To: cygwin-xfree
[-- Attachment #1: Type: text/plain, Size: 2694 bytes --]
On 29/06/2011 15:25, Jon TURNEY wrote:
> On 25/06/2011 13:48, Tobias HäuÃler wrote:
>> 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...
>
> Firstly, thanks very much for this patch.
>
> Getting Windows to correctly group XWin windows on the taskbar is something
> that has needed fixing for a while, so it's great to have it done :-)
>
Thanks for your suggestions! I changed the code you mentioned.
> A few minor comments included inline:
>> [...]
> Can you start this file with the license information, like all other files.
>
> This should also serve to confirm that you are happy for me to forward this
> upstream to be distributed under the MIT/X11 license [1]
>
Done. I copied the license text from another file...
>> [...]
>
> Looks like this function can be made static?
>
Yes, however for proper cleanup this function is now also called from
the WM_DESTROY handler and I left it non-static.
>> [...]
>
> Since the results of LoadLibrary/GetProcAddress are invariant at run-time, I'd
> rather these calls were done once, rather than every time we want to use those
> results.
>
> It would also be useful to include a comment mentioning which version of
> Windows these interfaces were added in (so future generations will know when
> they can directly link to those functions :-))
>
> I assume that there is no way to achieve this functionality prior for Windows
> 7, rather than an alternative interface which you chose not to use?
>
The initialization/deinitialization is now done only once when XWin is
started/stopped. I am not sure if there is an API to control the taskbar
grouping on older versions of Windows, therefore I have choosen this one...
>> [...]
>
> Should be PropVariantInit() ?
>
I cannot use PropVariantInit() for the initialization of the PROPVARIANT
structure because it is not supported bei the w32api of cygwin (or at
least I cannot find it). According to the Microsoft SDK, PropVariantInit
only calls memset.
>> [...]
>
> The MSDN description of SHGetPropertyStoreForWindow() says:
> "A window's properties must be removed before the window is closed. If this is
> not done, the resources used by those properties are not returned to the system."
>
> Does this not apply in this case, or is some cleanup needed?
>
You are right about that, I added code for cleanup.
>> [...]
>
> [1] http://cgit.freedesktop.org/xorg/xserver/tree/COPYING
>
Tobias
[-- Attachment #2: taskbar.patch --]
[-- Type: text/plain, Size: 11243 bytes --]
diff -uNr src/xserver-cygwin-1.10.1-1/hw/xwin/InitOutput.c src/xserver-cygwin-1.10.1-1/hw/xwin/InitOutput.c
--- src/xserver-cygwin-1.10.1-1/hw/xwin/InitOutput.c 2011-04-22 18:03:27.000000000 +0200
+++ src/xserver-cygwin-1.10.1-1/hw/xwin/InitOutput.c 2011-07-01 20:11:55.028448200 +0200
@@ -219,6 +219,9 @@
}
#ifdef XWIN_MULTIWINDOW
+ /* Unload libraries for taskbar grouping */
+ winTaskbarDestroy ();
+
/* Notify the worker threads we're exiting */
winDeinitMultiWindowWM ();
#endif
@@ -984,6 +987,11 @@
/* Detect supported engines */
winDetectSupportedEngines ();
+#ifdef XWIN_MULTIWINDOW
+ /* Load libraries for taskbar grouping */
+ winTaskbarInit ();
+#endif
+
/* Store the instance handle */
g_hInstance = GetModuleHandle (NULL);
diff -uNr 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-07-01 21:27:18.840399400 +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 -uNr 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-07-01 21:10:40.698151400 +0200
@@ -0,0 +1,72 @@
+/*
+ *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ *Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ *"Software"), to deal in the Software without restriction, including
+ *without limitation the rights to use, copy, modify, merge, publish,
+ *distribute, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ */
+
+#ifndef _TASKBAR_H
+#define _TASKBAR_H
+
+#include <windows.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);
+
+#ifdef INITGUID
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) GUID_EXT const PROPERTYKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
+#else
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) GUID_EXT const PROPERTYKEY name
+#endif
+
+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 -uNr 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-07-01 22:05:50.932997900 +0200
@@ -62,6 +62,13 @@
#include "pixmapstr.h"
#include "windowstr.h"
+#include <shlwapi.h>
+
+#define INITGUID
+#include "initguid.h"
+#include "taskbar.h"
+#undef INITGUID
+
#ifdef XWIN_MULTIWINDOWEXTWM
#include <X11/extensions/windowswmstr.h>
#else
@@ -213,6 +220,10 @@
static Bool g_shutdown = FALSE;
static Bool redirectError = FALSE;
static Bool g_fAnotherWMRunning = FALSE;
+static HMODULE g_hmodShell32Dll = NULL;
+static HMODULE g_hmodOle32Dll = NULL;
+static SHGETPROPERTYSTOREFORWINDOWPROC g_pSHGetPropertyStoreForWindow = NULL;
+static PROPVARIANTCLEARPROC g_pPropVariantClear = NULL;
/*
* PushMessage - Push a message onto the queue
@@ -1671,19 +1682,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 +1719,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 +1817,97 @@
winUpdateRgnMultiWindow(pWin);
}
}
+
+void
+winTaskbarInit (void)
+{
+ /* Load libraries and get function pointers to SHGetPropertyStoreForWindow
+ and PropVariantClear for winSetAppID().
+ SHGetPropertyStoreForWindow is only supported since Windows 7. On previous
+ versions the pointer will be NULL and taskbar grouping is not supported.
+ winSetAppID() will do nothing in this case. */
+
+ g_hmodShell32Dll = LoadLibrary ("shell32.dll");
+ if (g_hmodShell32Dll == NULL)
+ {
+ ErrorF ("winTaskbarInit - Could not load shell32.dll\n");
+ return;
+ }
+
+ g_pSHGetPropertyStoreForWindow = (SHGETPROPERTYSTOREFORWINDOWPROC)
+ GetProcAddress (g_hmodShell32Dll,
+ "SHGetPropertyStoreForWindow");
+ if (g_pSHGetPropertyStoreForWindow == NULL)
+ {
+ ErrorF ("winTaskbarInit - Could not get "
+ "SHGetPropertyStoreForWindow address\n");
+ return;
+ }
+
+
+ g_hmodOle32Dll = LoadLibrary ("ole32.dll");
+ if (g_hmodOle32Dll == NULL)
+ {
+ ErrorF ("winTaskbarInit - Could not load ole32.dll\n");
+ return;
+ }
+
+ g_pPropVariantClear = (PROPVARIANTCLEARPROC)
+ GetProcAddress (g_hmodOle32Dll,
+ "PropVariantClear");
+ if (g_pPropVariantClear == NULL)
+ {
+ ErrorF ("winTaskbarInit - Could not get "
+ "g_pPropVariantClear address\n");
+ return;
+ }
+}
+
+void
+winTaskbarDestroy (void)
+{
+ if (g_hmodOle32Dll != NULL)
+ {
+ FreeLibrary (g_hmodOle32Dll);
+ g_hmodOle32Dll = NULL;
+ g_pPropVariantClear = NULL;
+ }
+ if (g_hmodShell32Dll != NULL)
+ {
+ FreeLibrary (g_hmodShell32Dll);
+ g_hmodShell32Dll = NULL;
+ g_pSHGetPropertyStoreForWindow = NULL;
+ }
+}
+
+void
+winSetAppID (HWND hWnd, const char* AppID)
+{
+ PROPVARIANT pv;
+ IPropertyStore *pps = NULL;
+ HRESULT hr;
+
+ if (g_pSHGetPropertyStoreForWindow == NULL ||
+ g_pPropVariantClear == NULL)
+ {
+ return;
+ }
+
+ hr = g_pSHGetPropertyStoreForWindow (hWnd, &IID_IPropertyStore, (void**)&pps);
+ if(SUCCEEDED(hr) && pps)
+ {
+ memset(&pv, 0, sizeof(PROPVARIANT));
+ if(AppID)
+ {
+ pv.vt = VT_LPWSTR;
+ hr = SHStrDupA(AppID, &pv.pwszVal);
+ }
+
+ if(SUCCEEDED(hr))
+ {
+ hr = pps->lpVtbl->SetValue(pps, &PKEY_AppUserModel_ID, &pv);
+ g_pPropVariantClear(&pv);
+ }
+ pps->lpVtbl->Release(pps);
+ }
+}
diff -uNr src/xserver-cygwin-1.10.1-1/hw/xwin/winmultiwindowwndproc.c src/xserver-cygwin-1.10.1-1/hw/xwin/winmultiwindowwndproc.c
--- src/xserver-cygwin-1.10.1-1/hw/xwin/winmultiwindowwndproc.c 2011-04-22 18:03:27.000000000 +0200
+++ src/xserver-cygwin-1.10.1-1/hw/xwin/winmultiwindowwndproc.c 2011-07-01 19:23:06.977633000 +0200
@@ -832,6 +832,9 @@
break;
case WM_CLOSE:
+ /* Remove property AppUserModelID */
+ winSetAppID (hwnd, NULL);
+
/* Branch on if the window was killed in X already */
if (pWinPriv->fXKilled)
{
diff -uNr src/xserver-cygwin-1.10.1-1/hw/xwin/winwindow.h src/xserver-cygwin-1.10.1-1/hw/xwin/winwindow.h
--- src/xserver-cygwin-1.10.1-1/hw/xwin/winwindow.h 2011-04-22 18:03:27.000000000 +0200
+++ src/xserver-cygwin-1.10.1-1/hw/xwin/winwindow.h 2011-07-01 20:15:07.290362400 +0200
@@ -159,6 +159,14 @@
void
winMinimizeWindow (Window id);
+void
+winTaskbarInit (void);
+
+void
+winTaskbarDestroy (void);
+
+void
+winSetAppID (HWND hWnd, const char* AppID);
/*
* winmultiwindowicons.c
[-- 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
* Re: Taskbar grouping in Windows 7
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
0 siblings, 1 reply; 5+ messages in thread
From: Jon TURNEY @ 2011-07-19 15:31 UTC (permalink / raw)
To: cygwin-xfree; +Cc: Tobias Häußler
On 01/07/2011 21:38, Tobias Häußler wrote:
> On 29/06/2011 15:25, Jon TURNEY wrote:
>> On 25/06/2011 13:48, Tobias Häußler wrote:
>>> 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...
>>
>> Firstly, thanks very much for this patch.
>>
>> Getting Windows to correctly group XWin windows on the taskbar is something
>> that has needed fixing for a while, so it's great to have it done :-)
>
> Thanks for your suggestions! I changed the code you mentioned.
Thanks. I've included this patch into the 1.10.3-1 package.
I noticed that there are a couple of warnings issued when building
> CC winmultiwindowwm.o
> In file included from winmultiwindowwm.c:69:0:
> taskbar.h:59:19: warning: ‘IID_IPropertyStore’ initialized and declared ‘extern’
> taskbar.h:67:53: warning: ‘PKEY_AppUserModel_ID’ initialized and declared ‘extern’
This seems to be related to the nonsense that is INITGUID. I'm not sure how
to fix this warning. Would moving all the GUIDs we use (including the DirectX
ones we use) to a separate file and compiling that with INITGUID defined be
the correct solution?
The other thing I noticed is that PropVariantClear() has been provided by
ole32.dll since at least NT4, so there's no need to dynamically link with it.
So I'm confused as to why you are using GetProcAddress for that?
--
Jon TURNEY
Volunteer Cygwin/X X Server maintainer
--
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
* Re: Taskbar grouping in Windows 7
2011-07-19 15:31 ` Jon TURNEY
@ 2011-07-25 11:20 ` Tobias Häußler
0 siblings, 0 replies; 5+ messages in thread
From: Tobias Häußler @ 2011-07-25 11:20 UTC (permalink / raw)
To: cygwin-xfree
On 19.07.2011 17:17, Jon TURNEY wrote:
> On 01/07/2011 21:38, Tobias Häußler wrote:
>> On 29/06/2011 15:25, Jon TURNEY wrote:
>>> On 25/06/2011 13:48, Tobias Häußler wrote:
>>>> 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...
>>>
>>> Firstly, thanks very much for this patch.
>>>
>>> Getting Windows to correctly group XWin windows on the taskbar is something
>>> that has needed fixing for a while, so it's great to have it done :-)
>>
>> Thanks for your suggestions! I changed the code you mentioned.
>
> Thanks. I've included this patch into the 1.10.3-1 package.
>
> I noticed that there are a couple of warnings issued when building
>
>> CC winmultiwindowwm.o
>> In file included from winmultiwindowwm.c:69:0:
>> taskbar.h:59:19: warning: ‘IID_IPropertyStore’ initialized and declared ‘extern’
>> taskbar.h:67:53: warning: ‘PKEY_AppUserModel_ID’ initialized and declared ‘extern’
>
> This seems to be related to the nonsense that is INITGUID. I'm not sure how
> to fix this warning. Would moving all the GUIDs we use (including the DirectX
> ones we use) to a separate file and compiling that with INITGUID defined be
> the correct solution?
I don't know the right way to deal with that, but it seems to work if
taskbar.h is included in a separate .c-file with INITGUID defined, and
in winmultiwindowwm.c without:
--- taskbar.c:
#define INITGUID
#include <basetyps.h>
#include <shlguid.h>
#include "taskbar.h"
--- winmultiwindowwm.c:
#include "taskbar.h"
The current solution produces this warning because of the declaration of
DEFINE_GUID in basetyps.h and initguid.h:
DEFINE_GUID with INITGUID in basetyps.h resolves to:
const GUID IID_IPropertyStore = {a,b,c,...}
DEFINE_GUID without INITGUID in basetyps.h resolves to:
extern const GUID IID_IPropertyStore;
DEFINE_GUID with INITGUID in initguid.h resolves to:
(extern) const GUID IID_IPropertyStore = {a,b,c,...}
Whether extern is appended or not depends on basetyps.h, which is
included before initguid.h.
Including initguid.h (with INITGUID defined) after basetyps.h appends "=
{a,b,c}", but does not remove "extern". In winmultiwindowwm.c this is
the case, as basetyps.h is included by objbase.h before initguid.h.
The DirectX-GUIDs are initialized in the lib*.a-files of w32api,
therefore INITGUID is not necessary and the warnings are not present. As
soon as w32api contains the GUID for IID_IPropertyStore, taskbar.c with
INITGUID can be removed.
>
> The other thing I noticed is that PropVariantClear() has been provided by
> ole32.dll since at least NT4, so there's no need to dynamically link with it.
> So I'm confused as to why you are using GetProcAddress for that?
>
PropVariantClear() is not declared in the header files of w32api, so I
had to link it dynamically.
--
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).