77#if defined(__FreeBSD__)
88#include < sys/sysctl.h>
99#endif
10+ #include < libudev.h>
11+ #include < poll.h>
1012#include < spdlog/spdlog.h>
13+ #include < sys/signalfd.h>
1114
1215waybar::modules::Battery::Battery (const std::string& id, const Bar& bar, const Json::Value& config)
1316 : ALabel(config, " battery" , id, " {capacity}%" , 60 ), last_event_(" " ), bar_(bar) {
@@ -16,17 +19,19 @@ waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const J
1619 if (battery_watch_fd_ == -1 ) {
1720 throw std::runtime_error (" Unable to listen batteries." );
1821 }
19-
20- global_watch_fd_ = inotify_init1 (IN_CLOEXEC);
21- if (global_watch_fd_ == -1 ) {
22- throw std::runtime_error (" Unable to listen batteries." );
22+ udev_ = std::unique_ptr<udev, util::UdevDeleter>(udev_new ());
23+ if (udev_ == nullptr ) {
24+ throw std::runtime_error (" udev_new failed" );
2325 }
24-
25- // Watch the directory for any added or removed batteries
26- global_watch = inotify_add_watch (global_watch_fd_, data_dir_.c_str (), IN_CREATE | IN_DELETE);
27- if (global_watch < 0 ) {
28- throw std::runtime_error (" Could not watch for battery plug/unplug" );
26+ mon_ = std::unique_ptr<udev_monitor, util::UdevMonitorDeleter>(
27+ udev_monitor_new_from_netlink (udev_.get (), " kernel" ));
28+ if (mon_ == nullptr ) {
29+ throw std::runtime_error (" udev monitor new failed" );
2930 }
31+ if (udev_monitor_filter_add_match_subsystem_devtype (mon_.get (), " power_supply" , nullptr ) < 0 ) {
32+ throw std::runtime_error (" udev failed to add monitor filter" );
33+ }
34+ udev_monitor_enable_receiving (mon_.get ());
3035
3136 if (config_[" weighted-average" ].isBool ()) weightedAverage_ = config_[" weighted-average" ].asBool ();
3237#endif
@@ -38,11 +43,6 @@ waybar::modules::Battery::~Battery() {
3843#if defined(__linux__)
3944 std::lock_guard<std::mutex> guard (battery_list_mutex_);
4045
41- if (global_watch >= 0 ) {
42- inotify_rm_watch (global_watch_fd_, global_watch);
43- }
44- close (global_watch_fd_);
45-
4646 for (auto it = batteries_.cbegin (), next_it = it; it != batteries_.cend (); it = next_it) {
4747 ++next_it;
4848 auto watch_id = (*it).second ;
@@ -79,12 +79,18 @@ void waybar::modules::Battery::worker() {
7979 dp.emit ();
8080 };
8181 thread_battery_update_ = [this ] {
82- struct inotify_event event = {0 };
83- int nbytes = read (global_watch_fd_, &event, sizeof (event));
84- if (nbytes != sizeof (event) || event.mask & IN_IGNORED) {
82+ poll_fds_[0 ].revents = 0 ;
83+ poll_fds_[0 ].events = POLLIN;
84+ poll_fds_[0 ].fd = udev_monitor_get_fd (mon_.get ());
85+ int ret = poll (poll_fds_.data (), poll_fds_.size (), -1 );
86+ if (ret < 0 ) {
8587 thread_.stop ();
8688 return ;
8789 }
90+ if ((poll_fds_[0 ].revents & POLLIN) != 0 ) {
91+ signalfd_siginfo signal_info;
92+ read (poll_fds_[0 ].fd , &signal_info, sizeof (signal_info));
93+ }
8894 refreshBatteries ();
8995 dp.emit ();
9096 };
@@ -680,6 +686,7 @@ auto waybar::modules::Battery::update() -> void {
680686 status = getAdapterStatus (capacity);
681687 }
682688 auto status_pretty = status;
689+ puts (status.c_str ());
683690 // Transform to lowercase and replace space with dash
684691 std::ranges::transform (status.begin (), status.end (), status.begin (),
685692 [](char ch) { return ch == ' ' ? ' -' : std::tolower (ch); });
0 commit comments