From 2dc4ae78fcd96ffc549b8ed094a3eb43c20bf73a Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Mon, 20 Jan 2020 00:35:37 +0100 Subject: [PATCH 1/9] distinguish between wifi disabled and disconnected --- include/modules/network.hpp | 2 ++ src/modules/network.cpp | 54 ++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/modules/network.hpp b/include/modules/network.hpp index 91e4ddb..f0d2e8e 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "ALabel.hpp" #include "util/sleeper_thread.hpp" @@ -45,6 +46,7 @@ class Network : public ALabel { const std::string getNetworkState() const; void clearIface(); bool wildcardMatch(const std::string& pattern, const std::string& text) const; + bool isDisabled(enum rfkill_type rfkill_type) const; int ifid_; sa_family_t family_; diff --git a/src/modules/network.cpp b/src/modules/network.cpp index a332d5a..b140a95 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -4,6 +4,11 @@ #include #include "util/format.hpp" +#include +//#include +#include +#include +#include namespace { @@ -221,12 +226,59 @@ void waybar::modules::Network::worker() { } const std::string waybar::modules::Network::getNetworkState() const { - if (ifid_ == -1) return "disconnected"; + if (ifid_ == -1) { + if (isDisabled(RFKILL_TYPE_WLAN)) + return "disabled"; + return "disconnected"; + } if (ipaddr_.empty()) return "linked"; if (essid_.empty()) return "ethernet"; return "wifi"; } +bool waybar::modules::Network::isDisabled(enum rfkill_type rfkill_type) const { + struct rfkill_event event; + ssize_t len; + int fd; + int ret; + ret = false; + + fd = open("/dev/rfkill", O_RDONLY); + if (fd < 0) { + perror("Can't open RFKILL control device"); + return false; + } + + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { + perror("Can't set RFKILL control device to non-blocking"); + close(fd); + return false; + } + + while(true) { + len = read(fd, &event, sizeof(event)); + if (len < 0) { + if (errno == EAGAIN) + return 1; + perror("Reading of RFKILL events failed"); + return false; + } + + if (len != RFKILL_EVENT_SIZE_V1) { + fprintf(stderr, "Wrong size of RFKILL event\n"); + return false; + } + + if(event.type == rfkill_type) { + ret = event.soft || event.hard; + break; + } + } + + close(fd); + return ret; +} + auto waybar::modules::Network::update() -> void { std::lock_guard lock(mutex_); std::string tooltip_format; From 2c4369a65321901fb70b5d9327736a9aaa6e9bd0 Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Tue, 21 Jan 2020 15:46:08 +0100 Subject: [PATCH 2/9] add basis for bluetooth module implementation --- include/factory.hpp | 1 + meson.build | 1 + src/factory.cpp | 3 +++ 3 files changed, 5 insertions(+) diff --git a/include/factory.hpp b/include/factory.hpp index 7d4d14e..b14b998 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -32,6 +32,7 @@ #include "bar.hpp" #include "modules/custom.hpp" #include "modules/temperature.hpp" +#include "modules/bluetooth.hpp" namespace waybar { diff --git a/meson.build b/meson.build index a099ad2..0032c91 100644 --- a/meson.build +++ b/meson.build @@ -88,6 +88,7 @@ src_files = files( 'src/ALabel.cpp', 'src/modules/memory.cpp', 'src/modules/battery.cpp', + 'src/modules/bluetooth.cpp', 'src/modules/clock.cpp', 'src/modules/custom.cpp', 'src/modules/cpu.cpp', diff --git a/src/factory.cpp b/src/factory.cpp index 8f7cea7..16a6903 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -66,6 +66,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "temperature") { return new waybar::modules::Temperature(id, config_[name]); } + if (ref == "bluetooth") { + return new waybar::modules::Bluetooth(id, config_[name]); + } if (ref.compare(0, 7, "custom/") == 0 && ref.size() > 7) { return new waybar::modules::Custom(ref.substr(7), id, config_[name]); } From 626af1ddc15df55b92bd38e03977089922e34f40 Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Tue, 21 Jan 2020 17:04:54 +0100 Subject: [PATCH 3/9] add rudimentary bluetooth module functionality --- include/modules/bluetooth.hpp | 18 ++++++++++++ include/util/rfkill.hpp | 55 +++++++++++++++++++++++++++++++++++ src/modules/bluetooth.cpp | 29 ++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 include/modules/bluetooth.hpp create mode 100644 include/util/rfkill.hpp create mode 100644 src/modules/bluetooth.cpp diff --git a/include/modules/bluetooth.hpp b/include/modules/bluetooth.hpp new file mode 100644 index 0000000..4329861 --- /dev/null +++ b/include/modules/bluetooth.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "ALabel.hpp" + +namespace waybar::modules { + +class Bluetooth : public ALabel { + public: + Bluetooth(const std::string&, const Json::Value&); + ~Bluetooth() = default; + auto update() -> void; + + private: + ; +}; + +} // namespace waybar::modules diff --git a/include/util/rfkill.hpp b/include/util/rfkill.hpp new file mode 100644 index 0000000..9ef6892 --- /dev/null +++ b/include/util/rfkill.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +//#include +#include +#include +#include + +namespace waybar::util { + +bool isDisabled(enum rfkill_type rfkill_type) { + struct rfkill_event event; + ssize_t len; + int fd; + int ret; + ret = false; + + fd = open("/dev/rfkill", O_RDONLY); + if (fd < 0) { + perror("Can't open RFKILL control device"); + return false; + } + + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { + perror("Can't set RFKILL control device to non-blocking"); + close(fd); + return false; + } + + while(true) { + len = read(fd, &event, sizeof(event)); + if (len < 0) { + if (errno == EAGAIN) + return 1; + perror("Reading of RFKILL events failed"); + return false; + } + + if (len != RFKILL_EVENT_SIZE_V1) { + fprintf(stderr, "Wrong size of RFKILL event\n"); + return false; + } + + if(event.type == rfkill_type) { + ret = event.soft || event.hard; + break; + } + } + + close(fd); + return ret; +} + +} // namespace waybar::util diff --git a/src/modules/bluetooth.cpp b/src/modules/bluetooth.cpp new file mode 100644 index 0000000..ab8bdda --- /dev/null +++ b/src/modules/bluetooth.cpp @@ -0,0 +1,29 @@ +#include "modules/bluetooth.hpp" +#include "util/rfkill.hpp" +#include + +waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config) + : ALabel(config, "bluetooth", id, "{status}", 10) { + dp.emit(); +} + +auto waybar::modules::Bluetooth::update() -> void { + auto text = "enabled"; + if (waybar::util::isDisabled(RFKILL_TYPE_BLUETOOTH)) { + text = "disabled"; + } else { + text = "enabled"; + } + + label_.set_markup(text); + + if (tooltipEnabled()) { + if (config_["tooltip-format"].isString()) { + auto tooltip_format = config_["tooltip-format"].asString(); + auto tooltip_text = fmt::format(tooltip_format, localtime); + label_.set_tooltip_text(tooltip_text); + } else { + label_.set_tooltip_text(text); + } + } +} From f0dbd8b78ddacee555cabb0258d758ff670db122 Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Tue, 21 Jan 2020 17:48:45 +0100 Subject: [PATCH 4/9] properly structure rfkill util --- include/modules/network.hpp | 2 -- include/util/rfkill.hpp | 48 +------------------------------ meson.build | 3 +- src/modules/network.cpp | 57 ++++--------------------------------- src/util/rfkill.cpp | 49 +++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 102 deletions(-) create mode 100644 src/util/rfkill.cpp diff --git a/include/modules/network.hpp b/include/modules/network.hpp index f0d2e8e..91e4ddb 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -9,7 +9,6 @@ #include #include #include -#include #include "ALabel.hpp" #include "util/sleeper_thread.hpp" @@ -46,7 +45,6 @@ class Network : public ALabel { const std::string getNetworkState() const; void clearIface(); bool wildcardMatch(const std::string& pattern, const std::string& text) const; - bool isDisabled(enum rfkill_type rfkill_type) const; int ifid_; sa_family_t family_; diff --git a/include/util/rfkill.hpp b/include/util/rfkill.hpp index 9ef6892..53f558c 100644 --- a/include/util/rfkill.hpp +++ b/include/util/rfkill.hpp @@ -1,55 +1,9 @@ #pragma once #include -#include -//#include -#include -#include -#include namespace waybar::util { -bool isDisabled(enum rfkill_type rfkill_type) { - struct rfkill_event event; - ssize_t len; - int fd; - int ret; - ret = false; - - fd = open("/dev/rfkill", O_RDONLY); - if (fd < 0) { - perror("Can't open RFKILL control device"); - return false; - } - - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - perror("Can't set RFKILL control device to non-blocking"); - close(fd); - return false; - } - - while(true) { - len = read(fd, &event, sizeof(event)); - if (len < 0) { - if (errno == EAGAIN) - return 1; - perror("Reading of RFKILL events failed"); - return false; - } - - if (len != RFKILL_EVENT_SIZE_V1) { - fprintf(stderr, "Wrong size of RFKILL event\n"); - return false; - } - - if(event.type == rfkill_type) { - ret = event.soft || event.hard; - break; - } - } - - close(fd); - return ret; -} +bool isDisabled(enum rfkill_type rfkill_type); } // namespace waybar::util diff --git a/meson.build b/meson.build index 0032c91..8f29d10 100644 --- a/meson.build +++ b/meson.build @@ -97,7 +97,8 @@ src_files = files( 'src/modules/temperature.cpp', 'src/main.cpp', 'src/bar.cpp', - 'src/client.cpp' + 'src/client.cpp', + 'src/util/rfkill.cpp' ) if true # find_program('sway', required : false).found() diff --git a/src/modules/network.cpp b/src/modules/network.cpp index b140a95..2639a05 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -3,12 +3,8 @@ #include #include #include "util/format.hpp" - -#include -//#include -#include +#include "util/rfkill.hpp" #include -#include namespace { @@ -227,58 +223,15 @@ void waybar::modules::Network::worker() { const std::string waybar::modules::Network::getNetworkState() const { if (ifid_ == -1) { - if (isDisabled(RFKILL_TYPE_WLAN)) - return "disabled"; - return "disconnected"; - } + if (waybar::util::isDisabled(RFKILL_TYPE_WLAN)) + return "disabled"; + return "disconnected"; + } if (ipaddr_.empty()) return "linked"; if (essid_.empty()) return "ethernet"; return "wifi"; } -bool waybar::modules::Network::isDisabled(enum rfkill_type rfkill_type) const { - struct rfkill_event event; - ssize_t len; - int fd; - int ret; - ret = false; - - fd = open("/dev/rfkill", O_RDONLY); - if (fd < 0) { - perror("Can't open RFKILL control device"); - return false; - } - - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - perror("Can't set RFKILL control device to non-blocking"); - close(fd); - return false; - } - - while(true) { - len = read(fd, &event, sizeof(event)); - if (len < 0) { - if (errno == EAGAIN) - return 1; - perror("Reading of RFKILL events failed"); - return false; - } - - if (len != RFKILL_EVENT_SIZE_V1) { - fprintf(stderr, "Wrong size of RFKILL event\n"); - return false; - } - - if(event.type == rfkill_type) { - ret = event.soft || event.hard; - break; - } - } - - close(fd); - return ret; -} - auto waybar::modules::Network::update() -> void { std::lock_guard lock(mutex_); std::string tooltip_format; diff --git a/src/util/rfkill.cpp b/src/util/rfkill.cpp new file mode 100644 index 0000000..d1b38ec --- /dev/null +++ b/src/util/rfkill.cpp @@ -0,0 +1,49 @@ +#include "util/rfkill.hpp" +#include +#include +#include +#include +#include + +bool waybar::util::isDisabled(enum rfkill_type rfkill_type) { + struct rfkill_event event; + ssize_t len; + int fd; + int ret; + ret = false; + + fd = open("/dev/rfkill", O_RDONLY); + if (fd < 0) { + //perror("Can't open RFKILL control device"); + return false; + } + + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { + //perror("Can't set RFKILL control device to non-blocking"); + close(fd); + return false; + } + + while(true) { + len = read(fd, &event, sizeof(event)); + if (len < 0) { + if (errno == EAGAIN) + return 1; + //perror("Reading of RFKILL events failed"); + return false; + } + + if (len != RFKILL_EVENT_SIZE_V1) { + //fprintf(stderr, "Wrong size of RFKILL event\n"); + return false; + } + + if(event.type == rfkill_type) { + ret = event.soft || event.hard; + break; + } + } + + close(fd); + return ret; +} From 89cb9673d42c0d4eb97e134a40cce16a76b4ec1f Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Wed, 22 Jan 2020 11:37:47 +0100 Subject: [PATCH 5/9] bluetooth module working --- include/modules/bluetooth.hpp | 6 ++++- include/util/rfkill.hpp | 2 +- src/modules/bluetooth.cpp | 44 ++++++++++++++++++++++------------- src/modules/network.cpp | 2 +- src/util/rfkill.cpp | 2 +- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/include/modules/bluetooth.hpp b/include/modules/bluetooth.hpp index 4329861..d0fdce8 100644 --- a/include/modules/bluetooth.hpp +++ b/include/modules/bluetooth.hpp @@ -3,6 +3,9 @@ #include #include "ALabel.hpp" +#include +#include "util/sleeper_thread.hpp" + namespace waybar::modules { class Bluetooth : public ALabel { @@ -12,7 +15,8 @@ class Bluetooth : public ALabel { auto update() -> void; private: - ; + std::string status_; + util::SleeperThread thread_; }; } // namespace waybar::modules diff --git a/include/util/rfkill.hpp b/include/util/rfkill.hpp index 53f558c..f309b6f 100644 --- a/include/util/rfkill.hpp +++ b/include/util/rfkill.hpp @@ -2,7 +2,7 @@ #include -namespace waybar::util { +namespace waybar::util::rfkill { bool isDisabled(enum rfkill_type rfkill_type); diff --git a/src/modules/bluetooth.cpp b/src/modules/bluetooth.cpp index ab8bdda..dff42cd 100644 --- a/src/modules/bluetooth.cpp +++ b/src/modules/bluetooth.cpp @@ -2,28 +2,40 @@ #include "util/rfkill.hpp" #include +#include + waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config) - : ALabel(config, "bluetooth", id, "{status}", 10) { - dp.emit(); + : ALabel(config, "bluetooth", id, "{status}", 10), + status_("disabled") { + 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); + }; + //dp.emit(); } auto waybar::modules::Bluetooth::update() -> void { - auto text = "enabled"; - if (waybar::util::isDisabled(RFKILL_TYPE_BLUETOOTH)) { - text = "disabled"; + status_ = "enabled"; + if (waybar::util::rfkill::isDisabled(RFKILL_TYPE_BLUETOOTH)) { + status_ = "disabled"; } else { - text = "enabled"; + status_ = "enabled"; } - label_.set_markup(text); + label_.set_markup( + fmt::format(format_, fmt::arg("status", status_), fmt::arg("icon", getIcon(0, status_)))); + label_.get_style_context()->add_class(status_); - if (tooltipEnabled()) { - if (config_["tooltip-format"].isString()) { - auto tooltip_format = config_["tooltip-format"].asString(); - auto tooltip_text = fmt::format(tooltip_format, localtime); - label_.set_tooltip_text(tooltip_text); - } else { - label_.set_tooltip_text(text); - } - } + //if (tooltipEnabled()) { + //if (config_["tooltip-format"].isString()) { + //auto tooltip_format = config_["tooltip-format"].asString(); + ////auto tooltip_text = fmt::format(tooltip_format, localtime); + //label_.set_tooltip_text(tooltip_text); + //} else { + //label_.set_tooltip_text(text); + //} + //} } diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 2639a05..636db67 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -223,7 +223,7 @@ void waybar::modules::Network::worker() { const std::string waybar::modules::Network::getNetworkState() const { if (ifid_ == -1) { - if (waybar::util::isDisabled(RFKILL_TYPE_WLAN)) + if (waybar::util::rfkill::isDisabled(RFKILL_TYPE_WLAN)) return "disabled"; return "disconnected"; } diff --git a/src/util/rfkill.cpp b/src/util/rfkill.cpp index d1b38ec..2b0e42d 100644 --- a/src/util/rfkill.cpp +++ b/src/util/rfkill.cpp @@ -5,7 +5,7 @@ #include #include -bool waybar::util::isDisabled(enum rfkill_type rfkill_type) { +bool waybar::util::rfkill::isDisabled(enum rfkill_type rfkill_type) { struct rfkill_event event; ssize_t len; int fd; From e3bf6b968c8ff9f12cd38d2944007fff36270949 Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Thu, 23 Jan 2020 17:17:29 +0100 Subject: [PATCH 6/9] bluetooth module handles rfkill events instantly --- include/modules/bluetooth.hpp | 7 ++-- include/modules/network.hpp | 3 ++ include/util/rfkill.hpp | 16 +++++++-- src/modules/bluetooth.cpp | 16 ++++----- src/modules/network.cpp | 6 ++-- src/util/rfkill.cpp | 66 +++++++++++++++++++++++++++++++++-- 6 files changed, 97 insertions(+), 17 deletions(-) diff --git a/include/modules/bluetooth.hpp b/include/modules/bluetooth.hpp index d0fdce8..9dbb7fa 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 91e4ddb..2d9d72c 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 f309b6f..b2fccce 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 dff42cd..9e6d797 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 63e3be9..31619bf 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 2b0e42d..92aee02 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; } From c045288ce4cb22f1888b4fa7f3b37ed56d42c1df Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Sun, 26 Jan 2020 05:34:31 +0100 Subject: [PATCH 7/9] add man page for bluetooth, fix bluetooth race-condition --- include/modules/bluetooth.hpp | 1 + include/modules/network.hpp | 1 + include/util/rfkill.hpp | 5 +- man/waybar-bluetooth.5.scd | 94 +++++++++++++++++++++++++++++++++++ man/waybar-network.5.scd | 10 ++++ src/modules/bluetooth.cpp | 38 ++++++++------ src/modules/network.cpp | 18 +++++-- src/util/rfkill.cpp | 64 ++++-------------------- 8 files changed, 153 insertions(+), 78 deletions(-) create mode 100644 man/waybar-bluetooth.5.scd diff --git a/include/modules/bluetooth.hpp b/include/modules/bluetooth.hpp index 9dbb7fa..04c213d 100644 --- a/include/modules/bluetooth.hpp +++ b/include/modules/bluetooth.hpp @@ -18,6 +18,7 @@ class Bluetooth : public ALabel { private: std::string status_; util::SleeperThread thread_; + util::SleeperThread intervall_thread_; util::Rfkill rfkill_; }; diff --git a/include/modules/network.hpp b/include/modules/network.hpp index 2d9d72c..edb5aa6 100644 --- a/include/modules/network.hpp +++ b/include/modules/network.hpp @@ -72,6 +72,7 @@ class Network : public ALabel { util::SleeperThread thread_; util::SleeperThread thread_timer_; + util::SleeperThread thread_rfkill_; util::Rfkill rfkill_; }; diff --git a/include/util/rfkill.hpp b/include/util/rfkill.hpp index b2fccce..67a9807 100644 --- a/include/util/rfkill.hpp +++ b/include/util/rfkill.hpp @@ -5,12 +5,11 @@ namespace waybar::util { class Rfkill { - public: + public:; Rfkill(enum rfkill_type rfkill_type); ~Rfkill() = default; - bool isDisabled() const; void waitForEvent(); - int getState(); + int getState() const; private: enum rfkill_type rfkill_type_; diff --git a/man/waybar-bluetooth.5.scd b/man/waybar-bluetooth.5.scd new file mode 100644 index 0000000..7f6876b --- /dev/null +++ b/man/waybar-bluetooth.5.scd @@ -0,0 +1,94 @@ +waybar-bluetooth(5) + +# NAME + +waybar - bluetooth module + +# DESCRIPTION + +The *bluetooth* module displays information about the status of the device's bluetooth device. + +# CONFIGURATION + +Addressed by *bluetooth* + +*interval*: ++ + typeof: integer ++ + default: 60 ++ + The interval in which the network information gets polled (e.g. signal strength). + +*format*: ++ + typeof: string ++ + default: *{icon}* ++ + The format, how information should be displayed. This format is used when other formats aren't specified. + +*format-icons*: ++ + typeof: array/object ++ + Based on the device status, the corresponding icon gets selected. ++ + The order is *low* to *high*. Or by the state if it is an object. + +*rotate*: ++ + typeof: integer ++ + Positive value to rotate the text label. + +*max-length*: ++ + typeof: integer ++ + The maximum length in character the module should display. + +*on-click*: ++ + typeof: string ++ + Command to execute when clicked on the module. + +*on-click-middle*: ++ + typeof: string ++ + Command to execute when middle-clicked on the module using mousewheel. + +*on-click-right*: ++ + typeof: string ++ + Command to execute when you right clicked on the module. + +*on-scroll-up*: ++ + typeof: string ++ + Command to execute when scrolling up on the module. + +*on-scroll-down*: ++ + typeof: string ++ + Command to execute when scrolling down on the module. + +*smooth-scrolling-threshold*: ++ + typeof: double ++ + Threshold to be used when scrolling. + +*tooltip*: ++ + typeof: bool ++ + default: *true* ++ + Option to disable tooltip on hover. + +*tooltip-format*: ++ + typeof: string ++ + The format, how information should be displayed in the tooltip. This format is used when other formats aren't specified. + +# FORMAT REPLACEMENTS + +*{status}*: Status of the bluetooth device. + +*{icon}*: Icon, as defined in *format-icons*. + +# EXAMPLES + +``` +"bluetooth": { + "format": "{icon}", + "format-alt": "bluetooth: {status}", + "interval": 30, + "format-icons": { + "enabled": "", + "disabled": "" + } + "tooltip-format": "{status}" +} +``` + +# STYLE + +- *#bluetooth* diff --git a/man/waybar-network.5.scd b/man/waybar-network.5.scd index a557aa3..ad4c906 100644 --- a/man/waybar-network.5.scd +++ b/man/waybar-network.5.scd @@ -47,6 +47,10 @@ Addressed by *network* typeof: string ++ This format is used when the displayed interface is disconnected. +*format-disabled*: ++ + typeof: string ++ + This format is used when the displayed interface is disabled. + *format-icons*: ++ typeof: array/object ++ Based on the current signal strength, the corresponding icon gets selected. ++ @@ -105,6 +109,10 @@ Addressed by *network* typeof: string ++ This format is used when the displayed interface is disconnected. +*tooltip-format-disabled*: ++ + typeof: string ++ + This format is used when the displayed interface is disabled. + # FORMAT REPLACEMENTS *{ifname}*: Name of the network interface. @@ -142,6 +150,7 @@ Addressed by *network* "format-wifi": "{essid} ({signalStrength}%) ", "format-ethernet": "{ifname} ", "format-disconnected": "", //An empty format will hide the module. + "format-disconnected": "", "tooltip-format": "{ifname}", "tooltip-format-wifi": "{essid} ({signalStrength}%) ", "tooltip-format-ethernet": "{ifname} ", @@ -154,6 +163,7 @@ Addressed by *network* - *#network* - *#network.disconnected* +- *#network.disabled* - *#network.linked* - *#network.ethernet* - *#network.wifi* diff --git a/src/modules/bluetooth.cpp b/src/modules/bluetooth.cpp index 9e6d797..b390976 100644 --- a/src/modules/bluetooth.cpp +++ b/src/modules/bluetooth.cpp @@ -3,20 +3,24 @@ #include #include -#include - waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config) - : ALabel(config, "bluetooth", id, "{status}", 10), + : ALabel(config, "bluetooth", id, "{icon}", 10), status_("disabled"), - rfkill_(*(new waybar::util::Rfkill(RFKILL_TYPE_BLUETOOTH))) { + rfkill_{RFKILL_TYPE_BLUETOOTH} { thread_ = [this] { dp.emit(); rfkill_.waitForEvent(); }; + intervall_thread_ = [this] { + 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); + dp.emit(); + }; } auto waybar::modules::Bluetooth::update() -> void { - status_ = "enabled"; if (rfkill_.getState()) { status_ = "disabled"; } else { @@ -24,16 +28,18 @@ auto waybar::modules::Bluetooth::update() -> void { } label_.set_markup( - fmt::format(format_, fmt::arg("status", status_), fmt::arg("icon", getIcon(0, status_)))); - label_.get_style_context()->add_class(status_); + fmt::format( + format_, + fmt::arg("status", status_), + fmt::arg("icon", getIcon(0, status_)))); - //if (tooltipEnabled()) { - //if (config_["tooltip-format"].isString()) { - //auto tooltip_format = config_["tooltip-format"].asString(); - ////auto tooltip_text = fmt::format(tooltip_format, localtime); - //label_.set_tooltip_text(tooltip_text); - //} else { - //label_.set_tooltip_text(status_); - //} - //} + if (tooltipEnabled()) { + if (config_["tooltip-format"].isString()) { + auto tooltip_format = config_["tooltip-format"].asString(); + auto tooltip_text = fmt::format(tooltip_format, status_); + label_.set_tooltip_text(tooltip_text); + } else { + label_.set_tooltip_text(status_); + } + } } diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 31619bf..d2065bd 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -3,9 +3,9 @@ #include #include #include +#include #include "util/format.hpp" #include "util/rfkill.hpp" -#include namespace { @@ -88,8 +88,7 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf signal_strength_dbm_(0), signal_strength_(0), frequency_(0), - rfkill_(*(new waybar::util::Rfkill(RFKILL_TYPE_WLAN))) { - + 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) { @@ -199,6 +198,7 @@ void waybar::modules::Network::createInfoSocket() { } void waybar::modules::Network::worker() { + // update via here not working thread_timer_ = [this] { { std::lock_guard lock(mutex_); @@ -209,6 +209,16 @@ void waybar::modules::Network::worker() { } thread_timer_.sleep_for(interval_); }; + thread_rfkill_ = [this] { + rfkill_.waitForEvent(); + { + std::lock_guard lock(mutex_); + if (ifid_ > 0) { + getInfo(); + dp.emit(); + } + } + }; thread_ = [this] { std::array events{}; @@ -226,7 +236,7 @@ void waybar::modules::Network::worker() { const std::string waybar::modules::Network::getNetworkState() const { if (ifid_ == -1) { - if (rfkill_.isDisabled()) + if (rfkill_.getState()) return "disabled"; return "disconnected"; } diff --git a/src/util/rfkill.cpp b/src/util/rfkill.cpp index 92aee02..a4f9c71 100644 --- a/src/util/rfkill.cpp +++ b/src/util/rfkill.cpp @@ -1,11 +1,12 @@ #include "util/rfkill.hpp" +#include #include #include #include #include #include #include -#include +#include waybar::util::Rfkill::Rfkill(const enum rfkill_type rfkill_type) : rfkill_type_(rfkill_type) { @@ -19,7 +20,7 @@ void waybar::util::Rfkill::waitForEvent() { fd = open("/dev/rfkill", O_RDONLY); if (fd < 0) { - //perror("Can't open RFKILL control device"); + throw std::runtime_error("Can't open RFKILL control device"); return; } @@ -30,7 +31,7 @@ void waybar::util::Rfkill::waitForEvent() { while (1) { n = poll(&p, 1, -1); if (n < 0) { - //perror("Failed to poll RFKILL control device"); + throw std::runtime_error("Failed to poll RFKILL control device"); break; } @@ -39,22 +40,18 @@ void waybar::util::Rfkill::waitForEvent() { len = read(fd, &event, sizeof(event)); if (len < 0) { - //perror("Reading of RFKILL events failed"); + throw std::runtime_error("Reading of RFKILL events failed"); break; } if (len != RFKILL_EVENT_SIZE_V1) { - //fprintf(stderr, "Wrong size of RFKILL event\n"); + throw std::runtime_error("Wrong size of RFKILL event"); continue; } - if(event.type == rfkill_type_) { + if(event.type == rfkill_type_ && event.op == RFKILL_OP_CHANGE) { state_ = event.soft || event.hard; - if (prev_state_ != state_) { - prev_state_ = state_; - break; - } - //ret = event.soft || event.hard; + break; } } @@ -63,49 +60,6 @@ void waybar::util::Rfkill::waitForEvent() { } -int waybar::util::Rfkill::getState() { +int waybar::util::Rfkill::getState() const { return state_; } - -bool waybar::util::Rfkill::isDisabled() const { - struct rfkill_event event; - ssize_t len; - int fd; - int ret; - ret = false; - - fd = open("/dev/rfkill", O_RDONLY); - if (fd < 0) { - //perror("Can't open RFKILL control device"); - return false; - } - - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - //perror("Can't set RFKILL control device to non-blocking"); - close(fd); - return false; - } - - while(true) { - len = read(fd, &event, sizeof(event)); - if (len < 0) { - if (errno == EAGAIN) - return 1; - //perror("Reading of RFKILL events failed"); - return false; - } - - if (len != RFKILL_EVENT_SIZE_V1) { - //fprintf(stderr, "Wrong size of RFKILL event\n"); - return false; - } - - if(event.type == rfkill_type_) { - ret = event.soft || event.hard; - break; - } - } - - close(fd); - return ret; -} From 6ae9f436a9df953b67cda2b9cf731c7aa646dd97 Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Thu, 30 Jan 2020 00:25:37 +0100 Subject: [PATCH 8/9] add copyright notice for rfkill util --- src/util/rfkill.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/util/rfkill.cpp b/src/util/rfkill.cpp index a4f9c71..2d5ad7f 100644 --- a/src/util/rfkill.cpp +++ b/src/util/rfkill.cpp @@ -1,3 +1,21 @@ +/* https://git.kernel.org/pub/scm/linux/kernel/git/jberg/rfkill.git/ + * + * Copyright 2009 Johannes Berg + * Copyright 2009 Marcel Holtmann + * Copyright 2009 Tim Gardner + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + #include "util/rfkill.hpp" #include #include From dd7d78cd605ae067f66d742a119c4f1507bd4638 Mon Sep 17 00:00:00 2001 From: Marc <39213657+marcplustwo@users.noreply.github.com> Date: Sun, 23 Feb 2020 23:09:05 +0100 Subject: [PATCH 9/9] changes requested --- include/util/rfkill.hpp | 3 +-- man/waybar-bluetooth.5.scd | 2 +- src/modules/network.cpp | 1 - src/util/rfkill.cpp | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/util/rfkill.hpp b/include/util/rfkill.hpp index 67a9807..5dbf3ce 100644 --- a/include/util/rfkill.hpp +++ b/include/util/rfkill.hpp @@ -9,12 +9,11 @@ class Rfkill { Rfkill(enum rfkill_type rfkill_type); ~Rfkill() = default; void waitForEvent(); - int getState() const; + bool getState() const; private: enum rfkill_type rfkill_type_; int state_ = 0; - int prev_state_ = 0; }; } // namespace waybar::util diff --git a/man/waybar-bluetooth.5.scd b/man/waybar-bluetooth.5.scd index 7f6876b..a07e544 100644 --- a/man/waybar-bluetooth.5.scd +++ b/man/waybar-bluetooth.5.scd @@ -15,7 +15,7 @@ Addressed by *bluetooth* *interval*: ++ typeof: integer ++ default: 60 ++ - The interval in which the network information gets polled (e.g. signal strength). + The interval in which the bluetooth state gets updated. *format*: ++ typeof: string ++ diff --git a/src/modules/network.cpp b/src/modules/network.cpp index b993f2c..0cf16c0 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "util/format.hpp" #include "util/rfkill.hpp" diff --git a/src/util/rfkill.cpp b/src/util/rfkill.cpp index 2d5ad7f..df77598 100644 --- a/src/util/rfkill.cpp +++ b/src/util/rfkill.cpp @@ -78,6 +78,6 @@ void waybar::util::Rfkill::waitForEvent() { } -int waybar::util::Rfkill::getState() const { +bool waybar::util::Rfkill::getState() const { return state_; }