Files
DualFloatingClock/main.cpp
T
sebastian 45fc172fc8
Build and Release DualFloatingClock / build-linux (push) Failing after 32s
CI Build / build (macos-latest) (push) Canceled after 0s
CI Build / build (windows-latest) (push) Canceled after 0s
Build and Release DualFloatingClock / build-macos (push) Canceled after 0s
Build and Release DualFloatingClock / build-windows (push) Canceled after 0s
Build and Release DualFloatingClock / generate-changelog (push) Canceled after 0s
Build and Release DualFloatingClock / create-release (push) Canceled after 0s
feat: rename project to DualFloatingClock, add README, public release
- Full rename: CMake target, bundle, LaunchAgent label
  (com.dualfloatingclock.clock), QSettings org/app, tray tooltip,
  icns resource, build scripts, CI workflows, sample config
- Config XML: new root DualFloatingClockConfig; reader accepts legacy
  ClouckConfig root for painless migration of existing settings
- README rewritten: fork provenance (ivaquero/clouck), features, build,
  tests, usage
- Drop stale README-CN.md
2026-08-27 22:36:05 +03:00

144 lines
4.6 KiB
C++

#include <QApplication>
#include <QAction>
#include <QMenu>
#include <QPainter>
#include <QSettings>
#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)
{
// Render at 16 logical points times the device pixel ratio so the
// bitmap is crisp on Retina but occupies exactly one menu bar cell.
const qreal devicePixelRatio = qApp->devicePixelRatio();
QPixmap pixmap(qRound(trayIconExtent * devicePixelRatio),
qRound(trayIconExtent * devicePixelRatio));
pixmap.setDevicePixelRatio(devicePixelRatio);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(color, 1.5));
// Draw inside the 16pt coordinate space; center with a small margin.
const QPointF center(trayIconExtent / 2.0, trayIconExtent / 2.0);
const qreal radius = trayIconExtent / 2.0 - 1.5;
painter.drawEllipse(center, radius, radius);
painter.drawLine(QPointF(center.x(), center.y() - radius * 0.55), center);
painter.drawLine(center, QPointF(center.x() + radius * 0.5, center.y() + radius * 0.3));
QIcon icon;
icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
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);
// Menu-bar-only app: no Dock icon, no app switcher entry.
#ifdef Q_OS_MAC
extern void clouck_setActivationPolicyAccessory(); // defined in window_helper_macos.mm
clouck_setActivationPolicyAccessory();
#endif
app.setApplicationName("DualFloatingClock");
app.setOrganizationName("DualFloatingClock");
app.setApplicationDisplayName("DualFloatingClock");
ClockWidget clock;
clock.show();
// Start at Login: honor the persisted choice instead of always forcing it.
{
QSettings autoStartSettings("DualFloatingClock", "DualFloatingClock");
const bool startAtLogin = autoStartSettings.value("startAtLogin", true).toBool();
if (startAtLogin)
{
AutoStartManager::enableForCurrentApplication();
}
else
{
AutoStartManager::disable();
}
autoStartSettings.setValue("startAtLogin", startAtLogin);
}
const QStyleHints *styleHints = app.styleHints();
QSystemTrayIcon trayIcon(createTrayIcon(trayIconColorForScheme(styleHints->colorScheme())), &app);
trayIcon.setToolTip("DualFloatingClock");
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 *startAtLoginAction = trayMenu.addAction("Start at Login");
{
QSettings autoStartSettings("DualFloatingClock", "DualFloatingClock");
startAtLoginAction->setCheckable(true);
startAtLoginAction->setChecked(autoStartSettings.value("startAtLogin", true).toBool());
}
QObject::connect(startAtLoginAction, &QAction::toggled, &app, [](bool checked) {
QSettings autoStartSettings("DualFloatingClock", "DualFloatingClock");
autoStartSettings.setValue("startAtLogin", checked);
if (checked)
{
AutoStartManager::enableForCurrentApplication();
}
else
{
AutoStartManager::disable();
}
});
trayMenu.addSeparator();
// Clock settings live directly in the tray menu — no submenu.
const QList<QAction *> clockActions = clock.menu()->actions();
for (QAction *action : clockActions)
{
trayMenu.addAction(action);
}
trayMenu.addSeparator();
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);
trayIcon.setContextMenu(&trayMenu);
trayIcon.show();
return app.exec();
}