From 14f626d422a77b51bca4bbbe5282ee6e995169e0 Mon Sep 17 00:00:00 2001 From: Oskar Carl Date: Sun, 24 Jan 2021 17:36:30 +0100 Subject: [PATCH 1/4] Add recursive config includes --- include/client.hpp | 1 + src/client.cpp | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/client.hpp b/include/client.hpp index ec3866ad..af6eeef7 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -39,6 +39,7 @@ class Client { void handleOutput(struct waybar_output &output); bool isValidOutput(const Json::Value &config, struct waybar_output &output); auto setupConfig(const std::string &config_file) -> void; + auto mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void; auto setupCss(const std::string &css_file) -> void; struct waybar_output & getOutput(void *); std::vector getOutputConfigs(struct waybar_output &output); diff --git a/src/client.cpp b/src/client.cpp index ced9e492..752574df 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -241,7 +241,24 @@ auto waybar::Client::setupConfig(const std::string &config_file) -> void { } std::string str((std::istreambuf_iterator(file)), std::istreambuf_iterator()); util::JsonParser parser; - config_ = parser.parse(str); + Json::Value tmp_config_ = parser.parse(str); + if (tmp_config_["include"].isArray()) { + for (const auto& include : tmp_config_["include"]) { + spdlog::info("Including resource file: {}", include.asString()); + setupConfig(getValidPath({include.asString()})); + } + } + mergeConfig(config_, tmp_config_); +} + +auto waybar::Client::mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void { + for (const auto& key : b_config_.getMemberNames()) { + if (a_config_[key].type() == Json::objectValue && b_config_[key].type() == Json::objectValue) { + mergeConfig(a_config_[key], b_config_[key]); + } else { + a_config_[key] = b_config_[key]; + } + } } auto waybar::Client::setupCss(const std::string &css_file) -> void { From e8278431d281e6bfa2cae15c6874963711a1396b Mon Sep 17 00:00:00 2001 From: Oskar Carl Date: Sun, 24 Jan 2021 18:32:05 +0100 Subject: [PATCH 2/4] Proper formatting --- src/client.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 752574df..7f3229cf 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -241,9 +241,9 @@ auto waybar::Client::setupConfig(const std::string &config_file) -> void { } std::string str((std::istreambuf_iterator(file)), std::istreambuf_iterator()); util::JsonParser parser; - Json::Value tmp_config_ = parser.parse(str); + Json::Value tmp_config_ = parser.parse(str); if (tmp_config_["include"].isArray()) { - for (const auto& include : tmp_config_["include"]) { + for (const auto &include : tmp_config_["include"]) { spdlog::info("Including resource file: {}", include.asString()); setupConfig(getValidPath({include.asString()})); } @@ -252,7 +252,7 @@ auto waybar::Client::setupConfig(const std::string &config_file) -> void { } auto waybar::Client::mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void { - for (const auto& key : b_config_.getMemberNames()) { + for (const auto &key : b_config_.getMemberNames()) { if (a_config_[key].type() == Json::objectValue && b_config_[key].type() == Json::objectValue) { mergeConfig(a_config_[key], b_config_[key]); } else { From e62b634f72a9b91a6f2e94ba04a7ac60bcee23cb Mon Sep 17 00:00:00 2001 From: Oskar Carl Date: Mon, 21 Jun 2021 19:29:09 +0200 Subject: [PATCH 3/4] Workaround for circular imports --- include/client.hpp | 2 +- src/client.cpp | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/client.hpp b/include/client.hpp index af6eeef7..a54bf4b4 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -38,7 +38,7 @@ class Client { const std::string getValidPath(const std::vector &paths) const; void handleOutput(struct waybar_output &output); bool isValidOutput(const Json::Value &config, struct waybar_output &output); - auto setupConfig(const std::string &config_file) -> void; + auto setupConfig(const std::string &config_file, int depth) -> void; auto mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void; auto setupCss(const std::string &css_file) -> void; struct waybar_output & getOutput(void *); diff --git a/src/client.cpp b/src/client.cpp index 7f3229cf..07c0b23d 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -234,7 +234,10 @@ std::tuple waybar::Client::getConfigs( return {config_file, css_file}; } -auto waybar::Client::setupConfig(const std::string &config_file) -> void { +auto waybar::Client::setupConfig(const std::string &config_file, int depth) -> void { + if (depth > 100) { + throw std::runtime_error("Aborting due to likely recursive include in config files"); + } std::ifstream file(config_file); if (!file.is_open()) { throw std::runtime_error("Can't open config file"); @@ -245,7 +248,7 @@ auto waybar::Client::setupConfig(const std::string &config_file) -> void { if (tmp_config_["include"].isArray()) { for (const auto &include : tmp_config_["include"]) { spdlog::info("Including resource file: {}", include.asString()); - setupConfig(getValidPath({include.asString()})); + setupConfig(getValidPath({include.asString()}), ++depth); } } mergeConfig(config_, tmp_config_); @@ -337,7 +340,7 @@ int waybar::Client::main(int argc, char *argv[]) { } wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj()); auto [config_file, css_file] = getConfigs(config, style); - setupConfig(config_file); + setupConfig(config_file, 0); setupCss(css_file); bindInterfaces(); gtk_app->hold(); From 982d571b2ea0577b70582e2830ab878eb8070ff3 Mon Sep 17 00:00:00 2001 From: Oskar Carl Date: Wed, 23 Jun 2021 23:08:47 +0200 Subject: [PATCH 4/4] Add include man section --- man/waybar.5.scd.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/man/waybar.5.scd.in b/man/waybar.5.scd.in index fe11c4a7..6e6dd13a 100644 --- a/man/waybar.5.scd.in +++ b/man/waybar.5.scd.in @@ -85,6 +85,10 @@ Also a minimal example configuration can be found on the at the bottom of this m Option to disable the use of gtk-layer-shell for popups. Only functional if compiled with gtk-layer-shell support. +*include* ++ + typeof: array ++ + Paths to additional configuration files. In case of duplicate options, the including file's value takes precedence. Make sure to avoid circular imports. + # MODULE FORMAT You can use PangoMarkupFormat (See https://developer.gnome.org/pango/stable/PangoMarkupFormat.html#PangoMarkupFormat).