- All settings move to flat tray menu; right-click on clock disabled - ClockLabel: custom QPainterPath text rendering with configurable glyph outline (BorderColor) — verified pixel-level offscreen - Fixed glyph positioning bug (baseline math) caught by isolated test - Window auto-fits content (adjustSize) — no more oversized clock - Start at Login: checkable tray item, persisted in QSettings, LaunchAgent enable/disable (TDD: roundTrip test caught disable() returning false when plist already absent) - Color dialog: hex/HTML input + 'transparent' + native picker fallback; opaque colors stored as #RRGGBB - Border: glyph outline instead of box border; background still painted in paintEvent (QSS doesn't render with WA_TranslucentBackground on macOS) - Removed window shadow (setHasShadow:NO), no bold, SF Pro Rounded - Font size dialogs allow up to 200 (was 72) - macOS: icon template 16pt, light/dark auto-adapt; LaunchAgent points to /Applications install
113 lines
2.7 KiB
C++
113 lines
2.7 KiB
C++
#include "autostart_manager.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QDir>
|
|
#include <QFileInfo>
|
|
#include <QSaveFile>
|
|
#include <QStandardPaths>
|
|
#include <QXmlStreamWriter>
|
|
|
|
namespace
|
|
{
|
|
const QString launchAgentLabel = QStringLiteral("com.clouck.clock");
|
|
}
|
|
|
|
bool AutoStartManager::enableForCurrentApplication()
|
|
{
|
|
#ifdef Q_OS_MAC
|
|
return enableForPath(QCoreApplication::applicationFilePath());
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool AutoStartManager::enableForPath(const QString &executablePath)
|
|
{
|
|
#ifdef Q_OS_MAC
|
|
const QString agentPath = launchAgentPath();
|
|
if (agentPath.isEmpty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const QFileInfo agentFileInfo(agentPath);
|
|
if (!QDir().mkpath(agentFileInfo.absolutePath()))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
QSaveFile agentFile(agentPath);
|
|
if (!agentFile.open(QIODevice::WriteOnly | QIODevice::Text))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
agentFile.write(launchAgentContents(executablePath).toUtf8());
|
|
return agentFile.commit();
|
|
#else
|
|
Q_UNUSED(executablePath);
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool AutoStartManager::disable()
|
|
{
|
|
#ifdef Q_OS_MAC
|
|
const QString agentPath = launchAgentPath();
|
|
if (agentPath.isEmpty() || !QFile::exists(agentPath))
|
|
{
|
|
return true; // already gone — desired state reached
|
|
}
|
|
return QFile::remove(agentPath);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool AutoStartManager::isEnabled()
|
|
{
|
|
#ifdef Q_OS_MAC
|
|
return QFile::exists(launchAgentPath());
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
QString AutoStartManager::launchAgentContents(const QString &executablePath)
|
|
{
|
|
QString contents;
|
|
QXmlStreamWriter writer(&contents);
|
|
writer.setAutoFormatting(true);
|
|
writer.writeStartDocument();
|
|
writer.writeDTD("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
|
|
writer.writeStartElement("plist");
|
|
writer.writeAttribute("version", "1.0");
|
|
writer.writeStartElement("dict");
|
|
|
|
writer.writeTextElement("key", "Label");
|
|
writer.writeTextElement("string", launchAgentLabel);
|
|
writer.writeTextElement("key", "ProgramArguments");
|
|
writer.writeStartElement("array");
|
|
writer.writeTextElement("string", executablePath);
|
|
writer.writeEndElement();
|
|
writer.writeTextElement("key", "RunAtLoad");
|
|
writer.writeEmptyElement("true");
|
|
|
|
writer.writeEndElement();
|
|
writer.writeEndElement();
|
|
writer.writeEndDocument();
|
|
|
|
return contents;
|
|
}
|
|
|
|
QString AutoStartManager::launchAgentPath()
|
|
{
|
|
const QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
|
|
if (homePath.isEmpty())
|
|
{
|
|
return QString();
|
|
}
|
|
|
|
return QDir(homePath).filePath("Library/LaunchAgents/" + launchAgentLabel + ".plist");
|
|
}
|