Created
March 9, 2014 13:15
-
-
Save silphire/9447590 to your computer and use it in GitHub Desktop.
Windows 7 jumplist patch for mintty
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: Makefile | |
=================================================================== | |
--- Makefile (revision 1322) | |
+++ Makefile (working copy) | |
@@ -69,7 +69,7 @@ | |
endif | |
LDFLAGS := -L$(shell $(CC) -print-file-name=w32api) -static-libgcc | |
-LDLIBS := -mwindows -lcomctl32 -limm32 -lwinspool -lole32 -luuid | |
+LDLIBS := -mwindows -lcomctl32 -limm32 -lwinspool -lole32 -luuid -lshlwapi | |
ifdef DEBUG | |
CFLAGS += -g | |
Index: config.c | |
=================================================================== | |
--- config.c (revision 1322) | |
+++ config.c (working copy) | |
@@ -97,6 +97,15 @@ | |
[BOLD_MAGENTA_I] = 0xFF40FF, | |
[BOLD_CYAN_I] = 0xFFFF40, | |
[BOLD_WHITE_I] = 0xFFFFFF, | |
+ }, | |
+ // Jump List | |
+ .jump_list_cmd = { | |
+ "", "", "", "", "", | |
+ "", "", "", "", "", | |
+ }, | |
+ .jump_list_title = { | |
+ "", "", "", "", "", | |
+ "", "", "", "", "", | |
} | |
}; | |
@@ -209,6 +218,29 @@ | |
{"BoldCyan", OPT_COLOUR, offcfg(ansi_colours[BOLD_CYAN_I])}, | |
{"BoldWhite", OPT_COLOUR, offcfg(ansi_colours[BOLD_WHITE_I])}, | |
+ // Jump List | |
+ {"JumpListCmd0", OPT_STRING, offcfg(jump_list_cmd[0])}, | |
+ {"JumpListCmd1", OPT_STRING, offcfg(jump_list_cmd[1])}, | |
+ {"JumpListCmd2", OPT_STRING, offcfg(jump_list_cmd[2])}, | |
+ {"JumpListCmd3", OPT_STRING, offcfg(jump_list_cmd[3])}, | |
+ {"JumpListCmd4", OPT_STRING, offcfg(jump_list_cmd[4])}, | |
+ {"JumpListCmd5", OPT_STRING, offcfg(jump_list_cmd[5])}, | |
+ {"JumpListCmd6", OPT_STRING, offcfg(jump_list_cmd[6])}, | |
+ {"JumpListCmd7", OPT_STRING, offcfg(jump_list_cmd[7])}, | |
+ {"JumpListCmd8", OPT_STRING, offcfg(jump_list_cmd[8])}, | |
+ {"JumpListCmd9", OPT_STRING, offcfg(jump_list_cmd[9])}, | |
+ | |
+ {"JumpListTitle0", OPT_STRING, offcfg(jump_list_title[0])}, | |
+ {"JumpListTitle1", OPT_STRING, offcfg(jump_list_title[1])}, | |
+ {"JumpListTitle2", OPT_STRING, offcfg(jump_list_title[2])}, | |
+ {"JumpListTitle3", OPT_STRING, offcfg(jump_list_title[3])}, | |
+ {"JumpListTitle4", OPT_STRING, offcfg(jump_list_title[4])}, | |
+ {"JumpListTitle5", OPT_STRING, offcfg(jump_list_title[5])}, | |
+ {"JumpListTitle6", OPT_STRING, offcfg(jump_list_title[6])}, | |
+ {"JumpListTitle7", OPT_STRING, offcfg(jump_list_title[7])}, | |
+ {"JumpListTitle8", OPT_STRING, offcfg(jump_list_title[8])}, | |
+ {"JumpListTitle9", OPT_STRING, offcfg(jump_list_title[9])}, | |
+ | |
// Legacy | |
{"UseSystemColours", OPT_BOOL | OPT_LEGACY, offcfg(use_system_colours)}, | |
{"BoldAsBright", OPT_BOOL | OPT_LEGACY, offcfg(bold_as_colour)}, | |
Index: config.h | |
=================================================================== | |
--- config.h (revision 1322) | |
+++ config.h (working copy) | |
@@ -99,6 +99,9 @@ | |
string word_chars; | |
colour ime_cursor_colour; | |
colour ansi_colours[16]; | |
+ // Jump List | |
+ string jump_list_cmd[10]; | |
+ string jump_list_title[10]; | |
// Legacy | |
bool use_system_colours; | |
} config; | |
Index: jumplist.c | |
=================================================================== | |
--- jumplist.c (revision 0) | |
+++ jumplist.c (working copy) | |
@@ -0,0 +1,208 @@ | |
+#include <objbase.h> | |
+#include <shlobj.h> | |
+#include <shobjidl.h> | |
+#include <propvarutil.h> | |
+#include <propkey.h> | |
+#include <unistd.h> | |
+ | |
+#include "jumplist.h" | |
+#include "charset.h" | |
+#include "config.h" | |
+ | |
+#if WINVER >= 0x0601 | |
+ | |
+static HRESULT clear_jumplist(void) | |
+{ | |
+ HRESULT hr = S_OK; | |
+ ICustomDestinationList *pCustomDestinationList; | |
+ | |
+ hr = CoCreateInstance(&CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER, &IID_ICustomDestinationList, (void **)&pCustomDestinationList); | |
+ if(FAILED(hr)) { | |
+ return hr; | |
+ } | |
+ | |
+ hr = pCustomDestinationList->lpVtbl->DeleteList((void *)pCustomDestinationList, NULL); | |
+ | |
+ pCustomDestinationList->lpVtbl->Release((void *)pCustomDestinationList); | |
+ return hr; | |
+} | |
+ | |
+#ifndef __cplusplus | |
+ | |
+static HRESULT InitPropVariantFromString(PCSTR pString, PROPVARIANT *pPropVariant) | |
+{ | |
+ HRESULT hr = SHStrDupA(pString, &pPropVariant->pwszVal); | |
+ if(SUCCEEDED(hr)) { | |
+ pPropVariant->vt = VT_LPWSTR; | |
+ } else { | |
+ PropVariantInit(pPropVariant); | |
+ } | |
+ | |
+ return hr; | |
+} | |
+ | |
+#endif | |
+ | |
+static HRESULT register_task(IObjectCollection *pObjectCollection, const string title, const string args) | |
+{ | |
+ HRESULT hr = S_OK; | |
+ IShellLink *pShellLink; | |
+ | |
+ if(args == NULL || strlen(args) == 0) | |
+ return S_OK; | |
+ | |
+ const string showTitle = (title == NULL || strlen(title) == 0) ? args : title; | |
+ | |
+ char exePath[MAX_PATH + 1]; | |
+ if(GetModuleFileName(NULL, exePath, MAX_PATH) == 0) | |
+ return S_FALSE; | |
+ | |
+ hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (void **)&pShellLink); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ do { | |
+ | |
+ // set title | |
+ IPropertyStore *pPropertyStore; | |
+ hr = pShellLink->lpVtbl->QueryInterface((void *)pShellLink, &IID_IPropertyStore, (void **)&pPropertyStore); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ PROPVARIANT propVariant; | |
+ | |
+ hr = InitPropVariantFromString(showTitle, &propVariant); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ hr = pPropertyStore->lpVtbl->SetValue((void *)pPropertyStore, &PKEY_Title, &propVariant); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ pPropertyStore->lpVtbl->Commit((void *)pPropertyStore); | |
+ } | |
+ } | |
+ } | |
+ if(FAILED(hr)) | |
+ break; | |
+ | |
+ // set full path of mintty.exe | |
+ hr = pShellLink->lpVtbl->SetPath((void *)pShellLink, exePath); | |
+ if(FAILED(hr)) | |
+ break; | |
+ | |
+ // set arguments | |
+ hr = pShellLink->lpVtbl->SetArguments((void *)pShellLink, args); | |
+ if(FAILED(hr)) | |
+ break; | |
+ | |
+ // finally, register this column into the jump list | |
+ hr = pObjectCollection->lpVtbl->AddObject((void *)pObjectCollection, (IUnknown *)pShellLink); | |
+ } while(0); | |
+ | |
+ pShellLink->lpVtbl->Release((void *)pShellLink); | |
+ } | |
+ | |
+ return hr; | |
+} | |
+ | |
+static HRESULT create_jumplist(const string titles[], const string args[]) | |
+{ | |
+ HRESULT hr = S_OK; | |
+ ICustomDestinationList *pCustomDestinationList; | |
+ | |
+ hr = CoCreateInstance(&CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER, &IID_ICustomDestinationList, (void **)&pCustomDestinationList); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ // register all custom tasks | |
+ size_t len = cs_mbstowcs(0, cfg.app_id, 0) + 1; | |
+ if(len) { | |
+ | |
+ wchar_t wAppID[len]; | |
+ | |
+ cs_mbstowcs(wAppID, cfg.app_id, len); | |
+ hr = pCustomDestinationList->lpVtbl->SetAppID((void *)pCustomDestinationList, wAppID); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ UINT nSlots; | |
+ IObjectArray *pRemovedList; | |
+ | |
+ hr = pCustomDestinationList->lpVtbl->BeginList((void *)pCustomDestinationList, &nSlots, &IID_IObjectArray, (void **)&pRemovedList); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ IObjectCollection *pObjectCollection; | |
+ | |
+ hr = CoCreateInstance(&CLSID_EnumerableObjectCollection, NULL, CLSCTX_INPROC_SERVER, &IID_IObjectCollection, (void **)&pObjectCollection); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ // add all tasks | |
+ for(int i = 0; i < 10; ++i) { | |
+ hr = register_task(pObjectCollection, titles[i], args[i]); | |
+ if(FAILED(hr)) { | |
+ break; | |
+ } | |
+ } | |
+ | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ IObjectArray *pObjectArray; | |
+ | |
+ hr = pObjectCollection->lpVtbl->QueryInterface((void *)pObjectCollection, &IID_IObjectArray, (void **)&pObjectArray); | |
+ if(SUCCEEDED(hr)) { | |
+ | |
+ hr = pCustomDestinationList->lpVtbl->AddUserTasks((void *)pCustomDestinationList, pObjectArray); | |
+ | |
+ pObjectArray->lpVtbl->Release((void *)pObjectArray); | |
+ } | |
+ | |
+ pCustomDestinationList->lpVtbl->CommitList((void *)pCustomDestinationList); | |
+ } | |
+ | |
+ pObjectCollection->lpVtbl->Release((void *)pObjectCollection); | |
+ } | |
+ | |
+ pRemovedList->lpVtbl->Release((void *)pRemovedList); | |
+ } | |
+ } | |
+ } | |
+ | |
+ pCustomDestinationList->lpVtbl->Release((void *)pCustomDestinationList); | |
+ } | |
+ | |
+ return hr; | |
+} | |
+ | |
+HRESULT setup_jumplist(const string titles[], const string args[]) | |
+{ | |
+ OSVERSIONINFO ver; | |
+ ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | |
+ GetVersionEx(&ver); | |
+ | |
+ // if running under the machine older than Windows 7, silently return. | |
+ if(!((ver.dwMajorVersion == 6 && ver.dwMinorVersion >= 1) || ver.dwMajorVersion >= 7)) { | |
+ return S_OK; | |
+ } | |
+ | |
+ HRESULT hr = S_OK; | |
+ | |
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); | |
+ if(FAILED(hr)) | |
+ return hr; | |
+ | |
+ hr = clear_jumplist(); | |
+ if(SUCCEEDED(hr)) { | |
+ hr = create_jumplist(titles, args); | |
+ } | |
+ | |
+ CoUninitialize(); | |
+ return hr; | |
+} | |
+ | |
+#else | |
+ | |
+HRESULT setup_jumplist(const string titles[], const string args[]) | |
+{ | |
+ (void)titles; | |
+ (void)args; | |
+ | |
+ return S_OK; | |
+} | |
+ | |
+#endif | |
+ | |
Index: jumplist.h | |
=================================================================== | |
--- jumplist.h (revision 0) | |
+++ jumplist.h (working copy) | |
@@ -0,0 +1,8 @@ | |
+#ifndef JUMPLIST_H_ | |
+#define JUMPLIST_H_ | |
+ | |
+#include <objbase.h> | |
+ | |
+HRESULT setup_jumplist(const string titles[], const string args[]); | |
+ | |
+#endif // JUMPLIST_H_ | |
Index: std.h | |
=================================================================== | |
--- std.h (revision 1322) | |
+++ std.h (working copy) | |
@@ -41,7 +41,8 @@ | |
char *asform(const char *fmt, ...); | |
-#define WINVER 0x500 // Windows 2000 | |
+// #define WINVER 0x500 // Windows 2000 | |
+#define WINVER 0x601 // Windows 7 | |
#define _WIN32_WINNT WINVER | |
#define _WIN32_IE WINVER | |
Index: winmain.c | |
=================================================================== | |
--- winmain.c (revision 1322) | |
+++ winmain.c (working copy) | |
@@ -9,6 +9,7 @@ | |
#include "appinfo.h" | |
#include "child.h" | |
#include "charset.h" | |
+#include "jumplist.h" | |
#include <locale.h> | |
#include <getopt.h> | |
@@ -41,6 +42,8 @@ | |
int cyBottomHeight; | |
} MARGINS; | |
+#else | |
+#include <dwmapi.h> | |
#endif | |
static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *); | |
@@ -765,7 +768,7 @@ | |
string rc_file = asform("%s/.minttyrc", home); | |
load_config(rc_file); | |
delete(rc_file); | |
- | |
+ | |
for (;;) { | |
int opt = getopt_long(argc, argv, short_opts, opts, 0); | |
if (opt == -1 || opt == 'e') | |
@@ -892,6 +895,8 @@ | |
inst = GetModuleHandle(NULL); | |
+ setup_jumplist(cfg.jump_list_title, cfg.jump_list_cmd); | |
+ | |
// Window class name. | |
wstring wclass = _W(APPNAME); | |
if (*cfg.class) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment