diff --git a/include/client.hpp b/include/client.hpp index 1124cbba..bd80d0bd 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -32,6 +32,7 @@ class Client { private: Client() = default; + const std::string getStyle(const std::string &style); void bindInterfaces(); void handleOutput(struct waybar_output &output); auto setupCss(const std::string &css_file) -> void; diff --git a/include/config.hpp b/include/config.hpp index bb7b9068..25b78ab2 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -2,17 +2,26 @@ #include +#include #include +#ifndef SYSCONFDIR +#define SYSCONFDIR "/etc" +#endif + namespace waybar { class Config { public: + static const std::vector CONFIG_DIRS; + + /* Try to find any of provided names in the supported set of config directories */ + static std::optional findConfigPath( + const std::vector &names, const std::vector &dirs = CONFIG_DIRS); + Config() = default; - void load(const std::string &config, const std::string &style); - - const std::string &getStyle() { return css_file_; } + void load(const std::string &config); Json::Value &getConfig() { return config_; } @@ -24,7 +33,6 @@ class Config { void mergeConfig(Json::Value &a_config_, Json::Value &b_config_); std::string config_file_; - std::string css_file_; Json::Value config_; }; diff --git a/src/client.cpp b/src/client.cpp index 07648839..95f5a295 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -151,6 +151,15 @@ void waybar::Client::handleDeferredMonitorRemoval(Glib::RefPtr mon outputs_.remove_if([&monitor](const auto &output) { return output.monitor == monitor; }); } +const std::string waybar::Client::getStyle(const std::string &style) { + auto css_file = style.empty() ? Config::findConfigPath({"style.css"}) : style; + if (!css_file) { + throw std::runtime_error("Missing required resource files"); + } + spdlog::info("Using CSS file {}", css_file.value()); + return css_file.value(); +}; + auto waybar::Client::setupCss(const std::string &css_file) -> void { css_provider_ = Gtk::CssProvider::create(); style_context_ = Gtk::StyleContext::create(); @@ -226,8 +235,9 @@ int waybar::Client::main(int argc, char *argv[]) { throw std::runtime_error("Bar need to run under Wayland"); } wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj()); - config.load(config_opt, style_opt); - setupCss(config.getStyle()); + config.load(config_opt); + auto css_file = getStyle(style_opt); + setupCss(css_file); bindInterfaces(); gtk_app->hold(); gtk_app->run(); diff --git a/src/config.cpp b/src/config.cpp index 6c7fa179..ed7168dc 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -9,58 +9,51 @@ #include "util/json.hpp" -#ifndef SYSCONFDIR -#define SYSCONFDIR "/etc" -#endif - namespace waybar { -const std::string getValidPath(const std::vector &paths) { - wordexp_t p; +const std::vector Config::CONFIG_DIRS = { + "$XDG_CONFIG_HOME/waybar/", + "$HOME/.config/waybar/", + "$HOME/waybar/", + "/etc/xdg/waybar/", + SYSCONFDIR "/xdg/waybar/", + "./resources/", +}; - for (const std::string &path : paths) { - if (wordexp(path.c_str(), &p, 0) == 0) { - if (access(*p.we_wordv, F_OK) == 0) { - std::string result = *p.we_wordv; - wordfree(&p); - return result; - } +std::optional tryExpandPath(const std::string &path) { + wordexp_t p; + if (wordexp(path.c_str(), &p, 0) == 0) { + if (access(*p.we_wordv, F_OK) == 0) { + std::string result = *p.we_wordv; wordfree(&p); + return result; + } + wordfree(&p); + } + return std::nullopt; +} + +const std::string getValidPath(const std::vector &paths) { + for (const std::string &path : paths) { + if (auto res = tryExpandPath(path); res) { + return res.value(); } } return std::string(); } -std::tuple getConfigs(const std::string &config, - const std::string &style) { - auto config_file = config.empty() ? getValidPath({ - "$XDG_CONFIG_HOME/waybar/config", - "$XDG_CONFIG_HOME/waybar/config.jsonc", - "$HOME/.config/waybar/config", - "$HOME/.config/waybar/config.jsonc", - "$HOME/waybar/config", - "$HOME/waybar/config.jsonc", - "/etc/xdg/waybar/config", - "/etc/xdg/waybar/config.jsonc", - SYSCONFDIR "/xdg/waybar/config", - "./resources/config", - }) - : config; - auto css_file = style.empty() ? getValidPath({ - "$XDG_CONFIG_HOME/waybar/style.css", - "$HOME/.config/waybar/style.css", - "$HOME/waybar/style.css", - "/etc/xdg/waybar/style.css", - SYSCONFDIR "/xdg/waybar/style.css", - "./resources/style.css", - }) - : style; - if (css_file.empty() || config_file.empty()) { - throw std::runtime_error("Missing required resources files"); +std::optional Config::findConfigPath(const std::vector &names, + const std::vector &dirs) { + std::vector paths; + for (const auto &dir : dirs) { + for (const auto &name : names) { + if (auto res = tryExpandPath(dir + name); res) { + return res; + } + } } - spdlog::info("Resources files: {}, {}", config_file, css_file); - return {config_file, css_file}; + return std::nullopt; } void Config::setupConfig(const std::string &config_file, int depth) { @@ -143,8 +136,13 @@ bool isValidOutput(const Json::Value &config, const std::string &name, return true; } -void Config::load(const std::string &config, const std::string &style) { - std::tie(config_file_, css_file_) = getConfigs(config, style); +void Config::load(const std::string &config) { + auto file = config.empty() ? findConfigPath({"config", "config.jsonc"}) : config; + if (!file) { + throw std::runtime_error("Missing required resource files"); + } + config_file_ = file.value(); + spdlog::info("Using configuration file {}", config_file_); setupConfig(config_file_, 0); }