From 08da7b5282cfbcfa705cd069726c728a814700aa Mon Sep 17 00:00:00 2001 From: markx86 <25851052+markx86@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:31:56 +0200 Subject: [PATCH] feat: Add support for battery related events --- include/modules/battery.hpp | 2 ++ src/ALabel.cpp | 2 +- src/modules/battery.cpp | 33 ++++++++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp index 8e1a2ad2..c593e59b 100644 --- a/include/modules/battery.hpp +++ b/include/modules/battery.hpp @@ -35,6 +35,7 @@ class Battery : public ALabel { std::tuple getInfos(); const std::string formatTimeRemaining(float hoursRemaining); void setBarClass(std::string&); + void processEvents(std::string& state, std::string& status, uint8_t capacity); int global_watch; std::map batteries_; @@ -43,6 +44,7 @@ class Battery : public ALabel { int global_watch_fd_; std::mutex battery_list_mutex_; std::string old_status_; + std::string last_event_; bool warnFirstTime_{true}; const Bar& bar_; diff --git a/src/ALabel.cpp b/src/ALabel.cpp index c218e402..6df80e46 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -200,7 +200,7 @@ std::string ALabel::getState(uint8_t value, bool lesser) { } } // Sort states - std::sort(states.begin(), states.end(), [&lesser](auto& a, auto& b) { + std::ranges::sort(states.begin(), states.end(), [&lesser](auto& a, auto& b) { return lesser ? a.second < b.second : a.second > b.second; }); std::string valid_state; diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 44481448..5738d883 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -1,14 +1,15 @@ #include "modules/battery.hpp" +#include "util/command.hpp" #include +#include #if defined(__FreeBSD__) #include #endif #include -#include waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const Json::Value& config) - : ALabel(config, "battery", id, "{capacity}%", 60), bar_(bar) { + : ALabel(config, "battery", id, "{capacity}%", 60), last_event_(""), bar_(bar) { #if defined(__linux__) battery_watch_fd_ = inotify_init1(IN_CLOEXEC); if (battery_watch_fd_ == -1) { @@ -26,6 +27,7 @@ waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const J throw std::runtime_error("Could not watch for battery plug/unplug"); } #endif + spdlog::debug("battery: worker interval is {}", interval_.count()); worker(); } @@ -677,10 +679,11 @@ auto waybar::modules::Battery::update() -> void { } auto status_pretty = status; // Transform to lowercase and replace space with dash - std::transform(status.begin(), status.end(), status.begin(), + std::ranges::transform(status.begin(), status.end(), status.begin(), [](char ch) { return ch == ' ' ? '-' : std::tolower(ch); }); auto format = format_; auto state = getState(capacity, true); + processEvents(state, status, capacity); setBarClass(state); auto time_remaining_formatted = formatTimeRemaining(time_remaining); if (tooltipEnabled()) { @@ -767,3 +770,27 @@ void waybar::modules::Battery::setBarClass(std::string& state) { bar_.window.get_style_context()->add_class(new_class); } } + +void waybar::modules::Battery::processEvents(std::string& state, std::string& status, uint8_t capacity) { + // There are no events specified, skip + auto events = config_["events"]; + if (!events.isObject() || events.empty()) { + return; + } + std::string event_name = fmt::format( + "on-{}-{}", + status == "discharging" ? status : "charging", + state.empty() ? std::to_string(capacity) : state + ); + if (last_event_ != event_name) { + spdlog::debug("battery: triggering event {}", event_name); + if (events[event_name].isString()) { + std::string exec = events[event_name].asString(); + // Execute the command if it is not empty + if (!exec.empty()) { + util::command::exec(exec, ""); + } + } + last_event_ = event_name; + } +}