Add hotplug detection of bluetooth controllers
This commit is contained in:
parent
79a6229522
commit
ab91d0bac3
|
@ -49,6 +49,9 @@ class Bluetooth : public ALabel {
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static auto onObjectAdded(GDBusObjectManager*, GDBusObject*, gpointer) -> void;
|
||||||
|
static auto onObjectRemoved(GDBusObjectManager*, GDBusObject*, gpointer) -> void;
|
||||||
|
|
||||||
static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*,
|
static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*,
|
||||||
gpointer) -> void;
|
gpointer) -> void;
|
||||||
static auto onInterfaceProxyPropertiesChanged(GDBusObjectManagerClient*, GDBusObjectProxy*,
|
static auto onInterfaceProxyPropertiesChanged(GDBusObjectManagerClient*, GDBusObjectProxy*,
|
||||||
|
|
|
@ -98,30 +98,31 @@ 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 selected stays unchanged
|
|
||||||
// for duration of the module
|
|
||||||
if (cur_controller_ = 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::warn("no bluetooth controller found with alias '{}'",
|
||||||
config_["controller-alias"].asString());
|
config_["controller-alias"].asString());
|
||||||
} else {
|
} else {
|
||||||
spdlog::error("findCurController() failed: no bluetooth controller found");
|
spdlog::warn("no bluetooth controller found");
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
// These calls only make sense if a controller could be found
|
// This call only make sense if a controller could be found
|
||||||
findConnectedDevices(cur_controller_->path, connected_devices_);
|
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),
|
g_signal_connect(manager_.get(), "object-added", G_CALLBACK(onObjectAdded), this);
|
||||||
this);
|
g_signal_connect(manager_.get(), "object-removed", G_CALLBACK(onObjectRemoved), this);
|
||||||
g_signal_connect(manager_.get(), "interface-removed", G_CALLBACK(onInterfaceAddedOrRemoved),
|
g_signal_connect(manager_.get(), "interface-proxy-properties-changed",
|
||||||
this);
|
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
|
||||||
}
|
|
||||||
|
|
||||||
dp.emit();
|
dp.emit();
|
||||||
}
|
}
|
||||||
|
@ -282,6 +283,41 @@ auto waybar::modules::Bluetooth::update() -> void {
|
||||||
ALabel::update();
|
ALabel::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::Bluetooth::onObjectAdded(GDBusObjectManager* manager,
|
||||||
|
GDBusObject* object,
|
||||||
|
gpointer user_data) -> void {
|
||||||
|
ControllerInfo info;
|
||||||
|
Bluetooth* bt = static_cast<Bluetooth*>(user_data);
|
||||||
|
|
||||||
|
if (!bt->cur_controller_.has_value() &&
|
||||||
|
bt->getControllerProperties(object, info) &&
|
||||||
|
(!bt->config_["controller-alias"].isString() ||
|
||||||
|
bt->config_["controller-alias"].asString() == info.alias)) {
|
||||||
|
bt->cur_controller_ = std::move(info);
|
||||||
|
bt->dp.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::Bluetooth::onObjectRemoved(GDBusObjectManager* manager,
|
||||||
|
GDBusObject* object,
|
||||||
|
gpointer user_data) -> void {
|
||||||
|
GDBusProxy* proxy_controller =
|
||||||
|
G_DBUS_PROXY(g_dbus_object_get_interface(object, "org.bluez.Adapter1"));
|
||||||
|
|
||||||
|
if (proxy_controller != NULL) {
|
||||||
|
|
||||||
|
std::string object_path = g_dbus_object_get_object_path(object);
|
||||||
|
Bluetooth* bt = static_cast<Bluetooth*>(user_data);
|
||||||
|
|
||||||
|
if (object_path == bt->cur_controller_->path) {
|
||||||
|
bt->cur_controller_ = bt->findCurController();
|
||||||
|
bt->dp.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref(proxy_controller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: only for when the org.bluez.Battery1 interface is added/removed after/before a device is
|
// NOTE: only for when the org.bluez.Battery1 interface is added/removed after/before a device is
|
||||||
// connected/disconnected
|
// connected/disconnected
|
||||||
auto waybar::modules::Bluetooth::onInterfaceAddedOrRemoved(GDBusObjectManager* manager,
|
auto waybar::modules::Bluetooth::onInterfaceAddedOrRemoved(GDBusObjectManager* manager,
|
||||||
|
@ -292,11 +328,13 @@ auto waybar::modules::Bluetooth::onInterfaceAddedOrRemoved(GDBusObjectManager* m
|
||||||
std::string object_path = g_dbus_proxy_get_object_path(G_DBUS_PROXY(interface));
|
std::string object_path = g_dbus_proxy_get_object_path(G_DBUS_PROXY(interface));
|
||||||
if (interface_name == "org.bluez.Battery1") {
|
if (interface_name == "org.bluez.Battery1") {
|
||||||
Bluetooth* bt = static_cast<Bluetooth*>(user_data);
|
Bluetooth* bt = static_cast<Bluetooth*>(user_data);
|
||||||
auto device = std::find_if(bt->connected_devices_.begin(), bt->connected_devices_.end(),
|
if (bt->cur_controller_.has_value()) {
|
||||||
[object_path](auto d) { return d.path == object_path; });
|
auto device = std::find_if(bt->connected_devices_.begin(), bt->connected_devices_.end(),
|
||||||
if (device != bt->connected_devices_.end()) {
|
[object_path](auto d) { return d.path == object_path; });
|
||||||
device->battery_percentage = bt->getDeviceBatteryPercentage(object);
|
if (device != bt->connected_devices_.end()) {
|
||||||
bt->dp.emit();
|
device->battery_percentage = bt->getDeviceBatteryPercentage(object);
|
||||||
|
bt->dp.emit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,6 +347,11 @@ auto waybar::modules::Bluetooth::onInterfaceProxyPropertiesChanged(
|
||||||
std::string object_path = g_dbus_object_get_object_path(G_DBUS_OBJECT(object_proxy));
|
std::string object_path = g_dbus_object_get_object_path(G_DBUS_OBJECT(object_proxy));
|
||||||
|
|
||||||
Bluetooth* bt = static_cast<Bluetooth*>(user_data);
|
Bluetooth* bt = static_cast<Bluetooth*>(user_data);
|
||||||
|
|
||||||
|
if (!bt->cur_controller_.has_value()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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_);
|
||||||
|
|
Loading…
Reference in New Issue