Bug 956286 - Hand off focus rights to the desktop browser process when launched via the command execute handler. r=bbondy a=metro-only
authorJim Mathies <jmathies@mozilla.com>
Wed, 15 Jan 2014 14:24:26 -0600
changeset 175936 b3056af995be7b49da58122745d4a5f8e466e7b6
parent 175935 88443d38a05f677456e46b148aa6de3c6c64d889
child 175937 4308bd949a964a247c2f95f4a4a426ce9aa921ba
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbondy, metro-only
bugs956286
milestone28.0a2
Bug 956286 - Hand off focus rights to the desktop browser process when launched via the command execute handler. r=bbondy a=metro-only
browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
--- a/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
+++ b/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
@@ -264,18 +264,18 @@ public:
     *aLaunchType = GetLaunchType();
     mIsDesktopRequest = (*aLaunchType == AHE_DESKTOP);
     return S_OK;
   }
 
   /**
    * Choose the appropriate launch type based on the user's previously chosen
    * host environment, along with system constraints.
-   * AHE_DESKTOP	= 0
-   * AHE_IMMERSIVE	= 1
+   *
+   * AHE_DESKTOP = 0, AHE_IMMERSIVE = 1
    */
   AHE_TYPE GetLaunchType() {
     AHE_TYPE ahe = GetLastAHE();
     Log(L"Previous AHE: %d", ahe);
 
     if (!mIsRestartMetroRequest && IsProcessRunning(kFirefoxExe, false)) {
       Log(L"Returning AHE_DESKTOP because desktop is already running");
       return AHE_DESKTOP;
@@ -559,17 +559,18 @@ bool CExecuteCommandVerb::SetTargetPath(
 
   return true;
 }
 
 /*
  * Desktop launch - Launch the destop browser to display the current
  * target using shellexecute.
  */
-void LaunchDesktopBrowserWithParams(CStringW& aBrowserPath, CStringW& aVerb, CStringW& aTarget, CStringW& aParameters,
+void LaunchDesktopBrowserWithParams(CStringW& aBrowserPath, CStringW& aVerb,
+                                    CStringW& aTarget, CStringW& aParameters,
                                     bool aTargetIsDefaultBrowser, bool aTargetIsBrowser)
 {
   // If a taskbar shortcut, link or local file is clicked, the target will
   // be the browser exe or file.  Don't pass in -url for the target if the
   // target is known to be a browser.  Otherwise, one instance of Firefox
   // will try to open another instance.
   CStringW params;
   if (!aTargetIsDefaultBrowser && !aTargetIsBrowser && !aTarget.IsEmpty()) {
@@ -584,41 +585,59 @@ void LaunchDesktopBrowserWithParams(CStr
   // Tack on any extra parameters we received (for example -profilemanager)
   if (!aParameters.IsEmpty()) {
     params += " ";
     params += aParameters;
   }
 
   Log(L"Desktop Launch: verb:%s exe:%s params:%s", aVerb, aBrowserPath, params);
 
-  SHELLEXECUTEINFOW seinfo;
-  memset(&seinfo, 0, sizeof(seinfo));
-  seinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
-  seinfo.fMask  = SEE_MASK_FLAG_LOG_USAGE;
-  seinfo.lpVerb = aVerb;
-  seinfo.lpFile = aBrowserPath;
-  seinfo.nShow  = SW_SHOWNORMAL;
-
   // Relaunch in Desktop mode uses a special URL to trick Windows into
-  // switching environments. We shouldn't actually try to open this URL
-  if (_wcsicmp(aTarget, L"http://-desktop/") != 0) {
-    seinfo.lpParameters = params;
+  // switching environments. We shouldn't actually try to open this URL.
+  if (!_wcsicmp(aTarget, L"http://-desktop/")) {
+    // Ignore any params and just launch on desktop
+    params.Empty();
   }
 
-  ShellExecuteEx(&seinfo);
+  PROCESS_INFORMATION procInfo;
+  STARTUPINFO startInfo;
+  memset(&procInfo, 0, sizeof(PROCESS_INFORMATION));
+  memset(&startInfo, 0, sizeof(STARTUPINFO));
+
+  startInfo.cb = sizeof(STARTUPINFO);
+  startInfo.dwFlags = STARTF_USESHOWWINDOW;
+  startInfo.wShowWindow = SW_SHOWNORMAL;
+
+  BOOL result =
+    CreateProcessW(aBrowserPath, static_cast<LPWSTR>(params.GetBuffer()),
+                   NULL, NULL, FALSE, 0, NULL, NULL, &startInfo, &procInfo);
+  if (!result) {
+    Log(L"CreateProcess failed! (%d)", GetLastError());
+    return;
+  }
+  // Hand off foreground/focus rights to the browser we create. If we don't
+  // do this the ceh will keep ownership causing desktop firefox to launch
+  // deactivated.
+  if (!AllowSetForegroundWindow(procInfo.dwProcessId)) {
+    Log(L"AllowSetForegroundWindow failed! (%d)", GetLastError());
+  }
+  CloseHandle(procInfo.hThread);
+  CloseHandle(procInfo.hProcess);
+  Log(L"Desktop browser process id: %d", procInfo.dwProcessId);
 }
 
 void CExecuteCommandVerb::LaunchDesktopBrowser()
 {
   CStringW browserPath;
   if (!GetDesktopBrowserPath(browserPath)) {
     return;
   }
 
-  LaunchDesktopBrowserWithParams(browserPath, mVerb, mTarget, mParameters, mTargetIsDefaultBrowser, mTargetIsBrowser);
+  LaunchDesktopBrowserWithParams(browserPath, mVerb, mTarget, mParameters,
+                                 mTargetIsDefaultBrowser, mTargetIsBrowser);
 }
 
 class AutoSetRequestMet
 {
 public:
   explicit AutoSetRequestMet(bool* aFlag) :
     mFlag(aFlag) {}
   ~AutoSetRequestMet() { if (mFlag) *mFlag = true; }