changeset 24671:65ebab3569e0

(sys_kill): Attach to current foreground thread when grabbing focus; necessary on NT 5.0.
author Andrew Innes <andrewi@gnu.org>
date Sun, 02 May 1999 10:27:27 +0000
parents 045e247575d9
children 8387918b52c6
files src/w32proc.c
diffstat 1 files changed, 49 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32proc.c	Sun May 02 10:23:06 1999 +0000
+++ b/src/w32proc.c	Sun May 02 10:27:27 1999 +0000
@@ -1359,25 +1359,58 @@
 	    }
 
 	  foreground_window = GetForegroundWindow ();
-	  if (foreground_window && SetForegroundWindow (cp->hwnd))
+	  if (foreground_window)
 	    {
-	      /* Generate keystrokes as if user had typed Ctrl-Break or
-                 Ctrl-C.  */
-	      keybd_event (VK_CONTROL, control_scan_code, 0, 0);
-	      keybd_event (vk_break_code, break_scan_code,
-			   (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0);
-	      keybd_event (vk_break_code, break_scan_code,
-			   (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY)
-			   | KEYEVENTF_KEYUP, 0);
-	      keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0);
+              /* NT 5.0, and apparently also Windows 98, will not allow
+		 a Window to be set to foreground directly without the
+		 user's involvement. The workaround is to attach
+		 ourselves to the thread that owns the foreground
+		 window, since that is the only thread that can set the
+		 foreground window.  */
+              DWORD foreground_thread, child_thread;
+              foreground_thread =
+		GetWindowThreadProcessId (foreground_window, NULL);
+	      if (foreground_thread == GetCurrentThreadId ()
+                  || !AttachThreadInput (GetCurrentThreadId (),
+                                         foreground_thread, TRUE))
+                foreground_thread = 0;
+
+              child_thread = GetWindowThreadProcessId (cp->hwnd, NULL);
+	      if (child_thread == GetCurrentThreadId ()
+                  || !AttachThreadInput (GetCurrentThreadId (),
+                                         child_thread, TRUE))
+                child_thread = 0;
 
-	      /* Sleep for a bit to give time for Emacs frame to respond
-		 to focus change events (if Emacs was active app).  */
-	      Sleep (10);
+              /* Set the foreground window to the child.  */
+              if (SetForegroundWindow (cp->hwnd))
+                {
+                  /* Generate keystrokes as if user had typed Ctrl-Break or
+                     Ctrl-C.  */
+                  keybd_event (VK_CONTROL, control_scan_code, 0, 0);
+                  keybd_event (vk_break_code, break_scan_code,
+		    (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0);
+                  keybd_event (vk_break_code, break_scan_code,
+                    (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY)
+                    | KEYEVENTF_KEYUP, 0);
+                  keybd_event (VK_CONTROL, control_scan_code,
+                               KEYEVENTF_KEYUP, 0);
 
-	      SetForegroundWindow (foreground_window);
-	    }
-	}
+                  /* Sleep for a bit to give time for Emacs frame to respond
+                     to focus change events (if Emacs was active app).  */
+                  Sleep (100);
+
+                  SetForegroundWindow (foreground_window);
+                }
+              /* Detach from the foreground and child threads now that
+                 the foreground switching is over.  */
+              if (foreground_thread)
+                AttachThreadInput (GetCurrentThreadId (),
+                                   foreground_thread, FALSE);
+              if (child_thread)
+                AttachThreadInput (GetCurrentThreadId (),
+                                   child_thread, FALSE);
+            }
+        }
       /* Ctrl-Break is NT equivalent of SIGINT.  */
       else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
         {