Add no-controller format to bluetooth module

This commit is contained in:
PucklaJ 2023-08-16 15:34:06 +02:00
parent e30fba0b8f
commit 22817089db
3 changed files with 54 additions and 34 deletions

View File

@ -59,7 +59,8 @@ class Bluetooth : public ALabel {
auto getDeviceProperties(GDBusObject*, DeviceInfo&) -> bool; auto getDeviceProperties(GDBusObject*, DeviceInfo&) -> bool;
auto getControllerProperties(GDBusObject*, ControllerInfo&) -> bool; auto getControllerProperties(GDBusObject*, ControllerInfo&) -> bool;
auto findCurController(ControllerInfo&) -> bool; // Returns std::nullopt if no controller could be found
auto findCurController() -> std::optional<ControllerInfo>;
auto findConnectedDevices(const std::string&, std::vector<DeviceInfo>&) -> void; auto findConnectedDevices(const std::string&, std::vector<DeviceInfo>&) -> void;
#ifdef WANT_RFKILL #ifdef WANT_RFKILL
@ -68,7 +69,7 @@ class Bluetooth : public ALabel {
const std::unique_ptr<GDBusObjectManager, void (*)(GDBusObjectManager*)> manager_; const std::unique_ptr<GDBusObjectManager, void (*)(GDBusObjectManager*)> manager_;
std::string state_; std::string state_;
ControllerInfo cur_controller_; std::optional<ControllerInfo> cur_controller_;
std::vector<DeviceInfo> connected_devices_; std::vector<DeviceInfo> connected_devices_;
DeviceInfo cur_focussed_device_; DeviceInfo cur_focussed_device_;
std::string device_enumerate_; std::string device_enumerate_;

View File

@ -42,6 +42,10 @@ Addressed by *bluetooth*
typeof: string ++ typeof: string ++
This format is used when the displayed controller is connected to at least 1 device. This format is used when the displayed controller is connected to at least 1 device.
*format-no-controller*: ++
typeof: string ++
This format is used when no bluetooth controller could be found
*format-icons*: ++ *format-icons*: ++
typeof: array/object ++ typeof: array/object ++
Based on the current battery percentage (see section *EXPERIMENTAL BATTERY PERCENTAGE FEATURE*), the corresponding icon gets selected. ++ Based on the current battery percentage (see section *EXPERIMENTAL BATTERY PERCENTAGE FEATURE*), the corresponding icon gets selected. ++
@ -113,6 +117,10 @@ Addressed by *bluetooth*
typeof: string ++ typeof: string ++
This format is used when the displayed controller is connected to at least 1 device. This format is used when the displayed controller is connected to at least 1 device.
*tooltip-format-no-controller*: ++
typeof: string ++
This format is used when no bluetooth controller could be found
*tooltip-format-enumerate-connected*: ++ *tooltip-format-enumerate-connected*: ++
typeof: string ++ typeof: string ++
This format is used to define how each connected device should be displayed within the *device_enumerate* format replacement in the tooltip menu. This format is used to define how each connected device should be displayed within the *device_enumerate* format replacement in the tooltip menu.

View File

@ -92,9 +92,9 @@ waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value&
std::back_inserter(device_preference_), [](auto x) { return x.asString(); }); std::back_inserter(device_preference_), [](auto x) { return x.asString(); });
} }
// NOTE: assumption made that the controller that is selcected stays unchanged // NOTE: assumption made that the controller that is selected stays unchanged
// for duration of the module // for duration of the module
if (!findCurController(cur_controller_)) { if (cur_controller_ = findCurController(); !cur_controller_) {
if (config_["controller-alias"].isString()) { if (config_["controller-alias"].isString()) {
spdlog::error("findCurController() failed: no bluetooth controller found with alias '{}'", spdlog::error("findCurController() failed: no bluetooth controller found with alias '{}'",
config_["controller-alias"].asString()); config_["controller-alias"].asString());
@ -102,15 +102,20 @@ waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value&
spdlog::error("findCurController() failed: no bluetooth controller found"); spdlog::error("findCurController() failed: no bluetooth controller found");
} }
event_box_.hide(); event_box_.hide();
update();
return; return;
} }
findConnectedDevices(cur_controller_.path, connected_devices_); if (cur_controller_) {
// These calls only make sense if a controller could be found
findConnectedDevices(cur_controller_->path, connected_devices_);
g_signal_connect(manager_.get(), "interface-proxy-properties-changed",
G_CALLBACK(onInterfaceProxyPropertiesChanged), this);
g_signal_connect(manager_.get(), "interface-added", G_CALLBACK(onInterfaceAddedOrRemoved),
this);
g_signal_connect(manager_.get(), "interface-removed", G_CALLBACK(onInterfaceAddedOrRemoved),
this);
}
g_signal_connect(manager_.get(), "interface-proxy-properties-changed",
G_CALLBACK(onInterfaceProxyPropertiesChanged), this);
g_signal_connect(manager_.get(), "interface-added", G_CALLBACK(onInterfaceAddedOrRemoved), this);
g_signal_connect(manager_.get(), "interface-removed", G_CALLBACK(onInterfaceAddedOrRemoved),
this);
#ifdef WANT_RFKILL #ifdef WANT_RFKILL
rfkill_.on_update.connect(sigc::hide(sigc::mem_fun(*this, &Bluetooth::update))); rfkill_.on_update.connect(sigc::hide(sigc::mem_fun(*this, &Bluetooth::update)));
#endif #endif
@ -144,12 +149,16 @@ auto waybar::modules::Bluetooth::update() -> void {
std::string state; std::string state;
std::string tooltip_format; std::string tooltip_format;
if (!cur_controller_.powered) if (cur_controller_) {
state = "off"; if (!cur_controller_->powered)
else if (!connected_devices_.empty()) state = "off";
state = "connected"; else if (!connected_devices_.empty())
else state = "connected";
state = "on"; else
state = "on";
} else {
state = "no-controller";
}
#ifdef WANT_RFKILL #ifdef WANT_RFKILL
if (rfkill_.getState()) state = "disabled"; if (rfkill_.getState()) state = "disabled";
#endif #endif
@ -196,9 +205,9 @@ auto waybar::modules::Bluetooth::update() -> void {
label_.get_style_context()->remove_class(style_class); label_.get_style_context()->remove_class(style_class);
} }
}; };
update_style_context("discoverable", cur_controller_.discoverable); update_style_context("discoverable", cur_controller_ ? cur_controller_->discoverable : false);
update_style_context("discovering", cur_controller_.discovering); update_style_context("discovering", cur_controller_ ? cur_controller_->discovering : false);
update_style_context("pairable", cur_controller_.pairable); update_style_context("pairable", cur_controller_ ? cur_controller_->pairable : false);
if (!state_.empty()) { if (!state_.empty()) {
update_style_context(state_, false); update_style_context(state_, false);
} }
@ -208,9 +217,9 @@ auto waybar::modules::Bluetooth::update() -> void {
label_.set_markup(fmt::format( label_.set_markup(fmt::format(
fmt::runtime(format_), fmt::arg("status", state_), fmt::runtime(format_), fmt::arg("status", state_),
fmt::arg("num_connections", connected_devices_.size()), fmt::arg("num_connections", connected_devices_.size()),
fmt::arg("controller_address", cur_controller_.address), fmt::arg("controller_address", cur_controller_ ? cur_controller_->address : "null"),
fmt::arg("controller_address_type", cur_controller_.address_type), fmt::arg("controller_address_type", cur_controller_ ? cur_controller_->address_type : "null"),
fmt::arg("controller_alias", cur_controller_.alias), fmt::arg("controller_alias", cur_controller_ ? cur_controller_->alias : "null"),
fmt::arg("device_address", cur_focussed_device_.address), fmt::arg("device_address", cur_focussed_device_.address),
fmt::arg("device_address_type", cur_focussed_device_.address_type), fmt::arg("device_address_type", cur_focussed_device_.address_type),
fmt::arg("device_alias", cur_focussed_device_.alias), fmt::arg("icon", icon_label), fmt::arg("device_alias", cur_focussed_device_.alias), fmt::arg("icon", icon_label),
@ -250,9 +259,10 @@ auto waybar::modules::Bluetooth::update() -> void {
label_.set_tooltip_text(fmt::format( label_.set_tooltip_text(fmt::format(
fmt::runtime(tooltip_format), fmt::arg("status", state_), fmt::runtime(tooltip_format), fmt::arg("status", state_),
fmt::arg("num_connections", connected_devices_.size()), fmt::arg("num_connections", connected_devices_.size()),
fmt::arg("controller_address", cur_controller_.address), fmt::arg("controller_address", cur_controller_ ? cur_controller_->address : "null"),
fmt::arg("controller_address_type", cur_controller_.address_type), fmt::arg("controller_address_type",
fmt::arg("controller_alias", cur_controller_.alias), cur_controller_ ? cur_controller_->address_type : "null"),
fmt::arg("controller_alias", cur_controller_ ? cur_controller_->alias : "null"),
fmt::arg("device_address", cur_focussed_device_.address), fmt::arg("device_address", cur_focussed_device_.address),
fmt::arg("device_address_type", cur_focussed_device_.address_type), fmt::arg("device_address_type", cur_focussed_device_.address_type),
fmt::arg("device_alias", cur_focussed_device_.alias), fmt::arg("icon", icon_tooltip), fmt::arg("device_alias", cur_focussed_device_.alias), fmt::arg("icon", icon_tooltip),
@ -292,8 +302,8 @@ auto waybar::modules::Bluetooth::onInterfaceProxyPropertiesChanged(
Bluetooth* bt = static_cast<Bluetooth*>(user_data); Bluetooth* bt = static_cast<Bluetooth*>(user_data);
if (interface_name == "org.bluez.Adapter1") { if (interface_name == "org.bluez.Adapter1") {
if (object_path == bt->cur_controller_.path) { if (object_path == bt->cur_controller_->path) {
bt->getControllerProperties(G_DBUS_OBJECT(object_proxy), bt->cur_controller_); bt->getControllerProperties(G_DBUS_OBJECT(object_proxy), *bt->cur_controller_);
bt->dp.emit(); bt->dp.emit();
} }
} else if (interface_name == "org.bluez.Device1" || interface_name == "org.bluez.Battery1") { } else if (interface_name == "org.bluez.Device1" || interface_name == "org.bluez.Battery1") {
@ -378,22 +388,23 @@ auto waybar::modules::Bluetooth::getControllerProperties(GDBusObject* object,
return false; return false;
} }
auto waybar::modules::Bluetooth::findCurController(ControllerInfo& controller_info) -> bool { auto waybar::modules::Bluetooth::findCurController() -> std::optional<ControllerInfo> {
bool found_controller = false; std::optional<ControllerInfo> controller_info;
GList* objects = g_dbus_object_manager_get_objects(manager_.get()); GList* objects = g_dbus_object_manager_get_objects(manager_.get());
for (GList* l = objects; l != NULL; l = l->next) { for (GList* l = objects; l != NULL; l = l->next) {
GDBusObject* object = G_DBUS_OBJECT(l->data); GDBusObject* object = G_DBUS_OBJECT(l->data);
if (getControllerProperties(object, controller_info) && ControllerInfo info;
if (getControllerProperties(object, info) &&
(!config_["controller-alias"].isString() || (!config_["controller-alias"].isString() ||
config_["controller-alias"].asString() == controller_info.alias)) { config_["controller-alias"].asString() == info.alias)) {
found_controller = true; controller_info = std::move(info);
break; break;
} }
} }
g_list_free_full(objects, g_object_unref); g_list_free_full(objects, g_object_unref);
return found_controller; return controller_info;
} }
auto waybar::modules::Bluetooth::findConnectedDevices(const std::string& cur_controller_path, auto waybar::modules::Bluetooth::findConnectedDevices(const std::string& cur_controller_path,
@ -404,7 +415,7 @@ auto waybar::modules::Bluetooth::findConnectedDevices(const std::string& cur_con
GDBusObject* object = G_DBUS_OBJECT(l->data); GDBusObject* object = G_DBUS_OBJECT(l->data);
DeviceInfo device; DeviceInfo device;
if (getDeviceProperties(object, device) && device.connected && if (getDeviceProperties(object, device) && device.connected &&
device.paired_controller == cur_controller_.path) { device.paired_controller == cur_controller_->path) {
connected_devices.push_back(device); connected_devices.push_back(device);
} }
} }