fix bar crashing on monitor add/remove

This commit is contained in:
2026-02-09 13:49:52 +01:00
parent a90d1c2f6c
commit e1217305a5
30 changed files with 1186 additions and 247 deletions

View File

@@ -0,0 +1,111 @@
#pragma once
#include <cstdint>
#include <giomm.h>
#include <map>
#include <memory>
#include <sigc++/sigc++.h>
#include <string>
#include <vector>
#include "connection/dbus/dbus.hpp"
struct BluetoothDevice {
std::string object_path;
std::string address;
std::string name;
std::string icon;
bool paired = false;
bool connected = false;
bool trusted = false;
int16_t rssi = 0;
};
class BluetoothController : public DbusConnection {
using PropertiesMap = std::map<Glib::ustring, Glib::VariantBase>;
public:
static std::shared_ptr<BluetoothController> getInstance() {
if (!instance) {
instance = std::shared_ptr<BluetoothController>(new BluetoothController());
}
return instance;
}
// Adapter control
void setPowered(bool powered);
bool isPowered() const;
// Discovery
void startDiscovery();
void stopDiscovery();
bool isDiscovering() const;
// Device actions (identified by object_path)
void pairDevice(const std::string &object_path);
void unpairDevice(const std::string &object_path);
void connectDevice(const std::string &object_path);
void disconnectDevice(const std::string &object_path);
void trustDevice(const std::string &object_path, bool trusted);
// Queries
std::vector<BluetoothDevice> getDevices() const;
std::vector<BluetoothDevice> getPairedDevices() const;
// Signals
sigc::signal<void(bool)> &signalPoweredChanged();
sigc::signal<void(bool)> &signalDiscoveringChanged();
sigc::signal<void(const BluetoothDevice &)> &signalDeviceAdded();
sigc::signal<void(const std::string &)> &signalDeviceRemoved();
sigc::signal<void(const BluetoothDevice &)> &signalDeviceChanged();
private:
BluetoothController();
inline static std::shared_ptr<BluetoothController> instance = nullptr;
bool m_powered = false;
bool m_discovering = false;
std::string m_adapter_path;
Glib::RefPtr<Gio::DBus::Proxy> m_adapter_proxy;
Glib::RefPtr<Gio::DBus::Proxy> m_object_manager_proxy;
std::map<std::string, BluetoothDevice> m_devices;
std::map<std::string, Glib::RefPtr<Gio::DBus::Proxy>> m_device_proxies;
sigc::signal<void(bool)> m_powered_signal;
sigc::signal<void(bool)> m_discovering_signal;
sigc::signal<void(const BluetoothDevice &)> m_device_added_signal;
sigc::signal<void(const std::string &)> m_device_removed_signal;
sigc::signal<void(const BluetoothDevice &)> m_device_changed_signal;
// Bus setup
void onBusConnected(const Glib::RefPtr<Gio::AsyncResult> &result);
void enumerateObjects();
void parseInterfaces(const std::string &object_path, const Glib::VariantBase &interfaces_var);
// ObjectManager signals
void onObjectManagerSignal(const Glib::ustring &sender_name,
const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters);
// Adapter
void setupAdapter(const std::string &path, const PropertiesMap &properties);
void onAdapterPropertiesChanged(const Gio::DBus::Proxy::MapChangedProperties &changed,
const std::vector<Glib::ustring> &invalidated);
// Devices
void addDevice(const std::string &path, const PropertiesMap &properties);
void removeDevice(const std::string &path);
void onDevicePropertiesChanged(const std::string &object_path,
const Gio::DBus::Proxy::MapChangedProperties &changed,
const std::vector<Glib::ustring> &invalidated);
// Helpers
static BluetoothDevice parseDeviceProperties(const std::string &path, const PropertiesMap &properties);
void setDbusProperty(const std::string &object_path,
const std::string &interface,
const std::string &property,
const Glib::VariantBase &value);
};

View File

@@ -14,6 +14,10 @@ class DbusConnection {
Gio::DBus::Connection::get(Gio::DBus::BusType::SESSION, callback);
}
void connect_system_async(const sigc::slot<void(const Glib::RefPtr<Gio::AsyncResult> &)> &callback) {
Gio::DBus::Connection::get(Gio::DBus::BusType::SYSTEM, callback);
}
static void ensure_gio_init() {
try {
Gio::init();

View File

@@ -4,6 +4,7 @@
#include <giomm.h>
#include <gtkmm.h>
#include <sigc++/sigc++.h>
#include <sys/stat.h>
#include "connection/dbus/dbus.hpp"
@@ -43,7 +44,17 @@ const Glib::ustring introspection_xml = R"(
class NotificationService : public DbusConnection {
public:
NotificationService() : notificationIdCounter(1) {
static std::shared_ptr<NotificationService> getInstance() {
if (NotificationService::instance == nullptr) {
NotificationService::instance = std::shared_ptr<NotificationService>(new NotificationService());
}
return NotificationService::instance;
}
void onBusAcquired(const Glib::RefPtr<Gio::DBus::Connection> &connection, const Glib::ustring &name);
private:
NotificationService() {
Gio::DBus::own_name(
Gio::DBus::BusType::SESSION,
"org.freedesktop.Notifications",
@@ -53,10 +64,9 @@ class NotificationService : public DbusConnection {
Gio::DBus::BusNameOwnerFlags::REPLACE);
}
void onBusAcquired(const Glib::RefPtr<Gio::DBus::Connection> &connection, const Glib::ustring &name);
static inline std::shared_ptr<NotificationService> instance = nullptr;
private:
guint notificationIdCounter;
guint notificationIdCounter = 0;
const Gio::DBus::InterfaceVTable &getMessageInterfaceVTable();
void on_method_call(const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender,