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>
40const char* ENV_PREFIX =
"APPIMAGE_PRESERVED_";
42bool IsPreservedEnvVar(
const char* var)
44 return strncmp(var, ENV_PREFIX, strlen(ENV_PREFIX)) == 0;
49 for(
auto envIterator = environ; *envIterator; ++envIterator)
51 auto envVar = *envIterator;
53 if (!IsPreservedEnvVar(envVar))
56 auto separator = strchr(envVar,
'=');
62 auto varName = std::string(envVar + strlen(ENV_PREFIX), separator);
67 auto varValue = separator + 1;
69 const auto result = *varValue ?
70 setenv(varName.c_str(), varValue,
true) :
71 unsetenv(varName.c_str());
80std::string FindXDGOpen()
82 const char *path = getenv(
"PATH");
90 const char *colon = strchr(path,
':');
92 colon = path + strlen(path);
94 result.assign(path, colon);
95 result +=
"/xdg-open";
97 if (access(result.c_str(), X_OK) == 0)
109bool RunXDGOpen(
const std::string& uri)
111 std::string xdgOpen = FindXDGOpen();
125 int secondFork = fork();
133 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
135 for (
int fd = STDERR_FILENO + 1; fd < rlim.rlim_cur; ++fd)
140 int fd = open(
"/dev/null", O_RDWR);
144 dup2(fd, STDIN_FILENO);
145 dup2(fd, STDOUT_FILENO);
146 dup2(fd, STDERR_FILENO);
148 if (fd > STDERR_FILENO)
155 char*
const args[] = {
156 const_cast<char*
>(xdgOpen.c_str()),
157 const_cast<char*
>(uri.c_str()),
161 execv(xdgOpen.c_str(), args);
175 waitpid(pid, &status, 0);
177 return WIFEXITED(status) && WEXITSTATUS(status) == 0;
191WindowPlacement::operator bool()
const {
return false; }
216 p->DoCallAfter(action);
220 sActions.emplace_back(std::move(action));
230 std::vector<Action> actions;
232 for (
auto &action : actions)
247#if HAS_XDG_OPEN_HELPER
248 if (RunXDGOpen(url.ToStdString()))
253 return p->DoOpenInDefaultBrowser(url);
260 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.