diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index c384aaa..2291312 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -34,6 +34,7 @@ qt_add_executable(librepods eardetection.hpp media/playerstatuswatcher.cpp media/playerstatuswatcher.h + systemsleepmonitor.hpp ) qt_add_qml_module(librepods diff --git a/linux/ble/blemanager.cpp b/linux/ble/blemanager.cpp index 3da8767..d75a2a6 100644 --- a/linux/ble/blemanager.cpp +++ b/linux/ble/blemanager.cpp @@ -112,6 +112,11 @@ void BleManager::stopScan() discoveryAgent->stop(); } +bool BleManager::isScanning() const +{ + return discoveryAgent->isActive(); +} + void BleManager::onDeviceDiscovered(const QBluetoothDeviceInfo &info) { // Check for Apple's manufacturer ID (0x004C) diff --git a/linux/ble/blemanager.h b/linux/ble/blemanager.h index df61785..7a4a68a 100644 --- a/linux/ble/blemanager.h +++ b/linux/ble/blemanager.h @@ -72,6 +72,7 @@ public: void startScan(); void stopScan(); + bool isScanning() const; private slots: void onDeviceDiscovered(const QBluetoothDeviceInfo &info); diff --git a/linux/main.cpp b/linux/main.cpp index d118890..be9a8dc 100644 --- a/linux/main.cpp +++ b/linux/main.cpp @@ -24,6 +24,7 @@ #include "ble/blemanager.h" #include "ble/bleutils.h" #include "QRCodeImageProvider.hpp" +#include "systemsleepmonitor.hpp" using namespace AirpodsTrayApp::Enums; @@ -45,6 +46,7 @@ public: : QObject(parent), debugMode(debugMode), m_settings(new QSettings("AirPodsTrayApp", "AirPodsTrayApp")) , m_autoStartManager(new AutoStartManager(this)), m_hideOnStart(hideOnStart), parent(parent) , m_deviceInfo(new DeviceInfo(this)), m_bleManager(new BleManager(this)) + , m_systemSleepMonitor(new SystemSleepMonitor(this)) { QLoggingCategory::setFilterRules(QString("airpodsApp.debug=%1").arg(debugMode ? "true" : "false")); LOG_INFO("Initializing AirPodsTrayApp"); @@ -74,6 +76,8 @@ public: connect(m_bleManager, &BleManager::deviceFound, this, &AirPodsTrayApp::bleDeviceFound); connect(m_deviceInfo->getBattery(), &Battery::primaryChanged, this, &AirPodsTrayApp::primaryChanged); + connect(m_systemSleepMonitor, &SystemSleepMonitor::systemGoingToSleep, this, &AirPodsTrayApp::onSystemGoingToSleep); + connect(m_systemSleepMonitor, &SystemSleepMonitor::systemWakingUp, this, &AirPodsTrayApp::onSystemWakingUp); // Load settings CrossDevice.isEnabled = loadCrossDeviceEnabled(); @@ -333,6 +337,20 @@ public slots: int loadRetryAttempts() const { return m_settings->value("bluetooth/retryAttempts", 3).toInt(); } void saveRetryAttempts(int attempts) { m_settings->setValue("bluetooth/retryAttempts", attempts); } + void onSystemGoingToSleep() + { + if (m_bleManager->isScanning()) + { + LOG_INFO("Stopping BLE scan before going to sleep"); + m_bleManager->stopScan(); + } + } + void onSystemWakingUp() + { + LOG_INFO("System is waking up, starting ble scan"); + m_bleManager->startScan(); + } + private slots: void onTrayIconActivated() { @@ -851,6 +869,7 @@ private: bool m_hideOnStart = false; DeviceInfo *m_deviceInfo; BleManager *m_bleManager; + SystemSleepMonitor *m_systemSleepMonitor = nullptr; }; int main(int argc, char *argv[]) { diff --git a/linux/systemsleepmonitor.hpp b/linux/systemsleepmonitor.hpp new file mode 100644 index 0000000..22ed3e1 --- /dev/null +++ b/linux/systemsleepmonitor.hpp @@ -0,0 +1,49 @@ +#ifndef SYSTEMSLEEPMONITOR_HPP +#define SYSTEMSLEEPMONITOR_HPP + +#include +#include +#include +#include +#include + +class SystemSleepMonitor : public QObject { + Q_OBJECT + +public: + explicit SystemSleepMonitor(QObject *parent = nullptr) : QObject(parent) { + // Connect to the system D-Bus + QDBusConnection systemBus = QDBusConnection::systemBus(); + if (!systemBus.isConnected()) { + qWarning() << "Cannot connect to system D-Bus"; + return; + } + + // Subscribe to PrepareForSleep signal from logind + systemBus.connect( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "PrepareForSleep", + this, + SLOT(handlePrepareForSleep(bool)) + ); + } + + ~SystemSleepMonitor() override = default; + +signals: + void systemGoingToSleep(); + void systemWakingUp(); + +private slots: + void handlePrepareForSleep(bool sleeping) { + if (sleeping) { + emit systemGoingToSleep(); + } else { + emit systemWakingUp(); + } + } +}; + +#endif // SYSTEMSLEEPMONITOR_HPP \ No newline at end of file