Do not fail to parse a multi-bar config
This commit is contained in:
parent
7c1303f57c
commit
78aaa5c1b4
|
@ -39,6 +39,7 @@ class Client {
|
||||||
void handleOutput(struct waybar_output &output);
|
void handleOutput(struct waybar_output &output);
|
||||||
bool isValidOutput(const Json::Value &config, struct waybar_output &output);
|
bool isValidOutput(const Json::Value &config, struct waybar_output &output);
|
||||||
auto setupConfig(const std::string &config_file, int depth) -> void;
|
auto setupConfig(const std::string &config_file, int depth) -> void;
|
||||||
|
auto resolveConfigIncludes(Json::Value &config, int depth) -> void;
|
||||||
auto mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void;
|
auto mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void;
|
||||||
auto setupCss(const std::string &css_file) -> void;
|
auto setupCss(const std::string &css_file) -> void;
|
||||||
struct waybar_output & getOutput(void *);
|
struct waybar_output & getOutput(void *);
|
||||||
|
|
|
@ -86,8 +86,9 @@ Also a minimal example configuration can be found on the at the bottom of this m
|
||||||
Only functional if compiled with gtk-layer-shell support.
|
Only functional if compiled with gtk-layer-shell support.
|
||||||
|
|
||||||
*include* ++
|
*include* ++
|
||||||
typeof: array ++
|
typeof: string|array ++
|
||||||
Paths to additional configuration files. In case of duplicate options, the including file's value takes precedence. Make sure to avoid circular imports.
|
Paths to additional configuration files. In case of duplicate options, the including file's value takes precedence. Make sure to avoid circular imports.
|
||||||
|
For a multi-bar config, specify at least an empty object for each bar also in every file being included.
|
||||||
|
|
||||||
# MODULE FORMAT
|
# MODULE FORMAT
|
||||||
|
|
||||||
|
|
|
@ -245,22 +245,50 @@ auto waybar::Client::setupConfig(const std::string &config_file, int depth) -> v
|
||||||
std::string str((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
std::string str((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||||
util::JsonParser parser;
|
util::JsonParser parser;
|
||||||
Json::Value tmp_config_ = parser.parse(str);
|
Json::Value tmp_config_ = parser.parse(str);
|
||||||
if (tmp_config_["include"].isArray()) {
|
if (tmp_config_.isArray()) {
|
||||||
for (const auto &include : tmp_config_["include"]) {
|
for (auto &config_part : tmp_config_) {
|
||||||
spdlog::info("Including resource file: {}", include.asString());
|
resolveConfigIncludes(config_part, depth);
|
||||||
setupConfig(getValidPath({include.asString()}), ++depth);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
resolveConfigIncludes(tmp_config_, depth);
|
||||||
}
|
}
|
||||||
mergeConfig(config_, tmp_config_);
|
mergeConfig(config_, tmp_config_);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::Client::mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void {
|
auto waybar::Client::resolveConfigIncludes(Json::Value &config, int depth) -> void {
|
||||||
for (const auto &key : b_config_.getMemberNames()) {
|
Json::Value includes = config["include"];
|
||||||
if (a_config_[key].type() == Json::objectValue && b_config_[key].type() == Json::objectValue) {
|
if (includes.isArray()) {
|
||||||
mergeConfig(a_config_[key], b_config_[key]);
|
for (const auto &include : includes) {
|
||||||
} else {
|
spdlog::info("Including resource file: {}", include.asString());
|
||||||
a_config_[key] = b_config_[key];
|
setupConfig(getValidPath({include.asString()}), ++depth);
|
||||||
}
|
}
|
||||||
|
} else if (includes.isString()) {
|
||||||
|
spdlog::info("Including resource file: {}", includes.asString());
|
||||||
|
setupConfig(getValidPath({includes.asString()}), ++depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waybar::Client::mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void {
|
||||||
|
if (!a_config_) {
|
||||||
|
// For the first config
|
||||||
|
a_config_ = b_config_;
|
||||||
|
} else if (a_config_.isObject() && b_config_.isObject()) {
|
||||||
|
for (const auto &key : b_config_.getMemberNames()) {
|
||||||
|
if (a_config_[key].isObject() && b_config_[key].isObject()) {
|
||||||
|
mergeConfig(a_config_[key], b_config_[key]);
|
||||||
|
} else {
|
||||||
|
a_config_[key] = b_config_[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (a_config_.isArray() && b_config_.isArray()) {
|
||||||
|
// This can happen only on the top-level array of a multi-bar config
|
||||||
|
for (Json::Value::ArrayIndex i = 0; i < b_config_.size(); i++) {
|
||||||
|
if (a_config_[i].isObject() && b_config_[i].isObject()) {
|
||||||
|
mergeConfig(a_config_[i], b_config_[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
spdlog::error("Cannot merge config, conflicting or invalid JSON types");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue