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] 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; -}