Merge pull request #2810 from ArneshRC/master

feat(battery): added support for battery state-based classes on the entire waybar
This commit is contained in:
Alexis Rouillard 2024-01-23 22:45:24 +01:00 committed by GitHub
commit 0948a407d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 4 deletions

View File

@ -16,6 +16,7 @@
#include <vector> #include <vector>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "bar.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
namespace waybar::modules { namespace waybar::modules {
@ -28,7 +29,7 @@ namespace fs = std::filesystem;
class Battery : public ALabel { class Battery : public ALabel {
public: public:
Battery(const std::string&, const Json::Value&); Battery(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Battery(); virtual ~Battery();
auto update() -> void override; auto update() -> void override;
@ -40,6 +41,7 @@ class Battery : public ALabel {
const std::string getAdapterStatus(uint8_t capacity) const; const std::string getAdapterStatus(uint8_t capacity) const;
const std::tuple<uint8_t, float, std::string, float> getInfos(); const std::tuple<uint8_t, float, std::string, float> getInfos();
const std::string formatTimeRemaining(float hoursRemaining); const std::string formatTimeRemaining(float hoursRemaining);
void setBarClass(std::string&);
int global_watch; int global_watch;
std::map<fs::path, int> batteries_; std::map<fs::path, int> batteries_;
@ -49,6 +51,7 @@ class Battery : public ALabel {
std::mutex battery_list_mutex_; std::mutex battery_list_mutex_;
std::string old_status_; std::string old_status_;
bool warnFirstTime_{true}; bool warnFirstTime_{true};
const Bar& bar_;
util::SleeperThread thread_; util::SleeperThread thread_;
util::SleeperThread thread_battery_update_; util::SleeperThread thread_battery_update_;

View File

@ -167,3 +167,10 @@ The *battery* module allows one to define custom formats based on up to two fact
- *<state>* can be defined in the *config*. For more information see *states*. - *<state>* can be defined in the *config*. For more information see *states*.
- *#battery.<status>.<state>* - *#battery.<status>.<state>*
- Combination of both *<status>* and *<state>*. - Combination of both *<status>* and *<state>*.
The following classes are applied to the entire Waybar rather than just the
battery widget:
- *window#waybar.battery-<state>*
- *<state>* can be defined in the *config*, as previously mentioned.

View File

@ -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) : ""; auto id = hash_pos != std::string::npos ? name.substr(hash_pos + 1) : "";
#if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM)) #if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM))
if (ref == "battery") { if (ref == "battery") {
return new waybar::modules::Battery(id, config_[name]); return new waybar::modules::Battery(id, bar_, config_[name]);
} }
#endif #endif
#ifdef HAVE_GAMEMODE #ifdef HAVE_GAMEMODE

View File

@ -1,12 +1,13 @@
#include "modules/battery.hpp" #include "modules/battery.hpp"
#include <algorithm>
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <iostream> #include <iostream>
waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config) waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const Json::Value& config)
: ALabel(config, "battery", id, "{capacity}%", 60) { : ALabel(config, "battery", id, "{capacity}%", 60), bar_(bar) {
#if defined(__linux__) #if defined(__linux__)
battery_watch_fd_ = inotify_init1(IN_CLOEXEC); battery_watch_fd_ = inotify_init1(IN_CLOEXEC);
if (battery_watch_fd_ == -1) { if (battery_watch_fd_ == -1) {
@ -641,6 +642,7 @@ auto waybar::modules::Battery::update() -> void {
[](char ch) { return ch == ' ' ? '-' : std::tolower(ch); }); [](char ch) { return ch == ' ' ? '-' : std::tolower(ch); });
auto format = format_; auto format = format_;
auto state = getState(capacity, true); auto state = getState(capacity, true);
setBarClass(state);
auto time_remaining_formatted = formatTimeRemaining(time_remaining); auto time_remaining_formatted = formatTimeRemaining(time_remaining);
if (tooltipEnabled()) { if (tooltipEnabled()) {
std::string tooltip_text_default; std::string tooltip_text_default;
@ -689,3 +691,39 @@ auto waybar::modules::Battery::update() -> void {
// Call parent update // Call parent update
ALabel::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);
}
}