From 3f73e000eebd06096de6af83a740cbb09338e57e Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Mon, 2 Oct 2017 10:21:30 -0400 Subject: [PATCH 1/8] first pass at adding linux setAsDefaultProtocolClient --- atom/browser/browser_linux.cc | 84 ++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index f569040a2189..a1d32df137b4 100644 --- a/atom/browser/browser_linux.cc +++ b/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 env(base::Environment::Create()); + + std::vector 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 env(base::Environment::Create()); + + std::vector 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; } From 6131a523dc68f0721295047b5e7078a931d0d7c4 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Tue, 3 Oct 2017 11:10:38 -0400 Subject: [PATCH 2/8] add xdg helper method --- atom/browser/browser_linux.cc | 91 +++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index a1d32df137b4..dbde042fc0e3 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -41,40 +41,15 @@ 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) { - #if defined(OS_CHROMEOS) - return true; - #else - std::unique_ptr env(base::Environment::Create()); - - std::vector 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 + return SetDefaultWebClient(protocol); } // TODO(codebytere): handle/replace GetChromeVersionOfScript -bool Browser::IsDefaultProtocolClient(const std::string& protocol, - mate::Arguments* args) { +// https://portland.freedesktop.org/doc/xdg-settings.html +// https://cs.chromium.org/chromium/src/chrome/browser/shell_integration_linux.cc?sq=package:chromium&l=78 +bool Browser::IsDefaultProtocolClient(const std::string& protocol) { #if defined(OS_CHROMEOS) return UNKNOWN_DEFAULT; #else @@ -91,28 +66,19 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol, argv.push_back(kXdgSettingsDefaultSchemeHandler); argv.push_back(protocol); } - argv.push_back(shell_integration_linux::GetDesktopName(env.get())); + argv.push_back(libgtkui::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; - } + if (!ran_ok || success_code != EXIT_SUCCESS) return false; // Allow any reply that starts with "yes". return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE) - ? IS_DEFAULT - : NOT_DEFAULT; + ? true + : false; #endif } @@ -152,4 +118,45 @@ bool Browser::IsUnityRunning() { return unity::IsRunning(); } +/* Helper Functions */ + +bool LaunchXdgUtility(const std::vector& argv, int* exit_code) { + *exit_code = EXIT_FAILURE; + int devnull = open("/dev/null", O_RDONLY); + if (devnull < 0) + return false; + + base::LaunchOptions options; + options.fds_to_remap.push_back(std::make_pair(devnull, STDIN_FILENO)); + base::Process process = base::LaunchProcess(argv, options); + close(devnull); + if (!process.IsValid()) + return false; + return process.WaitForExit(exit_code); +} + +bool SetDefaultWebClient(const std::string& protocol) { +#if defined(OS_CHROMEOS) + return true; +#else + std::unique_ptr env(base::Environment::Create()); + + std::vector 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); + + return ran_ok && exit_code == EXIT_SUCCESS; +#endif +} + } // namespace atom From f8f21815eb2c465fd2dc02841436001b9fc36c37 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 5 Oct 2017 00:30:14 -0400 Subject: [PATCH 3/8] syntax updates and pointer conversion --- atom/browser/browser_linux.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index dbde042fc0e3..7a88a6620824 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -5,10 +5,14 @@ #include "atom/browser/browser.h" #include +#include #include "atom/browser/native_window.h" #include "atom/browser/window_list.h" #include "atom/common/atom_version.h" +#include "base/environment.h" +#include "base/command_line.h" +#include "base/process/launch.h" #include "brightray/common/application_info.h" #if defined(USE_X11) @@ -18,6 +22,8 @@ namespace atom { +bool SetDefaultWebClient(const std::string& protocol); + void Browser::Focus() { // Focus on the first visible window. for (const auto& window : WindowList::GetWindows()) { @@ -49,7 +55,8 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, // TODO(codebytere): handle/replace GetChromeVersionOfScript // https://portland.freedesktop.org/doc/xdg-settings.html // https://cs.chromium.org/chromium/src/chrome/browser/shell_integration_linux.cc?sq=package:chromium&l=78 -bool Browser::IsDefaultProtocolClient(const std::string& protocol) { +bool Browser::IsDefaultProtocolClient(const std::string& protocol, + mate::Arguments* args) { #if defined(OS_CHROMEOS) return UNKNOWN_DEFAULT; #else @@ -127,7 +134,8 @@ bool LaunchXdgUtility(const std::vector& argv, int* exit_code) { return false; base::LaunchOptions options; - options.fds_to_remap.push_back(std::make_pair(devnull, STDIN_FILENO)); + base::FileHandleMappingVector remap = *(options.fds_to_remap); + remap.push_back(std::make_pair(devnull, STDIN_FILENO)); base::Process process = base::LaunchProcess(argv, options); close(devnull); if (!process.IsValid()) From c9da806c84b614a92559e1f6d0ff2f4d6a6ff5b9 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Fri, 6 Oct 2017 23:32:46 -0400 Subject: [PATCH 4/8] slight refactor and lin cleanup --- atom/browser/browser_linux.cc | 102 +++++++++++++++------------------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index 7a88a6620824..7457b8c792fc 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -4,14 +4,14 @@ #include "atom/browser/browser.h" -#include #include +#include #include "atom/browser/native_window.h" #include "atom/browser/window_list.h" #include "atom/common/atom_version.h" -#include "base/environment.h" #include "base/command_line.h" +#include "base/environment.h" #include "base/process/launch.h" #include "brightray/common/application_info.h" @@ -22,7 +22,48 @@ namespace atom { -bool SetDefaultWebClient(const std::string& protocol); +const char kXdgSettings[] = "xdg-settings"; +const char kXdgSettingsDefaultBrowser[] = "default-web-browser"; +const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler"; + +bool LaunchXdgUtility(const std::vector& argv, int* exit_code) { + *exit_code = EXIT_FAILURE; + int devnull = open("/dev/null", O_RDONLY); + if (devnull < 0) return false; + + base::LaunchOptions options; + + base::FileHandleMappingVector remap; + remap.push_back(std::make_pair(devnull, STDIN_FILENO)); + options.fds_to_remap = &remap; + + base::Process process = base::LaunchProcess(argv, options); + close(devnull); + + if (!process.IsValid())return false; + return process.WaitForExit(exit_code); +} + +bool SetDefaultWebClient(const std::string& protocol) { +#if defined(OS_CHROMEOS) + return true; +#else + std::unique_ptr env(base::Environment::Create()); + + std::vector argv; + argv.push_back(kXdgSettings); + argv.push_back("set"); + if (!protocol.empty()) { + 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); + return ran_ok && exit_code == EXIT_SUCCESS; +#endif +} void Browser::Focus() { // Focus on the first visible window. @@ -43,18 +84,11 @@ void Browser::ClearRecentDocuments() { void Browser::SetAppUserModelID(const base::string16& name) { } -const char kXdgSettings[] = "xdg-settings"; -const char kXdgSettingsDefaultBrowser[] = "default-web-browser"; -const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler"; - bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { return SetDefaultWebClient(protocol); } -// TODO(codebytere): handle/replace GetChromeVersionOfScript -// https://portland.freedesktop.org/doc/xdg-settings.html -// https://cs.chromium.org/chromium/src/chrome/browser/shell_integration_linux.cc?sq=package:chromium&l=78 bool Browser::IsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { #if defined(OS_CHROMEOS) @@ -67,9 +101,7 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol, std::vector argv; argv.push_back(kXdgSettings); argv.push_back("check"); - if (protocol.empty()) { - argv.push_back(kXdgSettingsDefaultBrowser); - } else { + if (!protocol.empty()) { argv.push_back(kXdgSettingsDefaultSchemeHandler); argv.push_back(protocol); } @@ -89,7 +121,7 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol, #endif } -// TODO(codebytere): implement method with xdgsettings +// Todo implement bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { return false; @@ -125,46 +157,4 @@ bool Browser::IsUnityRunning() { return unity::IsRunning(); } -/* Helper Functions */ - -bool LaunchXdgUtility(const std::vector& argv, int* exit_code) { - *exit_code = EXIT_FAILURE; - int devnull = open("/dev/null", O_RDONLY); - if (devnull < 0) - return false; - - base::LaunchOptions options; - base::FileHandleMappingVector remap = *(options.fds_to_remap); - remap.push_back(std::make_pair(devnull, STDIN_FILENO)); - base::Process process = base::LaunchProcess(argv, options); - close(devnull); - if (!process.IsValid()) - return false; - return process.WaitForExit(exit_code); -} - -bool SetDefaultWebClient(const std::string& protocol) { -#if defined(OS_CHROMEOS) - return true; -#else - std::unique_ptr env(base::Environment::Create()); - - std::vector 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); - - return ran_ok && exit_code == EXIT_SUCCESS; -#endif -} - } // namespace atom From a1347f67a13cd51cf6e00453156541274dc5c894 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Fri, 6 Oct 2017 23:40:58 -0400 Subject: [PATCH 5/8] remove a space from a comment wow thanks linter --- atom/browser/browser_linux.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index 7457b8c792fc..5dd57bacf1f5 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -121,7 +121,7 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol, #endif } -// Todo implement +// Todo implement bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { return false; From 66827755e7edac3f69d12da7c7c88b75257a3b42 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Sat, 7 Oct 2017 00:36:18 -0400 Subject: [PATCH 6/8] remove chrome check and change protocol handler --- atom/browser/browser_linux.cc | 49 ++++++++++++++--------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index 5dd57bacf1f5..9e2b41194eea 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -40,14 +40,11 @@ bool LaunchXdgUtility(const std::vector& argv, int* exit_code) { base::Process process = base::LaunchProcess(argv, options); close(devnull); - if (!process.IsValid())return false; + if (!process.IsValid()) return false; return process.WaitForExit(exit_code); } bool SetDefaultWebClient(const std::string& protocol) { -#if defined(OS_CHROMEOS) - return true; -#else std::unique_ptr env(base::Environment::Create()); std::vector argv; @@ -62,7 +59,6 @@ bool SetDefaultWebClient(const std::string& protocol) { int exit_code; bool ran_ok = LaunchXdgUtility(argv, &exit_code); return ran_ok && exit_code == EXIT_SUCCESS; -#endif } void Browser::Focus() { @@ -90,35 +86,30 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, } bool Browser::IsDefaultProtocolClient(const std::string& protocol, - mate::Arguments* args) { - #if defined(OS_CHROMEOS) - return UNKNOWN_DEFAULT; - #else - base::ThreadRestrictions::AssertIOAllowed(); + mate::Arguments* args) { + base::ThreadRestrictions::AssertIOAllowed(); + std::unique_ptr env(base::Environment::Create()); - std::unique_ptr env(base::Environment::Create()); + if (protocol.empty()) return false; - std::vector argv; - argv.push_back(kXdgSettings); - argv.push_back("check"); - if (!protocol.empty()) { - argv.push_back(kXdgSettingsDefaultSchemeHandler); - argv.push_back(protocol); - } - argv.push_back(libgtkui::GetDesktopName(env.get())); + std::vector argv; + argv.push_back(kXdgSettings); + argv.push_back("check"); + argv.push_back(kXdgSettingsDefaultSchemeHandler); + argv.push_back(protocol); + argv.push_back(libgtkui::GetDesktopName(env.get())); - std::string reply; - int success_code; - bool ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv), - &reply, &success_code); + std::string reply; + int success_code; + bool ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv), + &reply, &success_code); - if (!ran_ok || success_code != EXIT_SUCCESS) return false; + if (!ran_ok || success_code != EXIT_SUCCESS) return false; - // Allow any reply that starts with "yes". - return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE) - ? true - : false; - #endif + // Allow any reply that starts with "yes". + return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE) + ? true + : false; } // Todo implement From 35eea8bea59607e1e7edf5b76c58de955f10f6bf Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Sat, 7 Oct 2017 00:38:25 -0400 Subject: [PATCH 7/8] remove unused xdg setting --- atom/browser/browser_linux.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index 9e2b41194eea..dce5e733462b 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -23,7 +23,6 @@ namespace atom { const char kXdgSettings[] = "xdg-settings"; -const char kXdgSettingsDefaultBrowser[] = "default-web-browser"; const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler"; bool LaunchXdgUtility(const std::vector& argv, int* exit_code) { From 443c30890b6dadf6b608e6124dcdd495c79e2b83 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Sat, 7 Oct 2017 10:38:08 -0400 Subject: [PATCH 8/8] remove dummy check --- atom/browser/browser_linux.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index dce5e733462b..280d2defb6b9 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -86,7 +86,6 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, bool Browser::IsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { - base::ThreadRestrictions::AssertIOAllowed(); std::unique_ptr env(base::Environment::Create()); if (protocol.empty()) return false;