Browse Source

first pass at adding linux setAsDefaultProtocolClient

Shelley Vohr 7 years ago
parent
commit
3f73e000ee
1 changed files with 79 additions and 5 deletions
  1. 79 5
      atom/browser/browser_linux.cc

+ 79 - 5
atom/browser/browser_linux.cc

@@ -10,7 +10,11 @@
 #include "atom/browser/window_list.h"
 #include "atom/common/atom_version.h"
 #include "brightray/common/application_info.h"
+
+#if defined(USE_X11)
+#include "chrome/browser/ui/libgtkui/gtk_util.h"
 #include "chrome/browser/ui/libgtkui/unity_service.h"
+#endif
 
 namespace atom {
 
@@ -33,18 +37,88 @@ void Browser::ClearRecentDocuments() {
 void Browser::SetAppUserModelID(const base::string16& name) {
 }
 
-bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
-                                            mate::Arguments* args) {
-  return false;
-}
+const char kXdgSettings[] = "xdg-settings";
+const char kXdgSettingsDefaultBrowser[] = "default-web-browser";
+const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler";
 
+// TODO(codebytere): handle/replace GetChromeVersionOfScript
 bool Browser::SetAsDefaultProtocolClient(const std::string& protocol,
                                          mate::Arguments* args) {
-  return false;
+  #if defined(OS_CHROMEOS)
+    return true;
+  #else
+    std::unique_ptr<base::Environment> env(base::Environment::Create());
+
+    std::vector<std::string> argv;
+    argv.push_back(kXdgSettings);
+    argv.push_back("set");
+    if (protocol.empty()) {
+     argv.push_back(kXdgSettingsDefaultBrowser);
+    } else {
+     argv.push_back(kXdgSettingsDefaultSchemeHandler);
+     argv.push_back(protocol);
+    }
+    argv.push_back(libgtkui::GetDesktopName(env.get()));
+
+    int exit_code;
+    bool ran_ok = LaunchXdgUtility(argv, &exit_code);
+    if (ran_ok && exit_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) {
+     if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) {
+       ran_ok = LaunchXdgUtility(argv, &exit_code);
+     }
+    }
+
+    return ran_ok && exit_code == EXIT_SUCCESS;
+  #endif
 }
 
+// TODO(codebytere): handle/replace GetChromeVersionOfScript
 bool Browser::IsDefaultProtocolClient(const std::string& protocol,
                                       mate::Arguments* args) {
+  #if defined(OS_CHROMEOS)
+    return UNKNOWN_DEFAULT;
+  #else
+    base::ThreadRestrictions::AssertIOAllowed();
+
+    std::unique_ptr<base::Environment> env(base::Environment::Create());
+
+    std::vector<std::string> argv;
+    argv.push_back(kXdgSettings);
+    argv.push_back("check");
+    if (protocol.empty()) {
+      argv.push_back(kXdgSettingsDefaultBrowser);
+    } else {
+      argv.push_back(kXdgSettingsDefaultSchemeHandler);
+      argv.push_back(protocol);
+    }
+    argv.push_back(shell_integration_linux::GetDesktopName(env.get()));
+
+    std::string reply;
+    int success_code;
+    bool ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv),
+    &reply, &success_code);
+    if (ran_ok && success_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) {
+      if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) {
+        ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv), &reply,
+                                                &success_code);
+      }
+    }
+
+    if (!ran_ok || success_code != EXIT_SUCCESS) {
+      // xdg-settings failed: we can't determine or set the default browser.
+      return UNKNOWN_DEFAULT;
+    }
+
+    // Allow any reply that starts with "yes".
+    return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE)
+               ? IS_DEFAULT
+               : NOT_DEFAULT;
+  #endif
+}
+
+// TODO(codebytere): implement method with xdgsettings
+bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
+                                            mate::Arguments* args) {
   return false;
 }