modules/custom: Allow json fields as format specifiers

This commit is contained in:
Tobias Manske 2023-08-30 06:36:50 +02:00
parent b665843085
commit 165814a57f
Signed by: tobias
GPG Key ID: 9164B527694A0709
2 changed files with 41 additions and 24 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <fmt/args.h>
#include <csignal> #include <csignal>
#include <string> #include <string>
@ -34,6 +35,7 @@ class Custom : public ALabel {
std::string alt_; std::string alt_;
std::string tooltip_; std::string tooltip_;
std::vector<std::string> class_; std::vector<std::string> class_;
fmt::dynamic_format_arg_store<fmt::format_context> fields_;
int percentage_; int percentage_;
FILE* fp_; FILE* fp_;
int pid_; int pid_;

View File

@ -122,14 +122,14 @@ auto waybar::modules::Custom::update() -> void {
(output_.out.empty() || output_.exit_code != 0)) { (output_.out.empty() || output_.exit_code != 0)) {
event_box_.hide(); event_box_.hide();
} else { } else {
fields_.clear();
if (config_["return-type"].asString() == "json") { if (config_["return-type"].asString() == "json") {
parseOutputJson(); parseOutputJson();
} else { } else {
parseOutputRaw(); parseOutputRaw();
} }
auto str = fmt::format(fmt::runtime(format_), text_, fmt::arg("alt", alt_), auto str = fmt::vformat(format_, fields_);
fmt::arg("icon", getIcon(percentage_, alt_)),
fmt::arg("percentage", percentage_));
if (str.empty()) { if (str.empty()) {
event_box_.hide(); event_box_.hide();
} else { } else {
@ -173,6 +173,7 @@ void waybar::modules::Custom::parseOutputRaw() {
} else { } else {
text_ = line; text_ = line;
} }
fields_.push_back(text_);
tooltip_ = line; tooltip_ = line;
class_.clear(); class_.clear();
} else if (i == 1) { } else if (i == 1) {
@ -189,32 +190,46 @@ void waybar::modules::Custom::parseOutputRaw() {
void waybar::modules::Custom::parseOutputJson() { void waybar::modules::Custom::parseOutputJson() {
std::istringstream output(output_.out); std::istringstream output(output_.out);
std::string line; std::string line;
getline(output, line);
class_.clear(); class_.clear();
while (getline(output, line)) { auto parsed = parser_.parse(line);
auto parsed = parser_.parse(line); parsed = parser_.parse(line);
// Preserve order so that first "{}" is resolved to "text" for backwards compatability
if (parsed["text"].isString()) {
auto str = parsed["text"].asString();
if (config_["escape"].isBool() && config_["escape"].asBool()) { if (config_["escape"].isBool() && config_["escape"].asBool()) {
text_ = Glib::Markup::escape_text(parsed["text"].asString()); str = Glib::Markup::escape_text(str);
} else {
text_ = parsed["text"].asString();
} }
fields_.push_back(str);
}
for (auto const& key : parsed.getMemberNames()) {
if (!parsed[key].isString()) continue;
auto str = parsed[key].asString();
if (config_["escape"].isBool() && config_["escape"].asBool()) { if (config_["escape"].isBool() && config_["escape"].asBool()) {
alt_ = Glib::Markup::escape_text(parsed["alt"].asString()); str = Glib::Markup::escape_text(str);
} else {
alt_ = parsed["alt"].asString();
} }
tooltip_ = parsed["tooltip"].asString(); fields_.push_back(fmt::arg(key.c_str(), str));
if (parsed["class"].isString()) { }
class_.push_back(parsed["class"].asString());
} else if (parsed["class"].isArray()) { tooltip_ = parsed["tooltip"].asString();
for (auto const& c : parsed["class"]) { if (parsed["class"].isString()) {
class_.push_back(c.asString()); class_.push_back(parsed["class"].asString());
} } else if (parsed["class"].isArray()) {
for (auto const& c : parsed["class"]) {
class_.push_back(c.asString());
} }
if (!parsed["percentage"].asString().empty() && parsed["percentage"].isNumeric()) { }
percentage_ = (int)lround(parsed["percentage"].asFloat());
} else { if (!parsed["percentage"].asString().empty() && parsed["percentage"].isNumeric()) {
percentage_ = 0; percentage_ = (int)lround(parsed["percentage"].asFloat());
} } else {
break; percentage_ = 0;
}
// Allow overriding icon from json, otherwise use percentage based icon
if (parsed["icon"].isNull()) {
fields_.push_back(fmt::arg("icon", getIcon(percentage_, alt_)));
} }
} }