# HG changeset patch # User Andrew Innes # Date 925640847 0 # Node ID 65ebab3569e04fd288b0cbe6737f21bd8f2fd921 # Parent 045e247575d938760d2ccff8c005af2b56b860e7 (sys_kill): Attach to current foreground thread when grabbing focus; necessary on NT 5.0. diff -r 045e247575d9 -r 65ebab3569e0 src/w32proc.c --- 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)) {