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;
 | 
			
		||||
 | 
			
		||||
 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,19 +98,21 @@ 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(), "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),
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +123,6 @@ waybar::modules::Bluetooth::Bluetooth(const std::string& id, const Json::Value&
 | 
			
		|||
#ifdef WANT_RFKILL
 | 
			
		||||
  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,6 +328,7 @@ 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);
 | 
			
		||||
    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()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -300,6 +337,7 @@ auto waybar::modules::Bluetooth::onInterfaceAddedOrRemoved(GDBusObjectManager* m
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
auto waybar::modules::Bluetooth::onInterfaceProxyPropertiesChanged(
 | 
			
		||||
    GDBusObjectManagerClient* manager, GDBusObjectProxy* object_proxy, GDBusProxy* interface_proxy,
 | 
			
		||||
| 
						 | 
				
			
			@ -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