mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-04-26 16:17:49 +00:00
[Linux] Add reopen to tray options, enhance app tray, add ability to detect duplicate app instances, prevent duplicate app instances, and allow for original instance to be brought to front using the sockets
This commit is contained in:
@@ -9,9 +9,33 @@ ApplicationWindow {
|
|||||||
width: 400
|
width: 400
|
||||||
height: 300
|
height: 300
|
||||||
title: "AirPods Settings"
|
title: "AirPods Settings"
|
||||||
|
objectName: "mainWindowObject"
|
||||||
|
|
||||||
onClosing: mainWindow.visible = false
|
onClosing: mainWindow.visible = false
|
||||||
|
|
||||||
|
function reopen(pageToLoad) {
|
||||||
|
if (pageToLoad == "settings")
|
||||||
|
{
|
||||||
|
if (stackView.depth == 1)
|
||||||
|
{
|
||||||
|
stackView.push(settingsPage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (stackView.depth > 1)
|
||||||
|
{
|
||||||
|
stackView.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mainWindow.visible) {
|
||||||
|
mainWindow.visible = true
|
||||||
|
}
|
||||||
|
raise()
|
||||||
|
requestActivate()
|
||||||
|
}
|
||||||
|
|
||||||
// Mouse area for handling back/forward navigation
|
// Mouse area for handling back/forward navigation
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include <QLocalSocket>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "airpods_packets.h"
|
#include "airpods_packets.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
@@ -38,7 +39,7 @@ class AirPodsTrayApp : public QObject {
|
|||||||
Q_PROPERTY(bool hideOnStart READ hideOnStart CONSTANT)
|
Q_PROPERTY(bool hideOnStart READ hideOnStart CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AirPodsTrayApp(bool debugMode, bool hideOnStart, QObject *parent = nullptr)
|
AirPodsTrayApp(bool debugMode, bool hideOnStart, QQmlApplicationEngine *parent = nullptr)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, debugMode(debugMode)
|
, debugMode(debugMode)
|
||||||
, m_battery(new Battery(this))
|
, m_battery(new Battery(this))
|
||||||
@@ -46,6 +47,7 @@ public:
|
|||||||
, m_settings(new QSettings("AirPodsTrayApp", "AirPodsTrayApp"))
|
, m_settings(new QSettings("AirPodsTrayApp", "AirPodsTrayApp"))
|
||||||
, m_autoStartManager(new AutoStartManager(this))
|
, m_autoStartManager(new AutoStartManager(this))
|
||||||
, m_hideOnStart(hideOnStart)
|
, m_hideOnStart(hideOnStart)
|
||||||
|
, parent(parent)
|
||||||
{
|
{
|
||||||
if (debugMode) {
|
if (debugMode) {
|
||||||
QLoggingCategory::setFilterRules("airpodsApp.debug=true");
|
QLoggingCategory::setFilterRules("airpodsApp.debug=true");
|
||||||
@@ -58,6 +60,8 @@ public:
|
|||||||
trayManager = new TrayIconManager(this);
|
trayManager = new TrayIconManager(this);
|
||||||
trayManager->setNotificationsEnabled(loadNotificationsEnabled());
|
trayManager->setNotificationsEnabled(loadNotificationsEnabled());
|
||||||
connect(trayManager, &TrayIconManager::trayClicked, this, &AirPodsTrayApp::onTrayIconActivated);
|
connect(trayManager, &TrayIconManager::trayClicked, this, &AirPodsTrayApp::onTrayIconActivated);
|
||||||
|
connect(trayManager, &TrayIconManager::openApp, this, &AirPodsTrayApp::onOpenApp);
|
||||||
|
connect(trayManager, &TrayIconManager::openSettings, this, &AirPodsTrayApp::onOpenSettings);
|
||||||
connect(trayManager, &TrayIconManager::noiseControlChanged, this, qOverload<NoiseControlMode>(&AirPodsTrayApp::setNoiseControlMode));
|
connect(trayManager, &TrayIconManager::noiseControlChanged, this, qOverload<NoiseControlMode>(&AirPodsTrayApp::setNoiseControlMode));
|
||||||
connect(trayManager, &TrayIconManager::conversationalAwarenessToggled, this, &AirPodsTrayApp::setConversationalAwareness);
|
connect(trayManager, &TrayIconManager::conversationalAwarenessToggled, this, &AirPodsTrayApp::setConversationalAwareness);
|
||||||
connect(this, &AirPodsTrayApp::batteryStatusChanged, trayManager, &TrayIconManager::updateBatteryStatus);
|
connect(this, &AirPodsTrayApp::batteryStatusChanged, trayManager, &TrayIconManager::updateBatteryStatus);
|
||||||
@@ -146,6 +150,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool debugMode;
|
bool debugMode;
|
||||||
bool isConnectedLocally = false;
|
bool isConnectedLocally = false;
|
||||||
|
|
||||||
|
QQmlApplicationEngine *parent = nullptr;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool isAvailable = true;
|
bool isAvailable = true;
|
||||||
bool isEnabled = true; // Ability to disable the feature
|
bool isEnabled = true; // Ability to disable the feature
|
||||||
@@ -352,6 +359,30 @@ private slots:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onOpenApp()
|
||||||
|
{
|
||||||
|
QObject *rootObject = parent->rootObjects().first();
|
||||||
|
if (rootObject) {
|
||||||
|
QMetaObject::invokeMethod(rootObject, "reopen", Q_ARG(QVariant, "app"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parent->loadFromModule("linux", "Main");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onOpenSettings()
|
||||||
|
{
|
||||||
|
QObject *rootObject = parent->rootObjects().first();
|
||||||
|
if (rootObject) {
|
||||||
|
QMetaObject::invokeMethod(rootObject, "reopen", Q_ARG(QVariant, "settings"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parent->loadFromModule("linux", "Main");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sendHandshake() {
|
void sendHandshake() {
|
||||||
LOG_INFO("Connected to device, sending initial packets");
|
LOG_INFO("Connected to device, sending initial packets");
|
||||||
writePacketToSocket(AirPodsPackets::Connection::HANDSHAKE, "Handshake packet written: ");
|
writePacketToSocket(AirPodsPackets::Connection::HANDSHAKE, "Handshake packet written: ");
|
||||||
@@ -918,6 +949,25 @@ private:
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
// Check if app is already open
|
||||||
|
QSharedMemory sharedMemory;
|
||||||
|
sharedMemory.setKey("TcpServer-Key");
|
||||||
|
if(sharedMemory.create(1) == false)
|
||||||
|
{
|
||||||
|
LOG_INFO("Another instance already running! Opening App Window Instead");
|
||||||
|
QLocalSocket socket;
|
||||||
|
// Connect to the original app, then trigger the reopen signal
|
||||||
|
socket.connectToServer("app_server");
|
||||||
|
if (socket.waitForConnected(500)) {
|
||||||
|
socket.write("reopen");
|
||||||
|
socket.flush();
|
||||||
|
socket.waitForBytesWritten(500);
|
||||||
|
socket.disconnectFromServer();
|
||||||
|
}
|
||||||
|
app.exit(); // exit already a process running
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
app.setQuitOnLastWindowClosed(false);
|
app.setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
bool debugMode = false;
|
bool debugMode = false;
|
||||||
@@ -935,6 +985,30 @@ int main(int argc, char *argv[]) {
|
|||||||
AirPodsTrayApp *trayApp = new AirPodsTrayApp(debugMode, hideOnStart, &engine);
|
AirPodsTrayApp *trayApp = new AirPodsTrayApp(debugMode, hideOnStart, &engine);
|
||||||
engine.rootContext()->setContextProperty("airPodsTrayApp", trayApp);
|
engine.rootContext()->setContextProperty("airPodsTrayApp", trayApp);
|
||||||
engine.loadFromModule("linux", "Main");
|
engine.loadFromModule("linux", "Main");
|
||||||
|
|
||||||
|
QLocalServer server;
|
||||||
|
QLocalServer::removeServer("app_server");
|
||||||
|
|
||||||
|
server.listen("app_server");
|
||||||
|
QObject::connect(&server, &QLocalServer::newConnection, [&]() {
|
||||||
|
QLocalSocket* socket = server.nextPendingConnection();
|
||||||
|
QObject::connect(socket, &QLocalSocket::readyRead, [socket, &engine]() {
|
||||||
|
QString msg = socket->readAll();
|
||||||
|
// Check if the message is "reopen", if so, trigger onOpenApp function
|
||||||
|
if (msg == "reopen") {
|
||||||
|
LOG_INFO("Reopening app window");
|
||||||
|
QObject *rootObject = engine.rootObjects().first();
|
||||||
|
if (rootObject) {
|
||||||
|
QMetaObject::invokeMethod(rootObject, "reopen", Q_ARG(QVariant, "app"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
engine.loadFromModule("linux", "Main");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket->disconnectFromServer();
|
||||||
|
});
|
||||||
|
});
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,19 @@ void TrayIconManager::updateConversationalAwareness(bool enabled)
|
|||||||
|
|
||||||
void TrayIconManager::setupMenuActions()
|
void TrayIconManager::setupMenuActions()
|
||||||
{
|
{
|
||||||
|
// Open action
|
||||||
|
QAction *openAction = new QAction("Open", trayMenu);
|
||||||
|
trayMenu->addAction(openAction);
|
||||||
|
connect(openAction, &QAction::triggered, qApp, [this](){emit openApp();});
|
||||||
|
|
||||||
|
// Settings Menu
|
||||||
|
|
||||||
|
QAction *settingsMenu = new QAction("Settings", trayMenu);
|
||||||
|
trayMenu->addAction(settingsMenu);
|
||||||
|
connect(settingsMenu, &QAction::triggered, qApp, [this](){emit openSettings();});
|
||||||
|
|
||||||
|
trayMenu->addSeparator();
|
||||||
|
|
||||||
// Conversational Awareness Toggle
|
// Conversational Awareness Toggle
|
||||||
caToggleAction = new QAction("Toggle Conversational Awareness", trayMenu);
|
caToggleAction = new QAction("Toggle Conversational Awareness", trayMenu);
|
||||||
caToggleAction->setCheckable(true);
|
caToggleAction->setCheckable(true);
|
||||||
@@ -63,6 +76,8 @@ void TrayIconManager::setupMenuActions()
|
|||||||
connect(caToggleAction, &QAction::triggered, this, [this](bool checked)
|
connect(caToggleAction, &QAction::triggered, this, [this](bool checked)
|
||||||
{ emit conversationalAwarenessToggled(checked); });
|
{ emit conversationalAwarenessToggled(checked); });
|
||||||
|
|
||||||
|
trayMenu->addSeparator();
|
||||||
|
|
||||||
// Noise Control Options
|
// Noise Control Options
|
||||||
noiseControlGroup = new QActionGroup(trayMenu);
|
noiseControlGroup = new QActionGroup(trayMenu);
|
||||||
const QPair<QString, NoiseControlMode> noiseOptions[] = {
|
const QPair<QString, NoiseControlMode> noiseOptions[] = {
|
||||||
@@ -82,6 +97,8 @@ void TrayIconManager::setupMenuActions()
|
|||||||
{ emit noiseControlChanged(mode); });
|
{ emit noiseControlChanged(mode); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trayMenu->addSeparator();
|
||||||
|
|
||||||
// Quit action
|
// Quit action
|
||||||
QAction *quitAction = new QAction("Quit", trayMenu);
|
QAction *quitAction = new QAction("Quit", trayMenu);
|
||||||
trayMenu->addAction(quitAction);
|
trayMenu->addAction(quitAction);
|
||||||
|
|||||||
@@ -54,4 +54,6 @@ signals:
|
|||||||
void trayClicked();
|
void trayClicked();
|
||||||
void noiseControlChanged(AirpodsTrayApp::Enums::NoiseControlMode);
|
void noiseControlChanged(AirpodsTrayApp::Enums::NoiseControlMode);
|
||||||
void conversationalAwarenessToggled(bool enabled);
|
void conversationalAwarenessToggled(bool enabled);
|
||||||
|
void openApp();
|
||||||
|
void openSettings();
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user