diff --git a/src/browser/client.cxx b/src/browser/client.cxx index 4172f90..d685078 100644 --- a/src/browser/client.cxx +++ b/src/browser/client.cxx @@ -104,7 +104,7 @@ _InternalFile allocate_file(const char* filename, CefString mime_type) { } } -Browser::Client::Client(CefRefPtr app): show_devtools(true) { +Browser::Client::Client(CefRefPtr app, std::filesystem::path config_dir): show_devtools(true), config_dir(config_dir) { CefString mime_type_html = "text/html"; CefString mime_type_js = "application/javascript"; app->SetBrowserProcessHandler(this); diff --git a/src/browser/client.hxx b/src/browser/client.hxx index 40ae116..9172d1a 100644 --- a/src/browser/client.hxx +++ b/src/browser/client.hxx @@ -6,6 +6,7 @@ #include "app.hxx" #include "../browser.hxx" +#include #include #include #include @@ -25,7 +26,7 @@ namespace Browser { /// https://github.com/chromiumembedded/cef/blob/5735/include/cef_life_span_handler.h /// https://github.com/chromiumembedded/cef/blob/5735/include/cef_request_handler.h struct Client: public CefClient, CefBrowserProcessHandler, CefLifeSpanHandler, CefRequestHandler { - Client(CefRefPtr); + Client(CefRefPtr, std::filesystem::path); /* CefClient overrides */ CefRefPtr GetLifeSpanHandler() override; @@ -75,6 +76,7 @@ namespace Browser { CefRefCount ref_count; bool show_devtools; + std::filesystem::path config_dir; std::string internal_url = "https://bolt-internal/"; std::map internal_pages; diff --git a/src/main.cxx b/src/main.cxx index ef74e58..7d5e397 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -8,6 +8,12 @@ #include #endif +#if defined(__linux__) +#include +#include +#include +#endif + #if defined(CEF_X11) #include @@ -29,6 +35,7 @@ int XIOErrorHandlerImpl(Display* display) { #endif int BoltRunBrowserProcess(CefMainArgs, CefRefPtr); +bool LockConfigDirectory(std::filesystem::path&); int BoltRunAnyProcess(CefMainArgs main_args) { // CefApp struct - this implements handlers used by multiple processes @@ -52,8 +59,14 @@ int BoltRunBrowserProcess(CefMainArgs main_args, CefRefPtr cef_app XSetIOErrorHandler(XIOErrorHandlerImpl); #endif + // find home directory + std::filesystem::path config_dir; + if (!LockConfigDirectory(config_dir)) { + return 1; + } + // CefClient struct - central object for main thread, and implements lots of handlers for browser process - Browser::Client client_(cef_app); + Browser::Client client_(cef_app, config_dir); CefRefPtr client = &client_; // CEF settings - only set the ones we're interested in @@ -97,6 +110,37 @@ int main(int argc, char* argv[]) { delete[] arg_; return ret; } + +bool LockConfigDirectory(std::filesystem::path& path) { + const char* xdg_config_home = getenv("XDG_CONFIG_HOME"); + const char* home = getenv("HOME"); + if (xdg_config_home) { + path.assign(xdg_config_home); + } else if (home) { + path.assign(home); + path.append(".config"); + } else { + fmt::print("No $XDG_CONFIG_HOME or $HOME\n"); + return false; + } + path.append("bolt-launcher"); + std::error_code err; + std::filesystem::create_directories(path, err); + if (err.value() != 0) { + fmt::print("Could not create directories (error {}) {}\n", err.value(), path.c_str()); + return false; + } + + std::filesystem::path fpath = path; + fpath.append("lock"); + int lockfile = open(fpath.c_str(), O_WRONLY | O_CREAT, 0666); + if (flock(lockfile, LOCK_EX | LOCK_NB)) { + fmt::print("Failed to obtain lockfile; is the program already running?\n"); + return false; + } else { + return true; + } +} #endif #if defined(_WIN32)