From 5d50aea73aace09f914ff95d90b771270aef1ab8 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 2 Jul 2016 09:57:34 -0700 Subject: Fix spawned process window not foregrounding. This patch addresses an issue whereby the window of a process created with CreateProcess fails to come to the foreground. This occurs when the calling process itself hasn't run any Windows event processing loop. A repro test case is to make a program with a main, and and call CreateProcess to spawn calc.exe or notepad.exe before doing anything else. It turns out that a dummy call to TranslateMessage makes this issue goes away. If such a call is made before CreateProcess, then the spawned process' window comes up in the foreground as expected. * winsup/cygwin/Makefile.in (DLL_IMPORTS): We need to link in user32.dll to call TranslateMessage. Condense the multiple ${shell ...} call repetition with a foreach. * winsup/cygwin/spawn.cc (child_info_spawn::worker): Do the dummy TranslateMessage call before the section of code that calls CreateProcess or CreateProcessAsUser. --- winsup/cygwin/Makefile.in | 3 ++- winsup/cygwin/spawn.cc | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 70da06fdf..ec6203d50 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -147,7 +147,8 @@ EXTRA_OFILES:= MALLOC_OFILES:=malloc.o -DLL_IMPORTS:=${shell $(CC) -print-file-name=w32api/libkernel32.a} ${shell $(CC) -print-file-name=w32api/libntdll.a} +DLL_IMPORTS:=${foreach i,kernel32 user32 ntdll,\ + ${shell $(CC) -print-file-name=w32api/lib${i}.a}} MT_SAFE_OBJECTS:= # diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index ff2d56d39..87cfb3a69 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -570,6 +570,12 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, SetHandleInformation (my_wr_proc_pipe, HANDLE_FLAG_INHERIT, 0); parent_winpid = GetCurrentProcessId (); + /* Workaround for the issue of the window of a spawned process + not coming to the foreground. A useless call to TranslateMessage + cures this somehow. */ + MSG dummy = { 0 }; + (void) TranslateMessage(&dummy); + loop: /* When ruid != euid we create the new process under the current original account and impersonate in child, this way maintaining the different -- cgit v1.2.3