# HG changeset patch # User Jason Rumney # Date 1246376903 0 # Node ID 48d529d3a5a49c0d789ff516242b4d5fee8432d8 # Parent fd001b102e15b8fdc59fc90dfcd3005a17305eff bug#1849 - Windows 7 Taskbar Support * w32term.c (w32_initialize): Use GetModuleHandle for library that is already loaded. Set user model ID if supported (bug#1849). * runemacs.c (set_user_model_id): New function. (WinMain): Use it. * emacsclient.c (w32_give_focus): Use GetModuleHandle for library that is already loaded. (w32_set_user_model_id): New function. (main): Use it to associate emacsclient with emacs (bug#1849). diff -r fd001b102e15 -r 48d529d3a5a4 lib-src/ChangeLog --- a/lib-src/ChangeLog Tue Jun 30 15:23:50 2009 +0000 +++ b/lib-src/ChangeLog Tue Jun 30 15:48:23 2009 +0000 @@ -1,3 +1,10 @@ +2009-06-30 Jason Rumney + + * emacsclient.c (w32_give_focus): Use GetModuleHandle for library + that is already loaded. + (w32_set_user_model_id): New function. + (main): Use it to associate emacsclient with emacs (bug#1849). + 2009-06-29 Jim Meyering Remove useless if-before-free test. diff -r fd001b102e15 -r 48d529d3a5a4 lib-src/emacsclient.c --- a/lib-src/emacsclient.c Tue Jun 30 15:23:50 2009 +0000 +++ b/lib-src/emacsclient.c Tue Jun 30 15:48:23 2009 +0000 @@ -392,6 +392,33 @@ return NULL; } +void +w32_set_user_model_id () +{ + HMODULE shell; + HRESULT (WINAPI * set_user_model) (PWCSTR); + + /* On Windows 7 and later, we need to set the user model ID + to associate emacsclient launched files with Emacs frames + in the UI. */ + shell = LoadLibrary("shell32.dll"); + if (shell) + { + set_user_model + = (void *) GetProcAddress (shell, + "SetCurrentProcessExplicitAppUserModelID"); + /* If the function is defined, then we are running on Windows 7 + or newer, and the UI uses this to group related windows + together. Since emacs, runemacs, emacsclient are related, we + want them grouped even though the executables are different, + so we need to set a consistent ID between them. */ + if (set_user_model) + set_user_model (L"GNU.Emacs"); + + FreeLibrary (shell); + } +} + int w32_window_app () { @@ -1415,22 +1442,23 @@ void w32_give_focus () { - HMODULE hUser32; + HANDLE user32; /* It shouldn't happen when dealing with TCP sockets. */ if (!emacs_pid) return; - if (!(hUser32 = LoadLibrary ("user32.dll"))) return; + user32 = GetModuleHandle ("user32.dll"); + + if (!user32) + return; /* Modern Windows restrict which processes can set the foreground window. emacsclient can allow Emacs to grab the focus by calling the function AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and NT) lack this function, so we have to check its availability. */ - if ((set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow")) - && (get_wc = GetProcAddress (hUser32, "RealGetWindowClassA"))) + if ((set_fg = GetProcAddress (user32, "AllowSetForegroundWindow")) + && (get_wc = GetProcAddress (user32, "RealGetWindowClassA"))) EnumWindows (w32_find_emacs_process, (LPARAM) 0); - - FreeLibrary (hUser32); } #endif @@ -1501,6 +1529,12 @@ main_argv = argv; progname = argv[0]; +#ifdef WINDOWSNT + /* On Windows 7 and later, we need to explicitly associate emacsclient + with emacs so the UI behaves sensibly. */ + w32_set_user_model_id (); +#endif + /* Process options. */ decode_options (argc, argv); diff -r fd001b102e15 -r 48d529d3a5a4 nt/ChangeLog --- a/nt/ChangeLog Tue Jun 30 15:23:50 2009 +0000 +++ b/nt/ChangeLog Tue Jun 30 15:48:23 2009 +0000 @@ -1,3 +1,8 @@ +2009-06-30 Jason Rumney + + * runemacs.c (set_user_model_id): New function. + (WinMain): Use it. + 2009-06-21 Chong Yidong * Branch for 23.1. diff -r fd001b102e15 -r 48d529d3a5a4 nt/runemacs.c --- a/nt/runemacs.c Tue Jun 30 15:23:50 2009 +0000 +++ b/nt/runemacs.c Tue Jun 30 15:48:23 2009 +0000 @@ -43,6 +43,8 @@ #include #include +static void set_user_model_id (); + int WINAPI WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow) { @@ -56,6 +58,8 @@ char *p; char modname[MAX_PATH]; + set_user_model_id (); + if (!GetModuleFileName (NULL, modname, MAX_PATH)) goto error; if ((p = strrchr (modname, '\\')) == NULL) @@ -170,5 +174,32 @@ return 1; } +void set_user_model_id () +{ + HMODULE shell; + HRESULT (WINAPI * set_user_model) (PCWSTR); + + /* On Windows 7 and later, we need to set the user model ID + to associate emacsclient launched files with Emacs frames + in the UI. */ + shell = LoadLibrary ("shell32.dll"); + if (shell) + { + set_user_model + = (void *) GetProcAddress (shell, + "SetCurrentProcessExplicitAppUserModelID"); + + /* If the function is defined, then we are running on Windows 7 + or newer, and the UI uses this to group related windows + together. Since emacs, runemacs, emacsclient are related, we + want them grouped even though the executables are different, + so we need to set a consistent ID between them. */ + if (set_user_model) + set_user_model (L"GNU.Emacs"); + + FreeLibrary (shell); + } +} + /* arch-tag: 7e02df73-4df7-4aa0-baea-99c6d047a384 (do not change this comment) */ diff -r fd001b102e15 -r 48d529d3a5a4 src/ChangeLog --- a/src/ChangeLog Tue Jun 30 15:23:50 2009 +0000 +++ b/src/ChangeLog Tue Jun 30 15:48:23 2009 +0000 @@ -1,3 +1,9 @@ +2009-06-30 Jason Rumney + + * w32term.c (w32_initialize): Use GetModuleHandle for library that + is already loaded. + Set user model ID if supported (bug#1849). + 2009-06-29 Jim Meyering Remove useless if-before-xfree test. diff -r fd001b102e15 -r 48d529d3a5a4 src/w32term.c --- a/src/w32term.c Tue Jun 30 15:23:50 2009 +0000 +++ b/src/w32term.c Tue Jun 30 15:48:23 2009 +0000 @@ -138,7 +138,7 @@ #endif /* Dynamic linking to SetLayeredWindowAttribute (only since 2000). */ -BOOL (PASCAL *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD); +BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD); #ifndef LWA_ALPHA #define LWA_ALPHA 0x02 @@ -6340,6 +6340,9 @@ static void w32_initialize () { + HANDLE shell; + HRESULT (WINAPI * set_user_model) (PCWSTR); + baud_rate = 19200; w32_system_caret_hwnd = NULL; @@ -6347,6 +6350,25 @@ w32_system_caret_x = 0; w32_system_caret_y = 0; + /* On Windows 7 and later, we need to set the user model ID + to associate emacsclient launched files with Emacs frames + in the UI. */ + shell = GetModuleHandle ("shell32.dll"); + if (shell) + { + set_user_model + = (void *) GetProcAddress (shell, + "SetCurrentProcessExplicitAppUserModelID"); + + /* If the function is defined, then we are running on Windows 7 + or newer, and the UI uses this to group related windows + together. Since emacs, runemacs, emacsclient are related, we + want them grouped even though the executables are different, + so we need to set a consistent ID between them. */ + if (set_user_model) + set_user_model (L"GNU.Emacs"); + } + /* Initialize w32_use_visible_system_caret based on whether a screen reader is in use. */ if (!SystemParametersInfo (SPI_GETSCREENREADER, 0, @@ -6400,7 +6422,7 @@ /* Dynamically link to optional system components. */ { - HANDLE user_lib = LoadLibrary ("user32.dll"); + HMODULE user_lib = GetModuleHandle ("user32.dll"); #define LOAD_PROC(lib, fn) pfn##fn = (void *) GetProcAddress (lib, #fn) @@ -6408,8 +6430,6 @@ #undef LOAD_PROC - FreeLibrary (user_lib); - /* Ensure scrollbar handle is at least 5 pixels. */ vertical_scroll_bar_min_handle = 5;