Use xdg-open if present, instead of guessing firefox.

This commit is contained in:
King_DuckZ 2020-03-21 18:53:52 +01:00
parent 91524c7f46
commit 60aaa5eb92
3 changed files with 103 additions and 21 deletions

View File

@ -18,6 +18,7 @@
#include <windows.h> #include <windows.h>
#include "../detail/mswin/platform_spec.hpp" #include "../detail/mswin/platform_spec.hpp"
#elif defined(NANA_POSIX) #elif defined(NANA_POSIX)
#include "split_string.hpp"
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/syscall.h> #include <sys/syscall.h>
@ -25,37 +26,45 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <spawn.h> #include <spawn.h>
#include <cstring> #include <cstring>
#include <memory>
static void posix_open_url(const char *url_utf8) static void posix_open_url(const char *url_utf8)
{ {
using nana::system::split_string_type;
using nana::system::split_string;
extern char **environ; extern char **environ;
const char *home = getenv("HOME");
std::string cheat(home);
cheat += "/.mozilla";
struct stat exists; struct stat exists;
const split_string_type path = getenv("PATH");
// TODO: generalize this for chromium, opera, waterfox, etc. //see https://stackoverflow.com/questions/5116473/linux-command-to-open-url-in-default-browser
// Most desktop environments (KDE, Gnome, Lumina etc.) provide a way to set
// your preferred browser - but there are more desktops than browsers. 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; pid_t pid = 0;
static const char firefox[] = "firefox";
char name[sizeof firefox]{};
// argv does not like const-literals so make a copy. // argv does not like const-literals so make a copy.
std::strcpy(name, firefox); const auto url_utf8_len = std::strlen(url_utf8);
char *argv[3] = {name, const_cast<char *>(url_utf8), nullptr}; auto string_cpy_buff = std::make_unique<char[]>(full_path.size() + 1 + url_utf8_len + 1);
posix_spawn(&pid, path, NULL, NULL, argv, environ); 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 #endif

View File

@ -0,0 +1,32 @@
#include "split_string.hpp"
#include <string>
#include <algorithm>
#include <cstddef>
namespace nana
{
namespace system {
std::vector<split_string_type> split_string (const split_string_type& text, char sep)
{
std::vector<split_string_type> 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;
}
}
}

View File

@ -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 <nana/config.hpp>
#include <vector>
#ifdef _nana_std_has_string_view
# include <string_view>
#else
# include <string>
#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_type> split_string (const split_string_type& text, char sep);
}
}
#endif