From 91524c7f466c7832fcf6dd3032228db6c1e23729 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 21 Mar 2020 17:55:09 +0100 Subject: [PATCH 1/2] Remove unneeded includes, prefer cstring over string.h --- source/system/platform.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/system/platform.cpp b/source/system/platform.cpp index d8832c68..7373f561 100644 --- a/source/system/platform.cpp +++ b/source/system/platform.cpp @@ -18,15 +18,13 @@ #include #include "../detail/mswin/platform_spec.hpp" #elif defined(NANA_POSIX) - #include - #include #include #include #include #include #include #include - #include + #include static void posix_open_url(const char *url_utf8) { @@ -55,7 +53,7 @@ static void posix_open_url(const char *url_utf8) static const char firefox[] = "firefox"; char name[sizeof firefox]{}; // argv does not like const-literals so make a copy. - strcpy(name, firefox); + std::strcpy(name, firefox); char *argv[3] = {name, const_cast(url_utf8), nullptr}; posix_spawn(&pid, path, NULL, NULL, argv, environ); } From 60aaa5eb92662bff16a69fd803d57655d42999dc Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 21 Mar 2020 18:53:52 +0100 Subject: [PATCH 2/2] Use xdg-open if present, instead of guessing firefox. --- source/system/platform.cpp | 51 ++++++++++++++++++++-------------- source/system/split_string.cpp | 32 +++++++++++++++++++++ source/system/split_string.hpp | 41 +++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 21 deletions(-) create mode 100644 source/system/split_string.cpp create mode 100644 source/system/split_string.hpp diff --git a/source/system/platform.cpp b/source/system/platform.cpp index 7373f561..83e803a0 100644 --- a/source/system/platform.cpp +++ b/source/system/platform.cpp @@ -18,6 +18,7 @@ #include #include "../detail/mswin/platform_spec.hpp" #elif defined(NANA_POSIX) + #include "split_string.hpp" #include #include #include @@ -25,37 +26,45 @@ #include #include #include + #include static void posix_open_url(const char *url_utf8) { + using nana::system::split_string_type; + using nana::system::split_string; + extern char **environ; - const char *home = getenv("HOME"); - std::string cheat(home); - cheat += "/.mozilla"; struct stat exists; + const split_string_type path = getenv("PATH"); - // TODO: generalize this for chromium, opera, waterfox, etc. - // Most desktop environments (KDE, Gnome, Lumina etc.) provide a way to set - // your preferred browser - but there are more desktops than browsers. + //see https://stackoverflow.com/questions/5116473/linux-command-to-open-url-in-default-browser + + std::string full_path; + for (const auto& cur_path : split_string(path, ':')) { + full_path = cur_path; + full_path += "/xdg-open"; + if ( stat(full_path.c_str(), &exists) == 0 && S_ISREG(exists.st_mode)) + break; + else + full_path.clear(); + } + if (full_path.empty()) { + //xdg-open not found sorry :( maybe print a message so users know? + return; + } - // Look for $HOME/.mozilla directory as strong evidence they use firefox. - if ( stat(cheat.c_str(), &exists) == 0 && S_ISDIR(exists.st_mode)) { - const char *path = ""; - static const char *likely[2] = { "/usr/local/bin/firefox", "/usr/bin/firefox"}; - if ( stat(likely[0], &exists) == 0 && S_ISREG(exists.st_mode)) - path = likely[0]; - else if ( stat(likely[1], &exists) == 0 && S_ISREG(exists.st_mode) ) - path = likely[1]; - else return; - pid_t pid = 0; - static const char firefox[] = "firefox"; - char name[sizeof firefox]{}; // argv does not like const-literals so make a copy. - std::strcpy(name, firefox); - char *argv[3] = {name, const_cast(url_utf8), nullptr}; - posix_spawn(&pid, path, NULL, NULL, argv, environ); + const auto url_utf8_len = std::strlen(url_utf8); + auto string_cpy_buff = std::make_unique(full_path.size() + 1 + url_utf8_len + 1); + char* const url_utf8_cpy = string_cpy_buff.get(); + char* const full_path_cpy = string_cpy_buff.get() + url_utf8_len + 1; + std::strncpy(url_utf8_cpy, url_utf8, url_utf8_len + 1); + std::strncpy(full_path_cpy, full_path.c_str(), full_path.size() + 1); + char *argv[3] = {full_path_cpy, url_utf8_cpy, nullptr}; + //system((full_path + " " + url_utf8).c_str()); + posix_spawn(&pid, full_path_cpy, nullptr, nullptr, argv, environ); } } #endif diff --git a/source/system/split_string.cpp b/source/system/split_string.cpp new file mode 100644 index 00000000..8269db6d --- /dev/null +++ b/source/system/split_string.cpp @@ -0,0 +1,32 @@ +#include "split_string.hpp" +#include +#include +#include + +namespace nana +{ +namespace system { +std::vector split_string (const split_string_type& text, char sep) +{ + std::vector retval; + const auto estimated_size = std::count(text.begin(), text.end(), sep) + 1; + retval.reserve(estimated_size); + + std::size_t sep_pos = 0; + while (sep_pos != text.size()) { + const std::size_t start = sep_pos; + sep_pos = text.find(sep, sep_pos); + sep_pos = (text.npos == sep_pos ? text.size() : sep_pos); + const std::size_t end = sep_pos; + while (sep_pos < text.size() and sep == text[sep_pos]) { + ++sep_pos; + } + + retval.push_back(text.substr(start, end - start)); + } + + return retval; +} + +} +} diff --git a/source/system/split_string.hpp b/source/system/split_string.hpp new file mode 100644 index 00000000..1512ef41 --- /dev/null +++ b/source/system/split_string.hpp @@ -0,0 +1,41 @@ +/* + * The Deploy Implementation + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file: nana/system/split_string.hpp + * + * What follows is dependent on what defined in nana/config.hpp + */ + +#ifndef NANA_SYSTEM_SPLITSTRING_HPP +#define NANA_SYSTEM_SPLITSTRING_HPP + +#include +#include +#ifdef _nana_std_has_string_view +# include +#else +# include +#endif + +namespace nana +{ +namespace system +{ +#ifdef _nana_std_has_string_view +typedef std::string_view split_string_type; +#else +typedef std::string split_string_type; +#endif + +std::vector split_string (const split_string_type& text, char sep); + +} +} + +#endif