diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp index d7bb757..e587ea1 100644 --- a/include/modules/battery.hpp +++ b/include/modules/battery.hpp @@ -22,6 +22,8 @@ class Battery : public ALabel { static inline const fs::path data_dir_ = "/sys/class/power_supply/"; void worker(); + std::tuple getInfos(); + std::string getState(uint16_t, bool); util::SleeperThread thread_; util::SleeperThread threadTimer_; diff --git a/resources/config b/resources/config index ba9c945..680b450 100644 --- a/resources/config +++ b/resources/config @@ -43,9 +43,14 @@ "format": "{}% " }, "battery": { - // "warning": 30, // Default value: 30 - // "critical": 15, // Default value: 15 + "states": { + // "good": 95, + "warning": 30, + "critical": 15 + }, "format": "{capacity}% {icon}", + // "format-good": "", // An empty format will hide the module + "format-full": "", "format-icons": ["", "", "", "", ""] }, "battery#bat2": { diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 2828be4..70892fa 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -34,7 +34,6 @@ waybar::modules::Battery::Battery(const Json::Value& config) for (auto const& bat : batteries_) { inotify_add_watch(fd_, (bat / "uevent").c_str(), IN_ACCESS); } - label_.set_name("battery"); worker(); } @@ -63,7 +62,7 @@ void waybar::modules::Battery::worker() }; } -auto waybar::modules::Battery::update() -> void +std::tuple waybar::modules::Battery::getInfos() { try { uint16_t total = 0; @@ -79,28 +78,68 @@ auto waybar::modules::Battery::update() -> void total += capacity; } uint16_t capacity = total / batteries_.size(); - label_.set_text(fmt::format(format_, fmt::arg("capacity", capacity), - fmt::arg("icon", getIcon(capacity)))); - label_.set_tooltip_text(status); - bool charging = status == "Charging"; - if (charging) { - label_.get_style_context()->add_class("charging"); - } else { - label_.get_style_context()->remove_class("charging"); - } - auto warning = config_["warning"].isUInt() ? config_["warning"].asUInt() : 30; - auto critical = config_["critical"].isUInt() ? config_["critical"].asUInt() : 15; - if (capacity <= critical && !charging) { - label_.get_style_context()->add_class("critical"); - label_.get_style_context()->remove_class("warning"); - } else if (capacity <= warning && !charging) { - label_.get_style_context()->add_class("warning"); - label_.get_style_context()->remove_class("critical"); - } else { - label_.get_style_context()->remove_class("critical"); - label_.get_style_context()->remove_class("warning"); - } + return {capacity, status}; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; + return {0, "Unknown"}; + } +} + +std::string waybar::modules::Battery::getState(uint16_t capacity, bool charging) +{ + // Get current state + std::vector> states; + if (config_["states"].isObject()) { + for (auto it = config_["states"].begin(); it != config_["states"].end(); ++it) { + if (it->isUInt() && it.key().isString()) { + states.push_back({it.key().asString(), it->asUInt()}); + } + } + } + // Sort states + std::sort(states.begin(), states.end(), [](auto &a, auto &b) { + return a.second < b.second; + }); + std::string validState = ""; + for (auto state : states) { + if (capacity <= state.second && !charging && validState.empty()) { + label_.get_style_context()->add_class(state.first); + validState = state.first; + } else { + label_.get_style_context()->remove_class(state.first); + } + } + return validState; +} + +auto waybar::modules::Battery::update() -> void +{ + auto [capacity, status] = getInfos(); + label_.set_tooltip_text(status); + bool charging = status == "Charging"; + auto format = format_; + if (charging) { + label_.get_style_context()->add_class("charging"); + if (config_["format-charging"].isString()) { + format = config_["format-charging"].asString(); + } + } else { + label_.get_style_context()->remove_class("charging"); + if (status == "Full" && config_["format-full"].isString()) { + format = config_["format-full"].asString(); + } + } + auto state = getState(capacity, charging); + if (!state.empty() && config_["format-" + state].isString()) { + format = config_["format-" + state].asString(); + } + if (format.empty()) { + event_box_.hide(); + label_.set_name(""); + } else { + event_box_.show(); + label_.set_name("battery"); + label_.set_text(fmt::format(format, fmt::arg("capacity", capacity), + fmt::arg("icon", getIcon(capacity)))); } }