From c94295ae1cfa9e7f22f7423070b31312c11b5ea8 Mon Sep 17 00:00:00 2001 From: Tim Gromeyer Date: Tue, 15 Apr 2025 19:55:40 +0200 Subject: [PATCH] Reset GUI when airpods disconnect, show notification --- linux/battery.hpp | 6 ++++++ linux/main.cpp | 32 ++++++++++++++++++++++++++++++-- linux/mediacontroller.cpp | 9 +++++++-- linux/trayiconmanager.cpp | 21 ++++++++++++++++++--- linux/trayiconmanager.h | 2 ++ 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/linux/battery.hpp b/linux/battery.hpp index 4bd45a1..6211901 100644 --- a/linux/battery.hpp +++ b/linux/battery.hpp @@ -21,11 +21,17 @@ class Battery : public QObject public: explicit Battery(QObject *parent = nullptr) : QObject(parent) + { + reset(); + } + + void reset() { // Initialize all components to unknown state states[Component::Left] = {}; states[Component::Right] = {}; states[Component::Case] = {}; + emit batteryStatusChanged(); } // Enum for AirPods components diff --git a/linux/main.cpp b/linux/main.cpp index be1284e..f04db4c 100644 --- a/linux/main.cpp +++ b/linux/main.cpp @@ -366,13 +366,41 @@ private slots: LOG_DEBUG("AIRPODS_DISCONNECTED packet written: " << AirPodsPackets::Connection::AIRPODS_DISCONNECTED.toHex()); } - mediaController->pause(); + mediaController->pause(); // Since the device is deconnected, we don't know if it was the active output device. Pause to be safe discoveryAgent->start(); + + // Show system notification + trayManager->showNotification( + tr("AirPods Disconnected"), + tr("Your AirPods have been disconnected")); } void bluezDeviceDisconnected(const QString &address) { - if (address == connectedDeviceMacAddress.replace("_", ":")) { + if (address == connectedDeviceMacAddress.replace("_", ":")) + { onDeviceDisconnected(QBluetoothAddress(address)); + + // Clear the device name and model + m_deviceName.clear(); + m_model = AirPodsModel::Unknown; + emit deviceNameChanged(m_deviceName); + emit modelChanged(); + + // Reset battery status + m_battery->reset(); + m_batteryStatus.clear(); + emit batteryStatusChanged(m_batteryStatus); + + // Reset ear detection + m_earDetectionStatus.clear(); + m_primaryInEar = false; + m_secoundaryInEar = false; + emit earDetectionStatusChanged(m_earDetectionStatus); + emit primaryChanged(); + + // Reset noise control mode + m_noiseControlMode = NoiseControlMode::Off; + emit noiseControlModeChanged(m_noiseControlMode); } else { LOG_WARN("Disconnected device does not match connected device: " << address << " != " << connectedDeviceMacAddress); diff --git a/linux/mediacontroller.cpp b/linux/mediacontroller.cpp index 9926a1e..d3ceb26 100644 --- a/linux/mediacontroller.cpp +++ b/linux/mediacontroller.cpp @@ -39,9 +39,14 @@ void MediaController::initializeMprisInterface() { } void MediaController::handleEarDetection(const QString &status) { + bool primaryInEar = false; + bool secondaryInEar = false; + QStringList parts = status.split(", "); - bool primaryInEar = parts[0].contains("In Ear"); - bool secondaryInEar = parts[1].contains("In Ear"); + if (parts.size() == 2) { + primaryInEar = parts[0].contains("In Ear"); + secondaryInEar = parts[1].contains("In Ear"); + } LOG_DEBUG("Ear detection status: primaryInEar=" << primaryInEar << ", secondaryInEar=" << secondaryInEar diff --git a/linux/trayiconmanager.cpp b/linux/trayiconmanager.cpp index 629288e..ca62087 100644 --- a/linux/trayiconmanager.cpp +++ b/linux/trayiconmanager.cpp @@ -27,6 +27,11 @@ TrayIconManager::TrayIconManager(QObject *parent) : QObject(parent) trayIcon->show(); } +void TrayIconManager::showNotification(const QString &title, const QString &message) +{ + trayIcon->showMessage(title, message, QSystemTrayIcon::Information, 3000); +} + void TrayIconManager::TrayIconManager::updateBatteryStatus(const QString &status) { trayIcon->setToolTip("Battery Status: " + status); @@ -83,10 +88,20 @@ void TrayIconManager::setupMenuActions() void TrayIconManager::updateIconFromBattery(const QString &status) { - QStringList parts = status.split(", "); - int leftLevel = parts[0].split(": ")[1].replace("%", "").toInt(); - int rightLevel = parts[1].split(": ")[1].replace("%", "").toInt(); + int leftLevel = 0; + int rightLevel = 0; + if (!status.isEmpty()) + { + // Parse the battery status string + QStringList parts = status.split(", "); + if (parts.size() >= 2) + { + leftLevel = parts[0].split(": ")[1].replace("%", "").toInt(); + rightLevel = parts[1].split(": ")[1].replace("%", "").toInt(); + } + } + int minLevel = (leftLevel == 0) ? rightLevel : (rightLevel == 0) ? leftLevel : qMin(leftLevel, rightLevel); diff --git a/linux/trayiconmanager.h b/linux/trayiconmanager.h index 89c1003..ac27b35 100644 --- a/linux/trayiconmanager.h +++ b/linux/trayiconmanager.h @@ -20,6 +20,8 @@ public: void updateConversationalAwareness(bool enabled); + void showNotification(const QString &title, const QString &message); + private slots: void onTrayIconActivated(QSystemTrayIcon::ActivationReason reason);