]> git.eshelyaron.com Git - emacs.git/commitdiff
bug#1849 - Windows 7 Taskbar Support
authorJason Rumney <jasonr@gnu.org>
Tue, 30 Jun 2009 15:48:23 +0000 (15:48 +0000)
committerJason Rumney <jasonr@gnu.org>
Tue, 30 Jun 2009 15:48:23 +0000 (15:48 +0000)
* 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).

lib-src/ChangeLog
lib-src/emacsclient.c
nt/ChangeLog
nt/runemacs.c
src/ChangeLog
src/w32term.c

index 590af7692efd60b2976329dcfe953018d1194ddd..4969b93734d1a96bd6846d6db79b9749dfcaa3f8 100644 (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.
index a451c1b9ba40dbe1d45422c1d4b0c7cd9c7799d8..5e6db54a90221a2664400e1d3eae50ab99eb76a2 100644 (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);
 
index d8f9685587c778772611848d02f75a10b19dc2ff..e4c95671aff9577b9962e2e6493846227d0dbe94 100644 (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.
index 55a520f7bc740517a975356ec8b4b2d861d06372..aba1d439957bd80684b663868398b99b4acd0fb3 100644 (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 @@ error:
   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) */
index dcf58c7f631bedda5fdff9abc0f01a0af10bddf6..b06bf4fac8ca09e38e5c4a6423ca90b98da819b5 100644 (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.
index 209e86edc8b72b5bab1e71af912a17fb11f3b911..c3cfc3411694f8354e7908edac8edf574217739f 100644 (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;