/* SPDX-FileCopyrightText: 2007 Aaron Seigo SPDX-FileCopyrightText: 2008 Alex Merry SPDX-License-Identifier: LGPL-2.0-or-later */ #include "timeengine.h" #include #include #include #include #include #ifdef Q_OS_LINUX #include #include #include #endif #include "debug.h" #include "timesource.h" // timezone is defined in msvc #ifdef timezone #undef timezone #endif TimeEngine::TimeEngine(QObject *parent) : Plasma5Support::DataEngine(parent) { setMinimumPollingInterval(333); // To have translated timezone names // (effectively a noop if the catalog is already present). ////KF5 port: remove this line and define TRANSLATION_DOMAIN in CMakeLists.txt instead // KLocale::global()->insertCatalog("timezones4"); QTimer::singleShot(0, this, &TimeEngine::init); } TimeEngine::~TimeEngine() { } void TimeEngine::init() { QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.connect(QString(), QString(), QStringLiteral("org.kde.KTimeZoned"), QStringLiteral("timeZoneChanged"), this, SLOT(tzConfigChanged())); #ifdef Q_OS_LINUX // monitor for the system clock being changed auto timeChangedFd = timerfd_create(CLOCK_REALTIME, O_CLOEXEC | O_NONBLOCK); itimerspec timespec; memset(×pec, 0, sizeof(timespec)); // set all timers to 0 seconds, which creates a timer that won't do anything int err = timerfd_settime(timeChangedFd, 3, ×pec, nullptr); // monitor for the time changing //(flags == TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET). However these are not exposed in glibc so value is hardcoded if (err) { qCWarning(DATAENGINE_TIME) << "Could not create timer with TFD_TIMER_CANCEL_ON_SET. Clock skews will not be detected. Error:" << qPrintable(strerror(err)); } connect(this, &QObject::destroyed, [timeChangedFd]() { close(timeChangedFd); }); auto notifier = new QSocketNotifier(timeChangedFd, QSocketNotifier::Read, this); connect(notifier, &QSocketNotifier::activated, this, [this](int fd) { uint64_t c; read(fd, &c, 8); clockSkewed(); }); #else dbus.connect(QString(), "/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated", this, SLOT(clockSkewed())); dbus.connect(QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("/org/kde/Solid/PowerManagement/Actions/SuspendSession"), QStringLiteral("org.kde.Solid.PowerManagement.Actions.SuspendSession"), QStringLiteral("resumingFromSuspend"), this, SLOT(clockSkewed())); #endif } void TimeEngine::clockSkewed() { qCDebug(DATAENGINE_TIME) << "Time engine Clock skew signaled"; updateAllSources(); forceImmediateUpdateOfAllVisualizations(); } void TimeEngine::tzConfigChanged() { qCDebug(DATAENGINE_TIME) << "Local timezone changed signaled"; TimeSource *s = qobject_cast(containerForSource(QStringLiteral("Local"))); if (s) { s->setTimeZone(QStringLiteral("Local")); } updateAllSources(); forceImmediateUpdateOfAllVisualizations(); } QStringList TimeEngine::sources() const { QStringList sources; for (const auto timezones = QTimeZone::availableTimeZoneIds(); const QByteArray &tz : timezones) { sources << QString::fromLocal8Bit(tz); } sources << QStringLiteral("Local"); return sources; } bool TimeEngine::sourceRequestEvent(const QString &name) { addSource(new TimeSource(name, this)); return true; } bool TimeEngine::updateSourceEvent(const QString &tz) { TimeSource *s = qobject_cast(containerForSource(tz)); if (s) { s->updateTime(); return true; } return false; } K_PLUGIN_CLASS_WITH_JSON(TimeEngine, "plasma-dataengine-time.json") #include "timeengine.moc"