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,19 +98,21 @@ 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(), "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_signal_connect(manager_.get(), "interface-proxy-properties-changed",
 | 
				
			||||||
                   G_CALLBACK(onInterfaceProxyPropertiesChanged), this);
 | 
					                   G_CALLBACK(onInterfaceProxyPropertiesChanged), this);
 | 
				
			||||||
  g_signal_connect(manager_.get(), "interface-added", G_CALLBACK(onInterfaceAddedOrRemoved),
 | 
					  g_signal_connect(manager_.get(), "interface-added", G_CALLBACK(onInterfaceAddedOrRemoved),
 | 
				
			||||||
| 
						 | 
					@ -121,7 +123,6 @@ waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value&
 | 
				
			||||||
#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,6 +328,7 @@ 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);
 | 
				
			||||||
 | 
					    if (bt->cur_controller_.has_value()) {
 | 
				
			||||||
      auto device = std::find_if(bt->connected_devices_.begin(), bt->connected_devices_.end(),
 | 
					      auto device = std::find_if(bt->connected_devices_.begin(), bt->connected_devices_.end(),
 | 
				
			||||||
                                 [object_path](auto d) { return d.path == object_path; });
 | 
					                                 [object_path](auto d) { return d.path == object_path; });
 | 
				
			||||||
      if (device != bt->connected_devices_.end()) {
 | 
					      if (device != bt->connected_devices_.end()) {
 | 
				
			||||||
| 
						 | 
					@ -299,6 +336,7 @@ auto waybar::modules::Bluetooth::onInterfaceAddedOrRemoved(GDBusObjectManager* m
 | 
				
			||||||
        bt->dp.emit();
 | 
					        bt->dp.emit();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto waybar::modules::Bluetooth::onInterfaceProxyPropertiesChanged(
 | 
					auto waybar::modules::Bluetooth::onInterfaceProxyPropertiesChanged(
 | 
				
			||||||
| 
						 | 
					@ -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