diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp index 017b0e48..bbdd0eed 100644 --- a/include/modules/battery.hpp +++ b/include/modules/battery.hpp @@ -16,6 +16,7 @@ #include #include "ALabel.hpp" +#include "bar.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { @@ -28,7 +29,7 @@ namespace fs = std::filesystem; class Battery : public ALabel { public: - Battery(const std::string&, const Json::Value&); + Battery(const std::string&, const waybar::Bar&, const Json::Value&); virtual ~Battery(); auto update() -> void override; @@ -40,6 +41,7 @@ class Battery : public ALabel { const std::string getAdapterStatus(uint8_t capacity) const; const std::tuple getInfos(); const std::string formatTimeRemaining(float hoursRemaining); + void setBarClass(std::string&); int global_watch; std::map batteries_; @@ -49,6 +51,7 @@ class Battery : public ALabel { std::mutex battery_list_mutex_; std::string old_status_; bool warnFirstTime_{true}; + const Bar& bar_; util::SleeperThread thread_; util::SleeperThread thread_battery_update_; diff --git a/man/waybar-battery.5.scd b/man/waybar-battery.5.scd index 7827f4a8..52a6a2d1 100644 --- a/man/waybar-battery.5.scd +++ b/man/waybar-battery.5.scd @@ -167,3 +167,10 @@ The *battery* module allows one to define custom formats based on up to two fact - ** can be defined in the *config*. For more information see *states*. - *#battery..* - Combination of both ** and **. + +The following classes are applied to the entire Waybar rather than just the +battery widget: + +- *window#waybar.battery-* + - ** can be defined in the *config*, as previously mentioned. + diff --git a/src/factory.cpp b/src/factory.cpp index 00fc42ed..2ad5b6fa 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -18,7 +18,7 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name, auto id = hash_pos != std::string::npos ? name.substr(hash_pos + 1) : ""; #if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM)) if (ref == "battery") { - return new waybar::modules::Battery(id, config_[name]); + return new waybar::modules::Battery(id, bar_, config_[name]); } #endif #ifdef HAVE_GAMEMODE diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 70268c8a..2495b33a 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -1,12 +1,13 @@ #include "modules/battery.hpp" +#include #if defined(__FreeBSD__) #include #endif #include #include -waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config) - : ALabel(config, "battery", id, "{capacity}%", 60) { +waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const Json::Value& config) + : ALabel(config, "battery", id, "{capacity}%", 60), bar_(bar) { #if defined(__linux__) battery_watch_fd_ = inotify_init1(IN_CLOEXEC); if (battery_watch_fd_ == -1) { @@ -641,6 +642,7 @@ auto waybar::modules::Battery::update() -> void { [](char ch) { return ch == ' ' ? '-' : std::tolower(ch); }); auto format = format_; auto state = getState(capacity, true); + setBarClass(state); auto time_remaining_formatted = formatTimeRemaining(time_remaining); if (tooltipEnabled()) { std::string tooltip_text_default; @@ -689,3 +691,39 @@ auto waybar::modules::Battery::update() -> void { // Call parent update ALabel::update(); } + +void waybar::modules::Battery::setBarClass(std::string& state) { + auto classes = bar_.window.get_style_context()->list_classes(); + const std::string prefix = "battery-"; + + auto old_class_it = std::find_if(classes.begin(), classes.end(), + [&prefix](auto classname) { + return classname.rfind(prefix, 0) == 0; + }); + + auto new_class = prefix + state; + + // If the bar doesn't have any `battery-` class + if(old_class_it == classes.end()) { + if(!state.empty()) { + bar_.window.get_style_context()->add_class(new_class); + } + return; + } + + auto old_class = *old_class_it; + + // If the bar has a `battery-` class, + // but `state` is empty + if(state.empty()) { + bar_.window.get_style_context()->remove_class(old_class); + return; + } + + // If the bar has a `battery-` class, + // and `state` is NOT empty + if(old_class != new_class) { + bar_.window.get_style_context()->remove_class(old_class); + bar_.window.get_style_context()->add_class(new_class); + } +}