[Linux] Add autostart setting

This commit is contained in:
Tim Gromeyer
2025-04-21 12:47:15 +02:00
committed by Tim Gromeyer
parent 1c7bdf987c
commit ec1b0c47ca
4 changed files with 119 additions and 10 deletions

View File

@@ -21,6 +21,7 @@ qt_add_executable(applinux
battery.hpp
BluetoothMonitor.cpp
BluetoothMonitor.h
autostartmanager.hpp
)
qt_add_qml_module(applinux

View File

@@ -127,6 +127,7 @@ ApplicationWindow {
}
Switch {
visible: airPodsTrayApp.airpodsConnected
text: "Conversational Awareness"
checked: airPodsTrayApp.conversationalAwareness
onCheckedChanged: airPodsTrayApp.conversationalAwareness = checked
@@ -187,6 +188,12 @@ ApplicationWindow {
}
}
Switch {
text: "Auto-Start on Login"
checked: airPodsTrayApp.autoStartManager.autoStartEnabled
onCheckedChanged: airPodsTrayApp.autoStartManager.autoStartEnabled = checked
}
Row {
spacing: 10

View File

@@ -0,0 +1,98 @@
#ifndef AUTOSTARTMANAGER_HPP
#define AUTOSTARTMANAGER_HPP
#include <QObject>
#include <QSettings>
#include <QStandardPaths>
#include <QFile>
#include <QDir>
#include <QCoreApplication>
class AutoStartManager : public QObject
{
Q_OBJECT
Q_PROPERTY(bool autoStartEnabled READ autoStartEnabled WRITE setAutoStartEnabled NOTIFY autoStartEnabledChanged)
public:
explicit AutoStartManager(QObject *parent = nullptr) : QObject(parent)
{
QString autostartDir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/autostart";
QDir().mkpath(autostartDir);
m_autostartFilePath = autostartDir + "/" + QCoreApplication::applicationName() + ".desktop";
}
bool autoStartEnabled() const
{
return QFile::exists(m_autostartFilePath);
}
void setAutoStartEnabled(bool enabled)
{
if (autoStartEnabled() == enabled)
{
return;
}
if (enabled)
{
createAutoStartEntry();
}
else
{
removeAutoStartEntry();
}
emit autoStartEnabledChanged(enabled);
}
private:
void createAutoStartEntry()
{
QFile desktopFile(m_autostartFilePath);
if (!desktopFile.open(QIODevice::WriteOnly | QIODevice::Text))
{
qWarning() << "Failed to create autostart file:" << desktopFile.errorString();
return;
}
QString appPath = QCoreApplication::applicationFilePath();
// Handle cases where the path might contain spaces
if (appPath.contains(' '))
{
appPath = "\"" + appPath + "\"";
}
QString content = QStringLiteral(
"[Desktop Entry]\n"
"Type=Application\n"
"Name=%1\n"
"Exec=%2\n"
"Icon=%3\n"
"Comment=%4\n"
"X-GNOME-Autostart-enabled=true\n"
"Terminal=false\n")
.arg(
QCoreApplication::applicationName(),
appPath,
QCoreApplication::applicationName().toLower(),
QCoreApplication::applicationName() + " autostart");
desktopFile.write(content.toUtf8());
desktopFile.close();
}
void removeAutoStartEntry()
{
if (QFile::exists(m_autostartFilePath))
{
QFile::remove(m_autostartFilePath);
}
}
QString m_autostartFilePath;
signals:
void autoStartEnabledChanged(bool enabled);
};
#endif // AUTOSTARTMANAGER_HPP

View File

@@ -8,6 +8,7 @@
#include "enums.h"
#include "battery.hpp"
#include "BluetoothMonitor.h"
#include "autostartmanager.hpp"
using namespace AirpodsTrayApp::Enums;
@@ -31,13 +32,17 @@ class AirPodsTrayApp : public QObject {
Q_PROPERTY(bool airpodsConnected READ areAirpodsConnected NOTIFY airPodsStatusChanged)
Q_PROPERTY(int earDetectionBehavior READ earDetectionBehavior WRITE setEarDetectionBehavior NOTIFY earDetectionBehaviorChanged)
Q_PROPERTY(bool crossDeviceEnabled READ crossDeviceEnabled WRITE setCrossDeviceEnabled NOTIFY crossDeviceEnabledChanged)
Q_PROPERTY(AutoStartManager *autoStartManager READ autoStartManager CONSTANT)
public:
AirPodsTrayApp(bool debugMode)
: debugMode(debugMode)
AirPodsTrayApp(bool debugMode, QObject *parent = nullptr)
: QObject(parent)
, debugMode(debugMode)
, m_battery(new Battery(this))
, monitor(new BluetoothMonitor(this))
, m_settings(new QSettings("AirPodsTrayApp", "AirPodsTrayApp")){
, m_settings(new QSettings("AirPodsTrayApp", "AirPodsTrayApp"))
, m_autoStartManager(new AutoStartManager(this))
{
if (debugMode) {
QLoggingCategory::setFilterRules("airpodsApp.debug=true");
} else {
@@ -92,8 +97,6 @@ public:
saveCrossDeviceEnabled();
saveEarDetectionSettings();
delete trayIcon;
delete trayMenu;
delete socket;
delete phoneSocket;
}
@@ -126,6 +129,7 @@ public:
bool areAirpodsConnected() const { return socket && socket->isOpen() && socket->state() == QBluetoothSocket::SocketState::ConnectedState; }
int earDetectionBehavior() const { return mediaController->getEarDetectionBehavior(); }
bool crossDeviceEnabled() const { return CrossDevice.isEnabled; }
AutoStartManager *autoStartManager() const { return m_autoStartManager; }
private:
bool debugMode;
@@ -853,8 +857,7 @@ signals:
void earDetectionBehaviorChanged(int behavior);
void crossDeviceEnabledChanged(bool enabled);
private : QSystemTrayIcon *trayIcon;
QMenu *trayMenu;
private:
QBluetoothSocket *socket = nullptr;
QBluetoothSocket *phoneSocket = nullptr;
QString connectedDeviceMacAddress;
@@ -864,6 +867,7 @@ signals:
TrayIconManager *trayManager;
BluetoothMonitor *monitor;
QSettings *m_settings;
AutoStartManager *m_autoStartManager;
QString m_batteryStatus;
QString m_earDetectionStatus;
@@ -893,10 +897,9 @@ int main(int argc, char *argv[]) {
QQmlApplicationEngine engine;
qmlRegisterType<Battery>("me.kavishdevar.Battery", 1, 0, "Battery");
AirPodsTrayApp trayApp(debugMode);
engine.rootContext()->setContextProperty("airPodsTrayApp", &trayApp);
AirPodsTrayApp *trayApp = new AirPodsTrayApp(debugMode, &engine);
engine.rootContext()->setContextProperty("airPodsTrayApp", trayApp);
engine.loadFromModule("linux", "Main");
return app.exec();
}