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).
This commit is contained in:
Jason Rumney 2009-06-30 15:48:23 +00:00
parent 974647ac91
commit ff90fbdecc
6 changed files with 113 additions and 10 deletions

View file

@ -1,3 +1,10 @@
2009-06-30 Jason Rumney <jasonr@gnu.org>
* 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 <meyering@redhat.com>
Remove useless if-before-free test.

View file

@ -392,6 +392,33 @@ w32_getenv (envvar)
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 @@ w32_find_emacs_process (hWnd, lParam)
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 (argc, argv)
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);

View file

@ -1,3 +1,8 @@
2009-06-30 Jason Rumney <jasonr@gnu.org>
* runemacs.c (set_user_model_id): New function.
(WinMain): Use it.
2009-06-21 Chong Yidong <cyd@stupidchicken.com>
* Branch for 23.1.

View file

@ -43,6 +43,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <string.h>
#include <malloc.h>
static void set_user_model_id ();
int WINAPI
WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
{
@ -56,6 +58,8 @@ WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
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 @@ WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
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) */

View file

@ -1,3 +1,9 @@
2009-06-30 Jason Rumney <jasonr@gnu.org>
* 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 <meyering@redhat.com>
Remove useless if-before-xfree test.

View file

@ -138,7 +138,7 @@ typedef struct tagGLYPHSET
#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 @@ DWORD WINAPI w32_msg_worker (void * arg);
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_initialize ()
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 @@ w32_initialize ()
/* 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 @@ w32_initialize ()
#undef LOAD_PROC
FreeLibrary (user_lib);
/* Ensure scrollbar handle is at least 5 pixels. */
vertical_scroll_bar_min_handle = 5;