make bluetooth service singleton

This commit is contained in:
2025-12-23 19:57:52 +01:00
parent 8613024f8d
commit a06c96f648
14 changed files with 148 additions and 65 deletions

View File

@@ -32,7 +32,7 @@ App::App() {
auto bar = new Bar(monitor->gobj(), this->hyprlandService,
this->trayService, this->bluetoothService, hyprlandMonitor->id);
this->trayService, hyprlandMonitor->id);
bar->set_application(app);
bar->show();

View File

@@ -17,8 +17,8 @@
#include "sigc++/functors/mem_fun.h"
Bar::Bar(GdkMonitor *monitor, HyprlandService &hyprlandService,
TrayService &trayService, BluetoothService &bluetoothService, int monitorId)
: hyprlandService(hyprlandService), trayService(trayService), bluetoothService(bluetoothService),
TrayService &trayService, int monitorId)
: hyprlandService(hyprlandService), trayService(trayService),
monitorId(monitorId) {
set_name("bar-window");
@@ -40,19 +40,7 @@ Bar::Bar(GdkMonitor *monitor, HyprlandService &hyprlandService,
this->volumeWidget = Gtk::make_managed<VolumeWidget>();
this->workspaceIndicator = Gtk::make_managed<WorkspaceIndicator>(hyprlandService, monitorId);
this->trayWidget = Gtk::make_managed<TrayWidget>(trayService);
this->bluetoothWidget = Gtk::make_managed<BluetoothWidget>("\ue8bb", "Bluetooth");
bluetoothService.powerStateChangedSignal.connect(
sigc::mem_fun(*this->bluetoothWidget, &BluetoothWidget::setPowerState));
bluetoothWidget->onPowerStateButtonClickedSignal.connect(
sigc::mem_fun(bluetoothService, &BluetoothService::togglePowerState));
bluetoothWidget->setPowerState(bluetoothService.getPowerState());
bluetoothService.isDiscoveringChangedSignal.connect(
sigc::mem_fun(*this->bluetoothWidget, &BluetoothWidget::setIsDiscovering));
bluetoothWidget->onIsDiscoveringButtonClickedSignal.connect(
sigc::mem_fun(bluetoothService, &BluetoothService::toggleIsDiscovering));
bluetoothWidget->setIsDiscovering(bluetoothService.getIsDiscovering());
load_css();
setup_ui();
@@ -93,7 +81,7 @@ void Bar::setup_center_box() {
void Bar::setup_right_box() {
right_box.append(*this->trayWidget);
right_box.append(this->homeAssistant);
right_box.append(*this->bluetoothWidget);
right_box.append(this->controlCenter);
}
void Bar::load_css() {

View File

@@ -7,8 +7,7 @@ Popover::Popover(std::string icon, std::string name) {
auto label = Gtk::make_managed<Gtk::Label>(icon);
label->add_css_class("icon-label");
set_child(*label);
signal_clicked().connect(
sigc::mem_fun(*this, &Popover::on_toggle_window));
signal_clicked().connect(sigc::mem_fun(*this, &Popover::on_toggle_window));
popover = new Gtk::Popover();
popover->set_parent(*this);

View File

@@ -2,10 +2,14 @@
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include "glib.h"
#include "sigc++/signal.h"
BluetoothService *BluetoothService::instance = nullptr;
BluetoothService::BluetoothService() {
GError *error = nullptr;
@@ -164,6 +168,7 @@ void BluetoothService::onPropertyChanged(GDBusProxy *proxy,
if (g_variant_lookup(changed_properties, "Discovering", "b", &is_discovering)) {
this->isDiscovering = is_discovering;
isDiscoveringChangedSignal.emit(isDiscovering);
// getDeviceObjectPaths();
}
}
@@ -179,4 +184,61 @@ void BluetoothService::onPropertyChangedStatic(GDBusProxy *proxy,
std::cerr << "Error: BluetoothService instance is null in static callback." << std::endl;
assert(false);
}
}
std::vector<std::string> BluetoothService::getDeviceObjectPaths() {
std::vector<std::string> device_paths;
GError *error = nullptr;
GDBusConnection *connection = g_dbus_proxy_get_connection(this->adapter_proxy);
GVariant *reply = g_dbus_connection_call_sync(
connection,
"org.bluez",
"/",
"org.freedesktop.DBus.ObjectManager",
"GetManagedObjects",
nullptr,
G_VARIANT_TYPE("(a{oa{sa{sv}}})"),
G_DBUS_CALL_FLAGS_NONE,
-1,
nullptr,
&error);
if (error) {
std::cerr << "Error calling GetManagedObjects: " << error->message << std::endl;
g_error_free(error);
return device_paths;
}
if (!reply) {
return device_paths;
}
GVariant *objects = g_variant_get_child_value(reply, 0);
g_variant_unref(reply);
if (!objects) {
return device_paths;
}
GVariantIter iter;
g_variant_iter_init(&iter, objects);
const gchar *object_path = nullptr;
GVariant *interfaces = nullptr;
while (g_variant_iter_next(&iter, "{&o@a{sa{sv}}}", &object_path, &interfaces)) {
GVariant *device_props = nullptr;
if (g_variant_lookup(interfaces, "org.bluez.Device1", "@a{sv}", &device_props)) {
std::cout << "Found device: " << object_path << std::endl;
device_paths.emplace_back(object_path);
g_variant_unref(device_props);
}
g_variant_unref(interfaces);
interfaces = nullptr;
}
g_variant_unref(objects);
return device_paths;
}

View File

@@ -1,17 +1,13 @@
#include "widgets/bluetooth.hpp"
BluetoothWidget::BluetoothWidget(std::string icon, std::string title) : Popover(icon, title) {
this->popover->set_size_request(100, -1);
set_popover_child(this->container);
this->container.set_orientation(Gtk::Orientation::VERTICAL);
this->container.set_spacing(10);
this->container.add_css_class("bluetooth-popover-container");
BluetoothWidget::BluetoothWidget() : Gtk::Box() {
this->set_orientation(Gtk::Orientation::VERTICAL);
this->add_css_class("bluetooth-popover-container");
this->statusArea.add_css_class("bluetooth-status-area");
this->statusArea.set_hexpand(true);
this->statusArea.set_halign(Gtk::Align::FILL);
this->container.append(this->statusArea);
this->append(this->statusArea);
this->powerButton = Gtk::make_managed<Gtk::Button>("\ue1a8");
this->powerButton->set_tooltip_text("Turn Bluetooth Off");
@@ -52,11 +48,11 @@ void BluetoothWidget::setPowerState(bool state) {
if (!state) {
this->scanButton->add_css_class("toggle-button-disabled");
this->add_css_class("disabled-popover-icon");
// this->add_css_class("disabled-popover-icon");
this->setIsDiscovering(false);
} else {
this->scanButton->remove_css_class("toggle-button-disabled");
this->remove_css_class("disabled-popover-icon");
// this->remove_css_class("disabled-popover-icon");
}
this->toggleButton(this->powerButton, state);

View File

@@ -0,0 +1,22 @@
#include "widgets/controlCenter.hpp"
ControlCenter::ControlCenter(std::string icon, std::string name)
: Popover(icon, name) {
this->popover->set_size_request(200, -1);
set_popover_child(this->container);
this->bluetoothWidget = Gtk::make_managed<BluetoothWidget>();
this->container.append(*this->bluetoothWidget);
bluetoothService->powerStateChangedSignal.connect(
sigc::mem_fun(*this->bluetoothWidget, &BluetoothWidget::setPowerState));
bluetoothWidget->onPowerStateButtonClickedSignal.connect(
sigc::mem_fun(*this->bluetoothService, &BluetoothService::togglePowerState));
bluetoothWidget->setPowerState(bluetoothService->getPowerState());
bluetoothService->isDiscoveringChangedSignal.connect(
sigc::mem_fun(*this->bluetoothWidget, &BluetoothWidget::setIsDiscovering));
bluetoothWidget->onIsDiscoveringButtonClickedSignal.connect(
sigc::mem_fun(*this->bluetoothService, &BluetoothService::toggleIsDiscovering));
bluetoothWidget->setIsDiscovering(bluetoothService->getIsDiscovering());
}

View File

@@ -9,7 +9,6 @@ TodoPopover::TodoPopover(std::string icon, std::string title) : Popover(icon, ti
this->popover->set_size_request(300, -1);
container.set_orientation(Gtk::Orientation::VERTICAL);
container.set_spacing(10);
container.add_css_class("todo-popover-container");
auto entry = Gtk::make_managed<Gtk::Entry>();