feat: dual time zones, autostart, tray icon, config relocation, tests

- Dual clock (primary/secondary time zone) with IANA picker, persisted in XML
- AutoStartManager: macOS LaunchAgent (com.clouck.clock, RunAtLoad)
- Tray icon: template image, light/dark adaptation, toggle + quit menu
- ConfigManager: default path moved to QStandardPaths::AppConfigLocation
- Qt Test suite (ConfigManager, AutoStartManager) wired into CTest
- GitHub origin renamed to upstream; private Gitea repo as origin
This commit is contained in:
2026-08-19 21:09:06 +03:00
parent e59a674ba7
commit 6b9cb32534
12 changed files with 448 additions and 20 deletions
+80
View File
@@ -1,6 +1,45 @@
#include <QApplication>
#include <QAction>
#include <QMenu>
#include <QPainter>
#include <QStyleHints>
#include <QSystemTrayIcon>
#include "autostart_manager.h"
#include "clock_widget.h"
namespace
{
// Standard macOS menu bar icon extent (points). Matches surrounding icons.
constexpr int trayIconExtent = 16;
QIcon createTrayIcon(const QColor &color)
{
QPixmap pixmap(trayIconExtent, trayIconExtent);
pixmap.setDevicePixelRatio(qApp->devicePixelRatio());
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(color, 1.5));
painter.drawEllipse(QPointF(8, 8), 5.5, 5.5);
painter.drawLine(QPointF(8, 4.5), QPointF(8, 8));
painter.drawLine(QPointF(8, 8), QPointF(10.5, 9.5));
QIcon icon(pixmap);
#ifdef Q_OS_MAC
// Template image: the system tints it black/white to match the
// active appearance, like native menu bar icons.
icon.setIsMask(true);
#endif
return icon;
}
QColor trayIconColorForScheme(Qt::ColorScheme scheme)
{
return scheme == Qt::ColorScheme::Dark ? QColor(Qt::white) : QColor(Qt::black);
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
@@ -12,5 +51,46 @@ int main(int argc, char *argv[])
ClockWidget clock;
clock.show();
AutoStartManager::enableForCurrentApplication();
const QStyleHints *styleHints = app.styleHints();
QSystemTrayIcon trayIcon(createTrayIcon(trayIconColorForScheme(styleHints->colorScheme())), &app);
trayIcon.setToolTip("Clouck");
QObject::connect(styleHints, &QStyleHints::colorSchemeChanged, &trayIcon,
[&trayIcon](Qt::ColorScheme scheme) {
trayIcon.setIcon(createTrayIcon(trayIconColorForScheme(scheme)));
});
QMenu trayMenu;
QAction *toggleClockAction = trayMenu.addAction("Turn Clock Off");
QAction *quitAction = trayMenu.addAction("Quit");
const auto toggleClock = [&clock, toggleClockAction]() {
if (clock.isVisible())
{
clock.hide();
toggleClockAction->setText("Turn Clock On");
return;
}
clock.show();
clock.raise();
toggleClockAction->setText("Turn Clock Off");
};
QObject::connect(toggleClockAction, &QAction::triggered, &app, toggleClock);
QObject::connect(quitAction, &QAction::triggered, &app, &QApplication::quit);
QObject::connect(&trayIcon, &QSystemTrayIcon::activated, &app,
[toggleClock](QSystemTrayIcon::ActivationReason reason) {
if (reason == QSystemTrayIcon::Trigger)
{
toggleClock();
}
});
trayIcon.setContextMenu(&trayMenu);
trayIcon.show();
return app.exec();
}