15#define HAS_XDG_OPEN_HELPER (defined(__linux__) && !defined __ANDROID__) || defined (__FreeBSD__) || defined (__NetBSD__) || defined(__OpenBSD__)
17#if HAS_XDG_OPEN_HELPER
21#include <sys/resource.h>
35const char* ENV_PREFIX =
"APPIMAGE_PRESERVED_";
37bool IsPreservedEnvVar(
const char* var)
39 return strncmp(var, ENV_PREFIX, strlen(ENV_PREFIX)) == 0;
44 for(
auto envIterator = environ; *envIterator; ++envIterator)
46 auto envVar = *envIterator;
48 if (!IsPreservedEnvVar(envVar))
51 auto separator = strchr(envVar,
'=');
57 auto varName = std::string(envVar + strlen(ENV_PREFIX), separator);
62 auto varValue = separator + 1;
64 const auto result = *varValue ?
65 setenv(varName.c_str(), varValue,
true) :
66 unsetenv(varName.c_str());
75std::string FindXDGOpen()
77 const char *path = getenv(
"PATH");
85 const char *colon = strchr(path,
':');
87 colon = path + strlen(path);
89 result.assign(path, colon);
90 result +=
"/xdg-open";
92 if (access(result.c_str(), X_OK) == 0)
104bool RunXDGOpen(
const std::string& uri)
106 std::string xdgOpen = FindXDGOpen();
120 int secondFork = fork();
128 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
130 for (
int fd = STDERR_FILENO + 1; fd < rlim.rlim_cur; ++fd)
135 int fd = open(
"/dev/null", O_RDWR);
139 dup2(fd, STDIN_FILENO);
140 dup2(fd, STDOUT_FILENO);
141 dup2(fd, STDERR_FILENO);
143 if (fd > STDERR_FILENO)
150 char*
const args[] = {
151 const_cast<char*
>(xdgOpen.c_str()),
152 const_cast<char*
>(uri.c_str()),
156 execv(xdgOpen.c_str(), args);
170 waitpid(pid, &status, 0);
172 return WIFEXITED(status) && WEXITSTATUS(status) == 0;
186WindowPlacement::operator bool()
const {
return false; }
211 p->DoCallAfter(action);
215 sActions.emplace_back(std::move(action));
225 std::vector<Action> actions;
227 for (
auto &action : actions)
242#if HAS_XDG_OPEN_HELPER
243 if (RunXDGOpen(url.ToStdString()))
248 return p->DoOpenInDefaultBrowser(url);
255 return XO(
"Message");
Toolkit-neutral facade for basic user interface services.
virtual ~GenericProgressDialog()
virtual ~ProgressDialog()
Abstract class defines a few user interface services, not mentioning particular toolkits.
virtual ~WindowPlacement()
Holds a msgid for the translation catalog; may also bind format arguments.
static Services * theInstance
TranslatableString DefaultCaption()
"Message", suitably translated
bool OpenInDefaultBrowser(const wxString &url)
Open an URL in default browser.
Services * Install(Services *pInstance)
Install an implementation; return the previously installed instance.
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
static std::vector< Action > sActions
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
std::function< void()> Action
static std::recursive_mutex sActionsMutex
void Yield()
Dispatch waiting events, including actions enqueued by CallAfter.