summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xwin/InitOutput.c8
-rw-r--r--hw/xwin/Makefile.am3
-rw-r--r--hw/xwin/taskbar.h72
-rw-r--r--hw/xwin/winmultiwindowwm.c127
-rw-r--r--hw/xwin/winmultiwindowwndproc.c3
-rw-r--r--hw/xwin/winwindow.h8
6 files changed, 219 insertions, 2 deletions
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 80cfc3151..1695ab8eb 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -220,6 +220,9 @@ ddxGiveUp (enum ExitCode error)
}
#ifdef XWIN_MULTIWINDOW
+ /* Unload libraries for taskbar grouping */
+ winTaskbarDestroy ();
+
/* Notify the worker threads we're exiting */
winDeinitMultiWindowWM ();
#endif
@@ -1029,6 +1032,11 @@ InitOutput (ScreenInfo *screenInfo, int argc, char *argv[])
/* Detect supported engines */
winDetectSupportedEngines ();
+#ifdef XWIN_MULTIWINDOW
+ /* Load libraries for taskbar grouping */
+ winTaskbarInit ();
+#endif
+
/* Store the instance handle */
g_hInstance = GetModuleHandle (NULL);
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index c24cf2a9c..105163677 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -26,6 +26,7 @@ SRCS_MULTIWINDOW = \
winmultiwindowwm.c \
winmultiwindowwndproc.c
DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
+MULTIWINDOW_LIBS = -lshlwapi
endif
if XWIN_MULTIWINDOWEXTWM
@@ -149,7 +150,7 @@ XWin_SOURCES = $(SRCS)
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 --git a/hw/xwin/taskbar.h b/hw/xwin/taskbar.h
new file mode 100644
index 000000000..bfe301d12
--- /dev/null
+++ b/hw/xwin/taskbar.h
@@ -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 --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 0121da7dc..69de2e417 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -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 pthread_t g_winMultiWindowXMsgProcThread;
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,10 +1682,14 @@ winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle)
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))
{
@@ -1682,8 +1697,21 @@ winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle)
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
@@ -1789,3 +1817,100 @@ winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle)
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;
+ }
+
+ /*
+ PropVariantClear is supported since NT4, but we have no propidl.h to
+ provide a prototype for it
+ */
+ 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;
+ }
+
+ winDebug ("winSetAppID - hwnd 0x%08x appid '%s'\n", hWnd, AppID);
+
+ 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 --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index f1fdf42f3..34f9d21a6 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -832,6 +832,9 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
break;
case WM_CLOSE:
+ /* Remove property AppUserModelID */
+ winSetAppID (hwnd, NULL);
+
/* Branch on if the window was killed in X already */
if (pWinPriv->fXKilled)
{
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 7783e190e..d1143cd2d 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -158,6 +158,14 @@ winDeinitMultiWindowWM (void);
void
winMinimizeWindow (Window id);
+void
+winTaskbarInit (void);
+
+void
+winTaskbarDestroy (void);
+
+void
+winSetAppID (HWND hWnd, const char* AppID);
/*
* winmultiwindowicons.c