shell/source/win32/SysShExec.cxx |   49 +++++++++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 14 deletions(-)

New commits:
commit e132f392594037ec9524c2da5304138405158744
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sun Oct 28 19:14:28 2018 +0300
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Thu Apr 4 09:34:22 2019 +0200

    tdf#120703 PVS: V547 Fix activation of launched process' window
    
    V547 Expression 'procHandle != nullptr' is always false.
    
    The code was nonsensical overall. First, the launched process handle
    was never returned by ShellExecuteExW, because SEE_MASK_NOCLOSEPROCESS
    wasn't used, so GetProcessId couldn't succeed. Then, nullptr window
    handle was passed to GetWindowThreadProcessId, thus never returning a
    meaningful result.
    
    This reimplements this to find the launched process' main window by
    first waiting for process idle (up to 1-second delay is possible),
    then enumerating all the top-level windows and checking their process.
    
    Change-Id: I5fb4c04147b3f9414e27650a023f7844523c18bd
    Reviewed-on: https://gerrit.libreoffice.org/62478
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/shell/source/win32/SysShExec.cxx b/shell/source/win32/SysShExec.cxx
index 55b20e62fc46..05daf97586d8 100644
--- a/shell/source/win32/SysShExec.cxx
+++ b/shell/source/win32/SysShExec.cxx
@@ -245,6 +245,34 @@ CSysShExec::CSysShExec( const Reference< 
css::uno::XComponentContext >& xContext
     CoInitialize( nullptr );
 }
 
+namespace
+{
+// This callback checks if the found window is the specified process's 
top-level window,
+// and activates the first found such window.
+BOOL CALLBACK FindAndActivateProcWnd(HWND hwnd, LPARAM lParam)
+{
+    if (!IsWindowVisible(hwnd))
+        return TRUE; // continue enumeration
+    if (GetWindow(hwnd, GW_OWNER)) // not a top-level window
+        return TRUE; // continue enumeration
+    const DWORD nParamProcId = static_cast<DWORD>(lParam);
+    assert(nParamProcId != 0);
+    DWORD nWndProcId = 0;
+    (void)GetWindowThreadProcessId(hwnd, &nWndProcId);
+    if (nWndProcId != nParamProcId)
+        return TRUE; // continue enumeration
+
+    // Found it! Bring it to front
+    if (IsIconic(hwnd))
+    {
+        ShowWindow(hwnd, SW_RESTORE);
+    }
+    SetForegroundWindow(hwnd);
+    SetActiveWindow(hwnd);
+    return FALSE; // stop enumeration
+}
+}
+
 void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& 
aParameter, sal_Int32 nFlags )
 {
     // parameter checking
@@ -301,9 +329,10 @@ void SAL_CALL CSysShExec::execute( const OUString& 
aCommand, const OUString& aPa
     sei.lpFile       = o3tl::toW(preprocessed_command.getStr());
     sei.lpParameters = o3tl::toW(aParameter.getStr());
     sei.nShow        = SW_SHOWNORMAL;
+    sei.fMask = SEE_MASK_NOCLOSEPROCESS; // we need sei.hProcess
 
     if (NO_SYSTEM_ERROR_MESSAGE & nFlags)
-        sei.fMask = SEE_MASK_FLAG_NO_UI;
+        sei.fMask |= SEE_MASK_FLAG_NO_UI;
 
     SetLastError( 0 );
 
@@ -327,20 +356,12 @@ void SAL_CALL CSysShExec::execute( const OUString& 
aCommand, const OUString& aPa
     else
     {
         // Get Permission make changes to the Window of the created Process
-        HWND procHandle = nullptr;
-        DWORD procId = GetProcessId(sei.hProcess);
-        AllowSetForegroundWindow(procId);
-
-        // Get the handle of the created Window
-        DWORD check = 0;
-        GetWindowThreadProcessId(procHandle, &check);
-        SAL_WARN_IF(check != procId, "shell", "Could not get handle of process 
called by shell.");
-
-        // Move created Window into the foreground
-        if(procHandle != nullptr)
+        const DWORD procId = GetProcessId(sei.hProcess);
+        if (procId != 0)
         {
-            SetForegroundWindow(procHandle);
-            SetActiveWindow(procHandle);
+            AllowSetForegroundWindow(procId);
+            WaitForInputIdle(sei.hProcess, 1000); // so that main window is 
created; imperfect
+            EnumWindows(FindAndActivateProcWnd, static_cast<LPARAM>(procId));
         }
     }
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to