Bug 1167294 - Launch the modern Settings app when setting the default browser on Windows 10. r=jimm, r=Gijs, a=sledru
authorJared Wein <jwein@mozilla.com>
Wed, 03 Jun 2015 13:42:26 -0400
changeset 274991 69dd71505f74d8738d870e50986ffb92524d168a
parent 274990 e33bb7d234df9ead02584173badc21b8b722fbdd
child 274992 afe619271392062bfe8f6ad4d331810770021e29
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, Gijs, sledru
bugs1167294
milestone40.0a2
Bug 1167294 - Launch the modern Settings app when setting the default browser on Windows 10. r=jimm, r=Gijs, a=sledru
browser/components/nsBrowserGlue.js
browser/components/preferences/in-content/main.js
browser/components/shell/nsWindowsShellService.cpp
browser/components/shell/nsWindowsShellService.h
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2671,19 +2671,19 @@ let DefaultBrowserCheck = {
       this._notification.close();
     }
   },
 
   setAsDefault: function() {
     let claimAllTypes = true;
 #ifdef XP_WIN
     try {
-      // In Windows 8, the UI for selecting default protocol is much
+      // In Windows 8+, the UI for selecting default protocol is much
       // nicer than the UI for setting file type associations. So we
-      // only show the protocol association screen on Windows 8.
+      // only show the protocol association screen on Windows 8+.
       // Windows 8 is version 6.2.
       let version = Services.sysinfo.getProperty("version");
       claimAllTypes = (parseFloat(version) < 6.2);
     } catch (ex) { }
 #endif
     try {
       ShellService.setDefaultBrowser(claimAllTypes, false);
     } catch (ex) {
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -705,17 +705,26 @@ var gMainPane = {
    * Set browser as the operating system default browser.
    */
   setDefaultBrowser: function()
   {
     let shellSvc = getShellService();
     if (!shellSvc)
       return;
     try {
-      shellSvc.setDefaultBrowser(true, false);
+      let claimAllTypes = true;
+      if (AppConstants.platform == "win") {
+        // In Windows 8+, the UI for selecting default protocol is much
+        // nicer than the UI for setting file type associations. So we
+        // only show the protocol association screen on Windows 8+.
+        // Windows 8 is version 6.2.
+        let version = Services.sysinfo.getProperty("version");
+        claimAllTypes = (parseFloat(version) < 6.2);
+      }
+      shellSvc.setDefaultBrowser(claimAllTypes, false);
     } catch (ex) {
       Cu.reportError(ex);
       return;
     }
     let selectedIndex =
       shellSvc.isDefaultBrowser(false, true) ? 1 : 0;
     document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
   }
--- a/browser/components/shell/nsWindowsShellService.cpp
+++ b/browser/components/shell/nsWindowsShellService.cpp
@@ -34,16 +34,19 @@
 #include "windows.h"
 #include "shellapi.h"
 
 #ifdef _WIN32_WINNT
 #undef _WIN32_WINNT
 #endif
 #define _WIN32_WINNT 0x0600
 #define INITGUID
+#undef NTDDI_VERSION
+#define NTDDI_VERSION NTDDI_WIN8
+// Needed for access to IApplicationActivationManager
 #include <shlobj.h>
 
 #include <mbstring.h>
 #include <shlwapi.h>
 
 #ifndef MAX_BUF
 #define MAX_BUF 4096
 #endif
@@ -658,16 +661,38 @@ nsWindowsShellService::LaunchControlPane
   }
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
 
   return NS_OK;
 }
 
 nsresult
+nsWindowsShellService::LaunchModernSettingsDialogDefaultApps()
+{
+  IApplicationActivationManager* pActivator;
+  HRESULT hr = CoCreateInstance(CLSID_ApplicationActivationManager,
+                                nullptr,
+                                CLSCTX_INPROC,
+                                IID_IApplicationActivationManager,
+                                (void**)&pActivator);
+
+  if (SUCCEEDED(hr)) {
+    DWORD pid;
+    hr = pActivator->ActivateApplication(
+           L"windows.immersivecontrolpanel_cw5n1h2txyewy"
+           L"!microsoft.windows.immersivecontrolpanel",
+           L"page=SettingsPageAppsDefaults", AO_NONE, &pid);
+    pActivator->Release();
+    return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
+
+nsresult
 nsWindowsShellService::LaunchHTTPHandlerPane()
 {
   OPENASINFO info;
   info.pcszFile = L"http";
   info.pcszClass = nullptr;
   info.oaifInFlags = OAIF_FORCE_REGISTRATION | 
                      OAIF_URL_PROTOCOL |
                      OAIF_REGISTER_EXT;
@@ -692,19 +717,27 @@ nsWindowsShellService::SetDefaultBrowser
     if (aClaimAllTypes) {
       rv = LaunchControlPanelDefaultPrograms();
       // The above call should never really fail, but just in case
       // fall back to showing the HTTP association screen only.
       if (NS_FAILED(rv)) {
         rv = LaunchHTTPHandlerPane();
       }
     } else {
-      rv = LaunchHTTPHandlerPane();
-      // The above calls hould never really fail, but just in case
-      // fallb ack to showing control panel for all defaults
+      // Windows 10 blocks attempts to load the HTTP Handler
+      // association dialog, so the modern Settings dialog
+      // is opened with the Default Apps view loaded.
+      if (IsWin10OrLater()) {
+        rv = LaunchModernSettingsDialogDefaultApps();
+      } else {
+        rv = LaunchHTTPHandlerPane();
+      }
+
+      // The above call should never really fail, but just in case
+      // fall back to showing control panel for all defaults
       if (NS_FAILED(rv)) {
         rv = LaunchControlPanelDefaultPrograms();
       }
     }
   }
 
   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefs) {
--- a/browser/components/shell/nsWindowsShellService.h
+++ b/browser/components/shell/nsWindowsShellService.h
@@ -23,15 +23,16 @@ public:
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHELLSERVICE
   NS_DECL_NSIWINDOWSSHELLSERVICE
 
 protected:
   bool IsDefaultBrowserVista(bool aCheckAllTypes, bool* aIsDefaultBrowser);
   nsresult LaunchControlPanelDefaultPrograms();
+  nsresult LaunchModernSettingsDialogDefaultApps();
   nsresult LaunchHTTPHandlerPane();
 
 private:
   bool      mCheckedThisSession;
 };
 
 #endif // nswindowsshellservice_h____