diff --git a/include/modules/bluetooth.hpp b/include/modules/bluetooth.hpp index d0fdce8a..9dbb7fa8 100644 --- a/include/modules/bluetooth.hpp +++ b/include/modules/bluetooth.hpp @@ -5,6 +5,7 @@ #include #include "util/sleeper_thread.hpp" +#include "util/rfkill.hpp" namespace waybar::modules { @@ -15,8 +16,10 @@ class Bluetooth : public ALabel { auto update() -> void; private: - std::string status_; - util::SleeperThread thread_; + std::string status_; + util::SleeperThread thread_; + + util::Rfkill rfkill_; }; } // namespace waybar::modules diff --git a/include/modules/network.hpp b/include/modules/network.hpp index 91e4ddb2..2d9d72ca 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -11,6 +11,7 @@ #include #include "ALabel.hpp" #include "util/sleeper_thread.hpp" +#include "util/rfkill.hpp" namespace waybar::modules { @@ -71,6 +72,8 @@ class Network : public ALabel { util::SleeperThread thread_; util::SleeperThread thread_timer_; + + util::Rfkill rfkill_; }; } // namespace waybar::modules diff --git a/include/util/rfkill.hpp b/include/util/rfkill.hpp index f309b6fb..b2fcccea 100644 --- a/include/util/rfkill.hpp +++ b/include/util/rfkill.hpp @@ -2,8 +2,20 @@ #include -namespace waybar::util::rfkill { +namespace waybar::util { -bool isDisabled(enum rfkill_type rfkill_type); +class Rfkill { + public: + Rfkill(enum rfkill_type rfkill_type); + ~Rfkill() = default; + bool isDisabled() const; + void waitForEvent(); + int getState(); + + private: + enum rfkill_type rfkill_type_; + int state_ = 0; + int prev_state_ = 0; +}; } // namespace waybar::util diff --git a/src/modules/bluetooth.cpp b/src/modules/bluetooth.cpp index dff42cdb..9e6d797d 100644 --- a/src/modules/bluetooth.cpp +++ b/src/modules/bluetooth.cpp @@ -1,25 +1,23 @@ #include "modules/bluetooth.hpp" #include "util/rfkill.hpp" #include - #include +#include + waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config) : ALabel(config, "bluetooth", id, "{status}", 10), - status_("disabled") { + status_("disabled"), + rfkill_(*(new waybar::util::Rfkill(RFKILL_TYPE_BLUETOOTH))) { thread_ = [this] { dp.emit(); - auto now = std::chrono::system_clock::now(); - auto timeout = std::chrono::floor(now + interval_); - auto diff = std::chrono::seconds(timeout.time_since_epoch().count() % interval_.count()); - thread_.sleep_until(timeout - diff); + rfkill_.waitForEvent(); }; - //dp.emit(); } auto waybar::modules::Bluetooth::update() -> void { status_ = "enabled"; - if (waybar::util::rfkill::isDisabled(RFKILL_TYPE_BLUETOOTH)) { + if (rfkill_.getState()) { status_ = "disabled"; } else { status_ = "enabled"; @@ -35,7 +33,7 @@ auto waybar::modules::Bluetooth::update() -> void { ////auto tooltip_text = fmt::format(tooltip_format, localtime); //label_.set_tooltip_text(tooltip_text); //} else { - //label_.set_tooltip_text(text); + //label_.set_tooltip_text(status_); //} //} } diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 63e3be95..31619bfb 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -87,7 +87,9 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf cidr_(-1), signal_strength_dbm_(0), signal_strength_(0), - frequency_(0) { + frequency_(0), + rfkill_(*(new waybar::util::Rfkill(RFKILL_TYPE_WLAN))) { + auto down_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_DOWN_TOTAL_KEY); auto up_octets = read_netstat(BANDWIDTH_CATEGORY, BANDWIDTH_UP_TOTAL_KEY); if (down_octets) { @@ -224,7 +226,7 @@ void waybar::modules::Network::worker() { const std::string waybar::modules::Network::getNetworkState() const { if (ifid_ == -1) { - if (waybar::util::rfkill::isDisabled(RFKILL_TYPE_WLAN)) + if (rfkill_.isDisabled()) return "disabled"; return "disconnected"; } diff --git a/src/util/rfkill.cpp b/src/util/rfkill.cpp index 2b0e42da..92aee029 100644 --- a/src/util/rfkill.cpp +++ b/src/util/rfkill.cpp @@ -3,9 +3,71 @@ #include #include #include +#include #include +#include -bool waybar::util::rfkill::isDisabled(enum rfkill_type rfkill_type) { +waybar::util::Rfkill::Rfkill(const enum rfkill_type rfkill_type) + : rfkill_type_(rfkill_type) { +} + +void waybar::util::Rfkill::waitForEvent() { + struct rfkill_event event; + struct pollfd p; + ssize_t len; + int fd, n; + + fd = open("/dev/rfkill", O_RDONLY); + if (fd < 0) { + //perror("Can't open RFKILL control device"); + return; + } + + memset(&p, 0, sizeof(p)); + p.fd = fd; + p.events = POLLIN | POLLHUP; + + while (1) { + n = poll(&p, 1, -1); + if (n < 0) { + //perror("Failed to poll RFKILL control device"); + break; + } + + if (n == 0) + continue; + + len = read(fd, &event, sizeof(event)); + if (len < 0) { + //perror("Reading of RFKILL events failed"); + break; + } + + if (len != RFKILL_EVENT_SIZE_V1) { + //fprintf(stderr, "Wrong size of RFKILL event\n"); + continue; + } + + if(event.type == rfkill_type_) { + state_ = event.soft || event.hard; + if (prev_state_ != state_) { + prev_state_ = state_; + break; + } + //ret = event.soft || event.hard; + } + } + + close(fd); + return; +} + + +int waybar::util::Rfkill::getState() { + return state_; +} + +bool waybar::util::Rfkill::isDisabled() const { struct rfkill_event event; ssize_t len; int fd; @@ -38,7 +100,7 @@ bool waybar::util::rfkill::isDisabled(enum rfkill_type rfkill_type) { return false; } - if(event.type == rfkill_type) { + if(event.type == rfkill_type_) { ret = event.soft || event.hard; break; }