Merge pull request #3360 from lukasfink1/bt-dyn-controller-pr
Add hotplug detection of bluetooth controllers
This commit is contained in:
		
						commit
						3f49725834
					
				|  | @ -49,6 +49,9 @@ class Bluetooth : public ALabel { | |||
|   auto update() -> void override; | ||||
| 
 | ||||
|  private: | ||||
|   static auto onObjectAdded(GDBusObjectManager*, GDBusObject*, gpointer) -> void; | ||||
|   static auto onObjectRemoved(GDBusObjectManager*, GDBusObject*, gpointer) -> void; | ||||
| 
 | ||||
|   static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*, | ||||
|                                         gpointer) -> void; | ||||
|   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(); }); | ||||
|   } | ||||
| 
 | ||||
|   // NOTE: assumption made that the controller that is selected stays unchanged
 | ||||
|   // for duration of the module
 | ||||
|   if (cur_controller_ = findCurController(); !cur_controller_) { | ||||
|     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()); | ||||
|     } else { | ||||
|       spdlog::error("findCurController() failed: no bluetooth controller found"); | ||||
|       spdlog::warn("no bluetooth controller found"); | ||||
|     } | ||||
|     update(); | ||||
|   } 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_); | ||||
|     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(), "object-added", G_CALLBACK(onObjectAdded), this); | ||||
|   g_signal_connect(manager_.get(), "object-removed", G_CALLBACK(onObjectRemoved), 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 | ||||
|     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 | ||||
|   } | ||||
| 
 | ||||
|   dp.emit(); | ||||
| } | ||||
|  | @ -282,6 +283,41 @@ auto waybar::modules::Bluetooth::update() -> void { | |||
|   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
 | ||||
| // connected/disconnected
 | ||||
| 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)); | ||||
|   if (interface_name == "org.bluez.Battery1") { | ||||
|     Bluetooth* bt = static_cast<Bluetooth*>(user_data); | ||||
|     auto device = std::find_if(bt->connected_devices_.begin(), bt->connected_devices_.end(), | ||||
|                                [object_path](auto d) { return d.path == object_path; }); | ||||
|     if (device != bt->connected_devices_.end()) { | ||||
|       device->battery_percentage = bt->getDeviceBatteryPercentage(object); | ||||
|       bt->dp.emit(); | ||||
|     if (bt->cur_controller_.has_value()) { | ||||
|       auto device = std::find_if(bt->connected_devices_.begin(), bt->connected_devices_.end(), | ||||
|                                  [object_path](auto d) { return d.path == object_path; }); | ||||
|       if (device != bt->connected_devices_.end()) { | ||||
|         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)); | ||||
| 
 | ||||
|   Bluetooth* bt = static_cast<Bluetooth*>(user_data); | ||||
| 
 | ||||
|   if (!bt->cur_controller_.has_value()) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   if (interface_name == "org.bluez.Adapter1") { | ||||
|     if (object_path == bt->cur_controller_->path) { | ||||
|       bt->getControllerProperties(G_DBUS_OBJECT(object_proxy), *bt->cur_controller_); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue