diff --git a/include/factory.hpp b/include/factory.hpp index 7d4d14e3..b14b9988 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/include/modules/bluetooth.hpp b/include/modules/bluetooth.hpp new file mode 100644 index 00000000..d0fdce8a --- /dev/null +++ b/include/modules/bluetooth.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include "ALabel.hpp" + +#include +#include "util/sleeper_thread.hpp" + +namespace waybar::modules { + +class Bluetooth : public ALabel { + public: + Bluetooth(const std::string&, const Json::Value&); + ~Bluetooth() = default; + auto update() -> void; + + private: + std::string status_; + util::SleeperThread thread_; +}; + +} // namespace waybar::modules diff --git a/include/modules/network.hpp b/include/modules/network.hpp index f0d2e8e7..91e4ddb2 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 new file mode 100644 index 00000000..f309b6fb --- /dev/null +++ b/include/util/rfkill.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace waybar::util::rfkill { + +bool isDisabled(enum rfkill_type rfkill_type); + +} // namespace waybar::util diff --git a/meson.build b/meson.build index a099ad2b..8f29d10c 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', @@ -96,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/factory.cpp b/src/factory.cpp index 8f7cea75..16a6903a 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]); } diff --git a/src/modules/bluetooth.cpp b/src/modules/bluetooth.cpp new file mode 100644 index 00000000..dff42cdb --- /dev/null +++ b/src/modules/bluetooth.cpp @@ -0,0 +1,41 @@ +#include "modules/bluetooth.hpp" +#include "util/rfkill.hpp" +#include + +#include + +waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value& config) + : 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 { + status_ = "enabled"; + if (waybar::util::rfkill::isDisabled(RFKILL_TYPE_BLUETOOTH)) { + status_ = "disabled"; + } else { + status_ = "enabled"; + } + + 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); + //} + //} +} diff --git a/src/modules/network.cpp b/src/modules/network.cpp index ec3b9be9..63e3be95 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -4,12 +4,8 @@ #include #include #include "util/format.hpp" - -#include -//#include -#include +#include "util/rfkill.hpp" #include -#include namespace { @@ -228,58 +224,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::rfkill::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 00000000..2b0e42da --- /dev/null +++ b/src/util/rfkill.cpp @@ -0,0 +1,49 @@ +#include "util/rfkill.hpp" +#include +#include +#include +#include +#include + +bool waybar::util::rfkill::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; +}